Submit form on pressing Enter with AngularJS

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

// HTML view //
<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');
    };
}])

Answers


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()"... />


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.


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()" ...>

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

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


Very good, clean and simple directive with shift + enter support:

app.directive('enterSubmit', function () {
    return {
        restrict: 'A',
        link: function (scope, elem, attrs) {
            elem.bind('keydown', function(event) {
                 var code = event.keyCode || event.which;
                 if (code === 13) {
                       if (!event.shiftKey) {
                            event.preventDefault();
                            scope.$apply(attrs.enterSubmit);
                       }
                 }
            });
        }
    }
});

If you want data validation too

<!-- form -->
<form name="loginForm">
...
  <input type="email" ng-keyup="$loginForm.$valid && $event.keyCode == 13 && signIn()" ng-model="email"... />
  <input type="password" ng-keyup="$loginForm.$valid && $event.keyCode == 13 && signIn()" ng-model="password"... />
</form>

The important addition here is $loginForm.$valid which will validate the form before executing function. You will have to add other attributes for validation which is beyond the scope of this question.

Good Luck.


Just wanted to point out that in the case of having a hidden submit button, you can just use the ngShow directive and set it to false like so:

HTML

<form ng-submit="myFunc()">
    <input type="text" name="username">
    <input type="submit" value="submit" ng-show="false">
</form>

Use ng-submit and just wrap both inputs in separate form tags:

<div ng-controller="mycontroller">

  <form ng-submit="myFunc()">
    <input type="text" ng-model="name" <!-- Press ENTER and call myFunc --> />
  </form>

  <br />

  <form ng-submit="myFunc()">
    <input type="text" ng-model="email" <!-- Press ENTER and call myFunc --> />
  </form>

</div>

Wrapping each input field in its own form tag allows ENTER to invoke submit on either form. If you use one form tag for both, you will have to include a submit button.


Will be slightly neater using a CSS class instead of repeating inline styles.

CSS

input[type=submit] {
    position: absolute;
    left: -9999px;
}

HTML

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

FWIW - Here's a directive I've used for a basic confirm/alert bootstrap modal, without the need for a <form>

(just switch out the jQuery click action for whatever you like, and add data-easy-dismiss to your modal tag)

app.directive('easyDismiss', function() {
    return {
        restrict: 'A',
        link: function ($scope, $element) {

            var clickSubmit = function (e) {
                if (e.which == 13) {
                    $element.find('[type="submit"]').click();
                }
            };

            $element.on('show.bs.modal', function() {
                $(document).on('keypress', clickSubmit);
            });

            $element.on('hide.bs.modal', function() {
                $(document).off('keypress', clickSubmit);
            });
        }
    };
});

Need Your Help

What is "string[] args" in Main class for?

c#

In C# the Main class has string[] args parameter.

Anything better than PHPDoc out there?

php documentation documentation-generation phpdoc

Does anybody use anything else to document their PHP code than PHPDoc?