Отправить форму при нажатии Enter с помощью AngularJS

В этом конкретном случае, какие параметры я должен сделать, чтобы эти входы вызывали функцию, когда я нажимаю 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');
    };
}])

Ответ 1

Angular поддерживает это из коробки. Вы пробовали ngSubmit в элементе формы?

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

EDIT: за комментарий относительно кнопки отправки см. Отправка формы нажатием кнопки без кнопки отправки, которая дает решение:

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

Если вам не нравится решение скрытой кнопки отправки, вам необходимо связать функцию контроллера с нажатием клавиши Enter или keyup. Для этого обычно требуется специальная директива, но в библиотеке AngularUI уже создано отличное решение для нажатия клавиш. См. http://angular-ui.github.com/

После добавления angularUI lib ваш код будет выглядеть примерно так:

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

или вы можете привязать клавишу ввода к каждому отдельному полю.

Также см. эти вопросы SO для создания простой директивы keypres: Как я могу обнаружить onKeyUp в AngularJS?

EDIT (2014-08-28): Во время написания этого ответа ng-keypress/ng-keyup/ng-keydown не существовало как родные директивы в AngularJS. В комментариях ниже @darlan-alves имеет довольно хорошее решение:

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

Ответ 2

Если вы хотите вызвать функцию без формы, вы можете использовать мою директиву ngEnter:

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>

Я представляю другие удивительные директивы на мой твиттер и мой gist account.

Ответ 3

Если у вас есть только один ввод, вы можете использовать тег формы.

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

Если у вас несколько входных данных или вы не хотите использовать тег формы или хотите добавить функциональные возможности ввода в определенное поле, вы можете вставить его на конкретный вход следующим образом:

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

Ответ 4

Я хотел что-то немного более расширяемое/семантическое, чем заданные ответы, поэтому я написал директиву, которая принимает объект javascript аналогично встроенному ngClass:

HTML

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

Значения объекта оцениваются в контексте области действия - убедитесь, что они заключены в одинарные кавычки, иначе все функции будут выполняться при загрузке директивы (!)

Итак, например: esc : 'clear()' вместо 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]);
                    });
                }
            });
        };
    }]);

Ответ 5

Очень хорошая, чистая и простая директива с поддержкой shift + enter:

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

Ответ 7

Если вы хотите проверить достоверность данных

<!-- 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>

Важным дополнением здесь является $loginForm.$valid, который будет проверять форму перед выполнением функции. Вам придется добавить другие атрибуты для проверки, которые выходят за рамки этого вопроса.

Удачи.

Ответ 8

Просто хотел указать, что в случае наличия скрытой кнопки отправки вы можете просто использовать директиву ngShow и установить ее как false:

HTML

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

Ответ 9

Используйте ng-submit и просто оберните оба входа в теги отдельной формы:

<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>

Обтекание каждого поля ввода в его собственном теге формы позволяет ENTER для вызова submit в любой форме. Если вы используете один тег формы для обоих, вам нужно будет добавить кнопку отправки.

Ответ 10

Будет немного более аккуратным, используя класс CSS вместо повторения встроенных стилей.

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>

Ответ 11

FWIW - вот директива, которую я использовал для базового подтверждения/оповещения для бутстрапа, без необходимости в <form>

(просто отключите действие click для jQuery для всех, что вам нравится, и добавьте data-easy-dismiss в ваш модальный тег)

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