Отправить форму при нажатии 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');
    };
}])
11 ответов
Angular поддерживает это из коробки. Вы пробовали ngSubmit на вашем элементе формы?
<form ng-submit="myFunc()" ng-controller="mycontroller">
   <input type="text" ng-model="name" />
    <br />
    <input type="text" ng-model="email" />
</form>
изменить: в комментарий, касающийся кнопку "Отправить", см. Отправка формы нажатием enter без кнопки отправки который дает решение:
<input type="submit" style="position: absolute; left: -9999px; width: 1px; height: 1px;"/>
Если вам не нравится решение скрытой кнопки отправки, вам нужно связать функцию контроллера с событием Enter keypress или keyup. Это обычно требует custom директива, но библиотека AngularUI уже имеет хорошее решение для нажатия клавиш. См.http://angular-ui.github.com/
после добавления angularui lib, ваш код будет что-то вроде:
<form ui-keypress="{13:'myFunc($event)'}">
  ... input fields ...
</form>
или вы можете привязать клавишу enter к каждому отдельному полю.
кроме того, см. Это SO вопросы для создания простой директивы keypres: как я могу обнаружить onKeyUp в AngularJS?
EDIT (2014-08-28): в то время этот ответ был написан, ng-keypress/ng-keyup / ng-keydown не существовал как собственные директивы в AngularJS. В комментариях ниже @darlan-alves имеет довольно хорошее решение с:
<input ng-keyup="$event.keyCode == 13 && myFunc()"... />
Если вы хотите вызвать функцию без формы, вы можете использовать мою директиву 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>
Я представляю другие удивительные директивы на мой твиттер и меня счета Гист.
Если у вас есть только один вход, можно использовать тег form.
<form ng-submit="myFunc()" ...>
Если у вас есть несколько входных данных, или вы не хотите использовать тег формы, или хотите прикрепить функцию ввода ключа к определенному полю, вы можете встроить его в определенный вход следующим образом:
<input ng-keyup="$event.keyCode == 13 && myFunc()" ...>
Я хотел что-то немного более расширяемое/семантическое, чем данные ответы, поэтому я написал директиву, которая принимает объект 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]);
                    });
                }
            });
        };
    }]);
другой подход будет использовать ng-keypress,
<input type="text" ng-model="data" ng-keypress="($event.charCode==13)? myfunc() : return"> 
отправить ввод при нажатии Enter с помощью AngularJS-jsfiddle
очень хорошая, чистая и простая директива с поддержкой 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);
                       }
                 }
            });
        }
    }
});
Если вы хотите, чтобы проверка данных
<!-- 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 который проверит форму перед выполнением функции.  Вам нужно будет добавить другие атрибуты для проверки, которые выходят за рамки этого вопроса.
Удачи.
просто хотел указать, что в случае наличия скрытой кнопки отправки вы можете просто использовать директиву ngShow и установить ее в false следующим образом:
HTML-код
<form ng-submit="myFunc()">
    <input type="text" name="username">
    <input type="submit" value="submit" ng-show="false">
</form>
используйте 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 в любой форме. Если вы используете один тег формы для обоих, вам нужно будет включить кнопку отправки.
будет немного аккуратнее, используя класс 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>
FWIW-вот директива, которую я использовал для базовой модальной загрузки подтверждения / оповещения, без необходимости <form>
(просто выключите действие щелчка 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);
            });
        }
    };
});
