Reputation: 363
I'm totally confused as to why my keypress event handler is always one keystroke behind. http://plnkr.co/edit/w3FAXGd5zjrktO6DgOpD?p=preview
<body ng-controller="myController">
<form>
<input ng-keypress="handleKeypress($event)" />
</form>
</body>
Controller:
myapp.controller('myController', function($scope, $timeout){
$scope.handleKeypress = function(ev){
console.log(ev.target.value); //always one keystroke behind
//$timeout(function(){console.log(ev.target.value);}); //works!
};
});
Why is $timeout necessary and why/how does it work? (A newbie-friendly answer is preferable)
I understand that with the keypress event the character hasn't yet been inserted into the DOM, but I'm confused because the Hello World example at angularjs.org responds before a key is released. Their example doesn't use a custom event handler, but clearly Angular is updating the model before the keyup event, so I'd like understand more about doing this in a custom event handler.
idursun's answer points out that event.which is available on keypress, and I thought Angular might be using String.fromCharCode()
, but I don't see anything in the Angular source to this effect.
Upvotes: 5
Views: 1688
Reputation: 11
It might help someone in latest angular.
I used (input) instead of keypress and it works with each character press.
Upvotes: 0
Reputation: 1872
tl:dr - event.target.value + event.key will give you the latest value.
The reason why it is one step behind is that it allows for you to reject the keypress by triggering the event prior to it is registered. This is not a bug, but a feature.
But if you want to get the most updated value, here's a workaround:-
html:-
<input type="text" (keypress)="myFunction($event)">
JS:-
myFunction(event) {
event.preventDefault()
console.log('latest input field value => ', event.target.value + event.key)
}
Update:-
Add event.preventDefault() to avoid double characters.
Update 2:-
The events are called in this order:-
So if you can change this event to keyup then you will get the latest value and wouldn't have to do additional changes in the method.
Upvotes: 1
Reputation: 3271
You should use ng-keyup
. Keypress might not always work as expected.
From the jQuery documentation:
Note: as the keypress event isn't covered by any official specification, the actual behavior encountered when using it may differ across browsers, browser versions, and platforms.
Upvotes: 6
Reputation: 6335
Because event target in your example is an input element and keystroke has not been processed by the element yet so value
of that element is always one keystroke lagging. This gives a chance to the event handler to reject key press.
You can check pressed key value by looking at which
field of the event object.
Upvotes: 1