How to use a keypress event in AngularJS?
Solution 1
You need to add a directive
, like this:
Javascript:
app.directive('myEnter', function () {
return function (scope, element, attrs) {
element.bind("keydown keypress", function (event) {
if(event.which === 13) {
scope.$apply(function (){
scope.$eval(attrs.myEnter);
});
event.preventDefault();
}
});
};
});
HTML:
<div ng-app="" ng-controller="MainCtrl">
<input type="text" my-enter="doSomething()">
</div>
Solution 2
An alternative is to use standard directive ng-keypress="myFunct($event)"
Then in your controller you can have:
...
$scope.myFunct = function(keyEvent) {
if (keyEvent.which === 13)
alert('I am an alert');
}
...
Solution 3
My simplest approach using just angular build-in directive:
ng-keypress
, ng-keydown
or ng-keyup
.
Usually, we want add keyboard support for something that already handled by ng-click.
for instance:
<a ng-click="action()">action</a>
Now, let's add keyboard support.
trigger by enter key:
<a ng-click="action()"
ng-keydown="$event.keyCode === 13 && action()">action</a>
by space key:
<a ng-click="action()"
ng-keydown="$event.keyCode === 32 && action()">action</a>
by space or enter key:
<a ng-click="action()"
ng-keydown="($event.keyCode === 13 || $event.keyCode === 32) && action()">action</a>
if you are in modern browser
<a ng-click="action()"
ng-keydown="[13, 32].includes($event.keyCode) && action()">action</a>
More about keyCode:
keyCode is deprecated but well supported API, you could use $evevt.key in supported browser instead.
See more in https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key
Solution 4
Another simple alternative:
<input ng-model="edItem" type="text"
ng-keypress="($event.which === 13)?foo(edItem):0"/>
And the ng-ui alternative:
<input ng-model="edItem" type="text" ui-keypress="{'enter':'foo(edItem)'}"/>
Solution 5
Here is what I figured out when I was building an app with a similar requirement, it doesn't require writing a directive and it's relatively simple to tell what it does:
<input type="text" ng-keypress="($event.charCode==13)?myFunction():return" placeholder="Will Submit on Enter">
Venkata K. C. Tata
Updated on August 27, 2020Comments
-
Venkata K. C. Tata almost 4 years
I want to catch the enter key press event on the textbox below. To make it more clear I am using a
ng-repeat
to populate the tbody. Here is the HTML:<td><input type="number" id="closeqty{{$index}}" class="pagination-right closefield" data-ng-model="closeqtymodel" data-ng-change="change($index)" required placeholder="{{item.closeMeasure}}" /></td>
This is my module:
angular.module('components', ['ngResource']);
I am using a resource to populate the table and my controller code is:
function Ajaxy($scope, $resource) { //controller which has resource to populate the table }
-
bobbymcr almost 11 yearsTo save other people some time,
ng-keypress
doesn't seem to be part of angular 1.0.x,ui-keypress
(with slightly different calling semantics) is available though: angular-ui.github.io/ui-utils -
Pete Martin over 10 years@DerekAdair The directive binds to the
keydown
andkeypress
events of the element it is attributed to. When the event is received the supplied expression is evaluated inside an$apply
block. -
Gabriel over 10 yearsMore safe to defined the key like this :
var key = typeof event.which === "undefined" ? event.keyCode : event.which;
as long as event.which is not used by every browser. See comments here : stackoverflow.com/a/4471635/2547632 -
user1713964 over 10 yearsI would add also
keyup
in the bind test -
Maya Kathrine Andersen over 10 yearsThis is the best solution as it keeps view and controller seperated.
-
Maya Kathrine Andersen over 10 yearsI think this is a nasty solution. A controller shouldn't handle UI things like keypresses.
-
Cornelius over 10 yearsI think the comment above this was aimed at a different answer. (Just for reference.)
-
Cornelius over 10 yearsSeparating out the actually triggered event handling function into the $scope of the directive allows for easier unit testing, because the fn() can be called directly in the test, instead of having to create and dispatch an actual event. Similar to the other answer here.
-
Cornelius over 10 yearsThis answer contains a lot of "noise", in a manner of speaking, containing a lot of markup that does — as far as I can see at a glance — not relate to the actual question at hand. It might be more succinct/useful to condense the code in the answer and provide the full example in a gist/jsfiddle/plnkr.
-
desperateCoder about 10 yearsMartin that's actually the function of a controller: to handle UI events.
-
Marius Balčytis about 10 yearsalso note that using ng prefix is not recommended, as this can clash with future ng-* directives. Use your own instead
-
Emanegux almost 10 years@MartinAndersen, where should a keypress be handled in an angular app?
-
Maya Kathrine Andersen almost 10 yearsWhen I look at it now it looks okay. It's basically how keypresses has always been handled with the JS event model.
-
Martin almost 10 yearsBetter yet, use ngKeypress and pass the $event to a custom filter.
-
BlaShadow over 9 yearsthe question it's about press enter and do something.
-
aycanadal over 9 years
<input type="text" name="itemname" ng-model="item.itemname" lta-enter="add(item.itemname)" placeholder="Add item"/>
-
Paulo Oliveira over 9 yearsng-ui it's ambiguous, instead you should say "UI.Utils" or share the link: angular-ui.github.io/ui-utils
-
GraehamF over 9 years
ng-keypress="console.log('foo')"
did not work for me either, but if you dong-keypress="fooMethod()"
and in your controller$scope.fooMethod = function() { console.log('fooMethod called'); }
does work. -
user12121234 about 9 yearsthe secret is the conditional before the method to be executed $event.which === 13 && action() - thanks!
-
flyer88 almost 9 yearsWhy is he binding
keydown
andkeypress
. Isn't just enough withkeypress
? -
Karl Adler almost 9 years'$event.which' is not working for me, but I found '$event.keyCode' which is working.
-
Eric Chen almost 9 yearsevent.which is undefined in IE<9 on keydown and keyup.
-
Joe Hany over 8 yearsDoes anyone have the tests (jasmine) of that directive :)
-
Xplouder over 8 yearsSimple and effective.
-
nawlbergs over 8 yearsDont forget to destroy your bindings: scope.$on('$destroy', function(){ element.unbind('keydown'); })
-
cafesanu over 8 yearsui-utils seems to be deprecated
-
Tommy Bjerregaard over 8 years@user1713964 Just use
keydown
orkeyup
if you needescape
key -
mike over 8 yearsNote, having both keydown and keypress can cause the action to be called twice. Bad news if you're making a server call, submitting a form, etc.
-
Mohan Singh about 8 years
$eval and $parse
evaluate only angular expression. $eval uses $parse internally So $parse can be used instead $eval. scope.$apply is trigger digest loop unnecessarily. Everything is handled by $parse internally. -
Mohan Singh about 8 yearsupdated directive is here gist.github.com/singhmohancs/317854a859098bffe9477f59eac8d915
-
bFunc almost 8 yearsBest answer +1. Why should I make my own directive, if there is one, already included in Angular?
-
Francois Stock almost 8 years
-
Aaron McMillin over 7 yearsHow/where is
chat.sendMessage()
defined -
Shashank Singh over 7 yearsI was using this with codemirror and it couldn't catch the enter key, probably because it was binded with something else on default. The answer by EpokK works best
-
Ed Greaves over 7 yearsWhy are you not using ng-keypress, ng-keydown, ng-keyup? The code is cleaner if you do this because then you get the keyCode directly without any binding. You can handle all your keycodes in this one function instead of creating a directive for each key. Or you could create specific key directives (onEnter) but just supply a handler function that your main ng-keydown handler calls.
-
Mihnea Belcin over 7 years"old browsers like IE9" .. never thought this day will come :)
-
Nathan Hazzard about 7 yearsWhy hasn't anyone updated the code snippets here to use $event.keyCode then? I'd edit it myself, but I'm unable to for some reason.
-
Neta Meta about 7 yearsway better then creating a whole directive.
-
birdus almost 7 yearsKudos for simplicity.
-
user841760 almost 7 yearshow would i use it in a nested directive? i.e. I've got a directive with it's own controller and template - when I use it in template it doesn't work. but if I used it outside of the directive, it will work just fine. is there a way to do it within the directive?
-
Matthew over 6 yearsIt took me a while of debugging to work out that the attribute is "my-enter" with a dash but the directive name is "myEnter" without a dash!
-
GrahamJRoy about 6 yearsbrilliant! Just what I needed
-
DBX12 over 5 years@ahnbizcad 13 is the keyCode for the enter key. You can find out which key corresponds to which code by looking up the according tables or by using keycode.info
-
DVK about 5 yearsI feel like this is a lot more palatable than creating custom directives, and even if you needed to do this multiple places, it would be simple enough to wrap the conditional logic in a function.
if (isEnterKey($event)) { do stuff... )
-
Shervin Ivari almost 5 yearsWhen I change the name of the directive, for example, myEnter to mdEnter it doesn't work, how can I customize name?