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});
        });
      });
    }
  };
})
Community
  • 1
  • 1
migu
  • 4,236
  • 5
  • 39
  • 60
  • 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. – Peter Ashwell Jan 04 '15 at 00: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. – migu Jan 04 '15 at 02:06

1 Answers1

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')
              });
       });

   }
 };
})
Mehmet Otkun
  • 1,374
  • 9
  • 22
  • 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: https://github.com/angular/angular.js/issues/10588 – migu Jan 05 '15 at 10:31
  • what is the time problem in keypress event? does it become late? – Mehmet Otkun Jan 05 '15 at 12:11
  • Please look at [**this**](http://stackoverflow.com/questions/6458840/on-input-change-event) 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. – Mehmet Otkun Jan 05 '15 at 12:47
  • 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. – migu Jan 09 '15 at 20:00
  • 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? – Mehmet Otkun Jan 11 '15 at 20:17