Submit form on pressing Enter with AngularJS

383,353

Solution 1

Angular supports this out of the box. Have you tried ngSubmit on your form element?

<form ng-submit="myFunc()" ng-controller="mycontroller">
   <input type="text" ng-model="name" />
    <br />
    <input type="text" ng-model="email" />
</form>

EDIT: Per the comment regarding the submit button, see Submitting a form by pressing enter without a submit button which gives the solution of:

<input type="submit" style="position: absolute; left: -9999px; width: 1px; height: 1px;"/>

If you don't like the hidden submit button solution, you'll need to bind a controller function to the Enter keypress or keyup event. This normally requires a custom directive, but the AngularUI library has a nice keypress solution set up already. See http://angular-ui.github.com/

After adding the angularUI lib, your code would be something like:

<form ui-keypress="{13:'myFunc($event)'}">
  ... input fields ...
</form>

or you can bind the enter keypress to each individual field.

Also, see this SO questions for creating a simple keypres directive: How can I detect onKeyUp in AngularJS?

EDIT (2014-08-28): At the time this answer was written, ng-keypress/ng-keyup/ng-keydown did not exist as native directives in AngularJS. In the comments below @darlan-alves has a pretty good solution with:

<input ng-keyup="$event.keyCode == 13 && myFunc()"... />

Solution 2

If you want to call function without form you can use my ngEnter directive:

Javascript:

angular.module('yourModuleName').directive('ngEnter', function() {
        return function(scope, element, attrs) {
            element.bind("keydown keypress", function(event) {
                if(event.which === 13) {
                    scope.$apply(function(){
                        scope.$eval(attrs.ngEnter, {'event': event});
                    });

                    event.preventDefault();
                }
            });
        };
    });

HTML:

<div ng-app="" ng-controller="MainCtrl">
    <input type="text" ng-enter="doSomething()">    
</div>

I submit others awesome directives on my twitter and my gist account.

Solution 3

If you only have one input you can use the form tag.

<form ng-submit="myFunc()" ...>

If you have more than one input, or don't want to use the form tag, or want to attach the enter-key functionality to a specific field, you can inline it to a specific input as follows:

<input ng-keyup="$event.keyCode == 13 && myFunc()" ...>

Solution 4

I wanted something a little more extensible/semantic than the given answers so I wrote a directive that takes a javascript object in a similar way to the built-in ngClass:

HTML

<input key-bind="{ enter: 'go()', esc: 'clear()' }" type="text"></input>

The values of the object are evaluated in the context of the directive's scope - ensure they are encased in single quotes otherwise all of the functions will be executed when the directive is loaded(!)

So for example: esc : 'clear()' instead of esc : clear()

Javascript

myModule
    .constant('keyCodes', {
        esc: 27,
        space: 32,
        enter: 13,
        tab: 9,
        backspace: 8,
        shift: 16,
        ctrl: 17,
        alt: 18,
        capslock: 20,
        numlock: 144
    })
    .directive('keyBind', ['keyCodes', function (keyCodes) {
        function map(obj) {
            var mapped = {};
            for (var key in obj) {
                var action = obj[key];
                if (keyCodes.hasOwnProperty(key)) {
                    mapped[keyCodes[key]] = action;
                }
            }
            return mapped;
        }
        
        return function (scope, element, attrs) {
            var bindings = map(scope.$eval(attrs.keyBind));
            element.bind("keydown keypress", function (event) {
                if (bindings.hasOwnProperty(event.which)) {
                    scope.$apply(function() {
                         scope.$eval(bindings[event.which]);
                    });
                }
            });
        };
    }]);

Solution 5

Another approach would be using ng-keypress ,

<input type="text" ng-model="data" ng-keypress="($event.charCode==13)? myfunc() : return"> 

Submit an input on pressing Enter with AngularJS - jsfiddle

Share:
383,353
ali
Author by

ali

I am a web, desktop and mobile applications developers with great knowledge in web development, medium knowledge in desktop applications development and a beginner status in mobile applications development.

Updated on August 19, 2021

Comments

  • ali
    ali almost 3 years

    In this particular case, what options do I have to make these inputs call a function when I press Enter?

    Html:

    <form>
        <input type="text" ng-model="name" <!-- Press ENTER and call myFunc --> />
        <br />
        <input type="text" ng-model="email" <!-- Press ENTER and call myFunc --> />
    </form>
    
    // Controller //
    .controller('mycontroller', ['$scope',function($scope) {
        $scope.name = '';
        $scope.email = '';
        // Function to be called when pressing ENTER
        $scope.myFunc = function() {
           alert('Submitted');
        };
    }])
    
  • ali
    ali over 11 years
    It only works if I have a submit button inside the form, too.
  • ali
    ali over 11 years
    I'll go with the custom directive, I can't use angular-ui. Thanks
  • CMCDragonkai
    CMCDragonkai almost 11 years
    What about ng-change?
  • Derek Adair
    Derek Adair over 10 years
    Is there a clever way to get this to trigger any time they hit enter while on your page?
  • Antonio Max
    Antonio Max over 10 years
    @EpokK I wanna disable the enter key for the entire form, how can I do that? (I want to avoid form submission with enter)
  • NotSimon
    NotSimon over 10 years
    @AntonioMax You could just have an extra flag within the directive that checks whether you want to person to be able to submit or not
  • Neil S
    Neil S over 10 years
    very nice, but as per AngularJs' reccomendation, you shouldn't create directives, services, or filters that are prefixed with ng-, in case an official release later uses the same name.
  • Chris Nicola
    Chris Nicola over 10 years
    The downside to this is ng-submit automatically checks form validity. ui-keypress won't AFAICT.
  • John Culviner
    John Culviner over 10 years
    Also note that this HAS to be a <form> it doesn't seem to work on <someElement ng-form="" ...> which is what I tend to use.
  • Brian F
    Brian F over 10 years
    Great solution. I just changed the name to keyBind and this line "if(event.which === 13) {" to this "if(event.which === Number(attrs.key)) {" And then my input to "<input type="text" bind-key="doSomething()" key="13">" so that I could re-use it for different key events.
  • CMCDragonkai
    CMCDragonkai over 10 years
    So basically ng-submit only works when there's a submit button inside the form? Why not clone the ng-submit code, but just remove the part where it requires a submit button, and keep all the validation code.
  • Charlie Martin
    Charlie Martin about 10 years
    This is a clever way of doing this without even having to write your own directive
  • MarcoS
    MarcoS about 10 years
    @Derek Adair: I'm quite new to angular directives, but I should try to use, instead of element.bind(..., window.bind(......
  • Darlan Alves
    Darlan Alves about 10 years
    Even shorter: <input ng-keyup="$event.keyCode == 13 && myFunc()"... />
  • tester
    tester about 10 years
    Just leaving a note: If you've ended up here and submit buttons don't work for you, you could be using a bad name for your submit function. I was foolishly using ng-submit="join()" for a registration controller that had $scope.join = function() {...} and changing that function name to foo() got enter-button submission working again.
  • user4815162342
    user4815162342 about 10 years
    What's different between ui-keypress and the built-in ng-keypress?
  • blong
    blong almost 10 years
    A very similar answer is posted on this question: How to use a keypress event in angularjs
  • Ryan Miller
    Ryan Miller almost 10 years
    IMPORTANT: Adding both the keydown and keypress events without a comma to delimit them means both may fire simultaneously. This is likely to spawn $rootScope:inprog errors. Adding a comma between them creates a disjunctive, and ensures only only $digest cycle occurs. Couldn't apply the edit since it's only a single character.
  • eterps
    eterps almost 10 years
    At the time this answer was written, ng-keypress/ng-keyup did not exist in Angular
  • SharpNoiZy
    SharpNoiZy almost 10 years
    Works great, I used the ng-keyup directive, but I have one big issue with it, if I only have one text field, he submits the complete form (postback) but I don't want that. I tried already ng-keyup="$event.keyCode == 13 && onTextBoxKeyUp($event)" and in the function "event.preventDefault();", but did not help ;(
  • Paul Wand
    Paul Wand over 9 years
    this doesn't capture the done event on iOS, I ended up listening to the blur event as well
  • dustin.schultz
    dustin.schultz over 9 years
    @BrianF - great solution. Thanks. You also have to change attrs.ngEnter to attrs.keyBind in the scope.$eval(...) function.
  • napstercake
    napstercake about 9 years
    Maybe this is a very easy question but, where do you put the doSomething() method?
  • EpokK
    EpokK about 9 years
    @RicardoGonzales in your controller.
  • Honchar Denys
    Honchar Denys about 9 years
    ng-keyup="$event.keyCode == 13 && myFunc()" Really awesome :)
  • Augustin Riedinger
    Augustin Riedinger almost 9 years
    Don't you need to take care of unbinding event on unlink or something?
  • Atul Chaudhary
    Atul Chaudhary almost 9 years
    this is shorter but keeping DRY approach in my mind i would still create directive and use it with directive.
  • Vishwajeet Vatharkar
    Vishwajeet Vatharkar almost 9 years
    This may be problematic depending upon the context - I have a form in which I have two buttons, (wizard like interface), with 'back' and 'next' button, default behaviour on clicking 'enter' key is back button. Now, when using above code, the back button get's CLICKED FIRST, and then myFunction() code is called (which in turns, get's to next part of wizard) So, my wizard goes BACK for a while, and then it goes forward. @EpokK's solution works perfect for me.
  • sree
    sree over 8 years
    Just in case if someone is ignorant. Keep in mind that input type="button" will not trigger form submit. It needs to be input type="submit" button
  • Félix Adriyel Gagnon-Grenier
    Félix Adriyel Gagnon-Grenier about 7 years
    ... late to the party, but a hidden input with name submit <input type="hidden" name="submit" /> will do the same trick as an actual submit button in terms of making the enter keypress submit a form, which I find elegant enough, compared to hiding the real one away from the screen. I would replace that in this post, but I don't want to put words in @eterps posts. I also find a hidden input more elegant than the keyup hack.
  • Mayur Randive
    Mayur Randive about 7 years
    ng-keyup="$event.keyCode == 13 && myFunc()" this dose not work in Firefox
  • musa
    musa almost 7 years
    +1 <button ng-show="false"></button> is even shorter. No need to set the value of an invisible button.
  • landesko
    landesko almost 7 years
    It was my understanding that in order to trigger the ng-submit directive, an input of type="submit" ... I suppose value could be ignored but I believe the former is necessary.
  • Alison S
    Alison S almost 7 years
    At least as of Firefox 54.0.1 (64-bit) on Mac OS X the ng-keyup answer works.
  • AForsberg
    AForsberg over 6 years
    This is perfect for when you have a simple input that isn't part of a form! I agree with @NeilS on not prefixing it with 'ng' though.
  • MaylorTaylor
    MaylorTaylor about 6 years
    I get a angluarjs HTML parse error when i try to add a string variable in the function. key-bind="{ enter: 'vm.doTheThing('myVar')' }"
  • MaylorTaylor
    MaylorTaylor about 6 years
    Also noticed that if i use function with an Object as a variable, the function happens more than once. The code below remove 2+ items when i run this. key-bind="{ enter: 'vm.removeItem(item)' }"
  • Alex
    Alex about 6 years
    @MaylorTaylor for the first issue, use different types of quotes i.e. 'vm.doTheThing("myVar")'