0

I had to write a custom directive because I need access to user input while composing Korean characters. As explained in another post, I can't use keydown or keypress because they don't get triggered at the right time when composing Korean characters. element.bind('input') does the trick but now I face another problem.

How can I access the event inside the element.bind callback to exit/return if the enter key has been hit?

HTML

<input cst-input="quizzesCtrl.checkAnswer(answer)" name="answer" id="answer" ng-model="quizzesCtrl.answer" type="text" />

Directive

.directive('cstInput', function() {
  return {
    restrict: 'A',
    require: '^ngModel',    
    link: function (scope, element, attrs, ngModel) {
      element.bind('input', function(event) {                  
        if (event.which === 13) { return; } // can't access the event unless I bind to keypress etc
        scope.$apply(function(){            
          scope.ngModel = element.val();
          scope.$eval(attrs.cstInput, {'answer': scope.ngModel});
        });
      });
    }
  };
})
2
  • My suggestion would be to have two bindings - one keydown especially for finding the enter keys, and leaving this one as is to do whatever you're doing with the korean characters. Commented Jan 4, 2015 at 0:30
  • I actually have a second one to listen to return key events. The goal here is to suppress the return key because of some issues with FireFox. Commented Jan 4, 2015 at 2:06

1 Answer 1

3

Please note that;

input: don't have which property and triggered after keypress. Namely you can bind unbind input event inside keypress event. Also input event don't triggered on Enter. Namely e.which==13 not requred to validate.

keypress event not triggered when backspace, if you don't need check value when backspace, there is no problem.

keydown and keyup events triggered for each key you can use them with eachother You can try something like this.

.directive('cstInput', function() {
  return {
   restrict: 'A',
   require: '^ngModel',    
   link: function (scope, element, attrs, ngModel) {
       element.on('keypress', function(event) {                  
              if (event.which === 13) { return; } // check key how you want
               //attach input event 
               element.on('input', function(evt) { 
                   scope.$apply(function(){            
                       scope.ngModel = element.val();
                       scope.$eval(attrs.cstInput, {'answer': scope.ngModel});
                   });
                   //deatach event again
                   element.off('input')
              });
       });

      //Alternatively using keydown with same way
      element.on('keydown', function(event) {                  
              if (event.which === 13) { return; } // check key how you want
               //attach input event 
               element.on('input', function(evt) { 
                   scope.$apply(function(){            
                       scope.ngModel = element.val();
                       scope.$eval(attrs.cstInput, {'answer': scope.ngModel});
                   });
                   //deatach event again
                   element.off('input')
              });
       });

   }
 };
})
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for your answer. I tried but scope.$watch doesn't work while composing Korean characters. It only gets triggered once a syllable has been fully composed and the next syllable has started. That was the reason why I started to write my custom directive. For more info, please see here: github.com/angular/angular.js/issues/10588
what is the time problem in keypress event? does it become late?
Please look at this question about input events, I think it would help you. Also you may need multiple event with together, Like keypress, keyup and input. Think about setTimeout setInterval too.
I checked, unfortunately keydown, keyup and keypress don't get triggered at the right time when composing Korean characters in FireFox. The only thing that seems to work is input but the problem there is that I don't have access the the event inside the callback.
Please look at the code carefully. When is the right time for you? isn't it when "input" event? "input" event has no callback, for this reason you cannot access it. If you bind "input" event inside "keyup", "keydown" or "keypress" you would have no time issue of them. Also, for which cases do you need event of input? why do you need it? what have you been tried to do with event?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.