How to use a keypress event in AngularJS?

494,040

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">
Share:
494,040
Venkata K. C. Tata
Author by

Venkata K. C. Tata

Updated on August 27, 2020

Comments

  • Venkata K. C. Tata
    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
    bobbymcr almost 11 years
    To 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
    Pete Martin over 10 years
    @DerekAdair The directive binds to the keydown and keypress events of the element it is attributed to. When the event is received the supplied expression is evaluated inside an $apply block.
  • Gabriel
    Gabriel over 10 years
    More 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
    user1713964 over 10 years
    I would add also keyup in the bind test
  • Maya Kathrine Andersen
    Maya Kathrine Andersen over 10 years
    This is the best solution as it keeps view and controller seperated.
  • Maya Kathrine Andersen
    Maya Kathrine Andersen over 10 years
    I think this is a nasty solution. A controller shouldn't handle UI things like keypresses.
  • Cornelius
    Cornelius over 10 years
    I think the comment above this was aimed at a different answer. (Just for reference.)
  • Cornelius
    Cornelius over 10 years
    Separating 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
    Cornelius over 10 years
    This 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
    desperateCoder about 10 years
    Martin that's actually the function of a controller: to handle UI events.
  • Marius Balčytis
    Marius Balčytis about 10 years
    also note that using ng prefix is not recommended, as this can clash with future ng-* directives. Use your own instead
  • Emanegux
    Emanegux almost 10 years
    @MartinAndersen, where should a keypress be handled in an angular app?
  • Maya Kathrine Andersen
    Maya Kathrine Andersen almost 10 years
    When I look at it now it looks okay. It's basically how keypresses has always been handled with the JS event model.
  • Martin
    Martin almost 10 years
    Better yet, use ngKeypress and pass the $event to a custom filter.
  • BlaShadow
    BlaShadow over 9 years
    the question it's about press enter and do something.
  • aycanadal
    aycanadal over 9 years
    <input type="text" name="itemname" ng-model="item.itemname" lta-enter="add(item.itemname)" placeholder="Add item"/>
  • Paulo Oliveira
    Paulo Oliveira over 9 years
    ng-ui it's ambiguous, instead you should say "UI.Utils" or share the link: angular-ui.github.io/ui-utils
  • GraehamF
    GraehamF over 9 years
    ng-keypress="console.log('foo')" did not work for me either, but if you do ng-keypress="fooMethod()" and in your controller $scope.fooMethod = function() { console.log('fooMethod called'); } does work.
  • user12121234
    user12121234 about 9 years
    the secret is the conditional before the method to be executed $event.which === 13 && action() - thanks!
  • flyer88
    flyer88 almost 9 years
    Why is he binding keydown and keypress. Isn't just enough with keypress?
  • Karl Adler
    Karl Adler almost 9 years
    '$event.which' is not working for me, but I found '$event.keyCode' which is working.
  • Eric Chen
    Eric Chen almost 9 years
    event.which is undefined in IE<9 on keydown and keyup.
  • Joe Hany
    Joe Hany over 8 years
    Does anyone have the tests (jasmine) of that directive :)
  • Xplouder
    Xplouder over 8 years
    Simple and effective.
  • nawlbergs
    nawlbergs over 8 years
    Dont forget to destroy your bindings: scope.$on('$destroy', function(){ element.unbind('keydown'); })
  • cafesanu
    cafesanu over 8 years
    ui-utils seems to be deprecated
  • Tommy Bjerregaard
    Tommy Bjerregaard over 8 years
    @user1713964 Just use keydown or keyup if you need escape key
  • mike
    mike over 8 years
    Note, 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
    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
    Mohan Singh about 8 years
  • bFunc
    bFunc almost 8 years
    Best answer +1. Why should I make my own directive, if there is one, already included in Angular?
  • Francois Stock
    Francois Stock almost 8 years
    KeyboardEvent.wich is now deprecated. You should use KeyboardEvent.key instead. Cf MDN.
  • Aaron McMillin
    Aaron McMillin over 7 years
    How/where is chat.sendMessage() defined
  • Shashank Singh
    Shashank Singh over 7 years
    I 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
    Ed Greaves over 7 years
    Why 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
    Mihnea Belcin over 7 years
    "old browsers like IE9" .. never thought this day will come :)
  • Nathan Hazzard
    Nathan Hazzard about 7 years
    Why 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
    Neta Meta about 7 years
    way better then creating a whole directive.
  • birdus
    birdus almost 7 years
    Kudos for simplicity.
  • user841760
    user841760 almost 7 years
    how 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
    Matthew over 6 years
    It 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
    GrahamJRoy about 6 years
    brilliant! Just what I needed
  • DBX12
    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
    DVK about 5 years
    I 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
    Shervin Ivari almost 5 years
    When I change the name of the directive, for example, myEnter to mdEnter it doesn't work, how can I customize name?