Отправить форму при нажатии 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 ответов:
Угловое поддерживает это из коробки. Вы пробовали ngSubmit на вашем элементе формы?
<form ng-submit="myFunc()" ng-controller="mycontroller"> <input type="text" ng-model="name" /> <br /> <input type="text" ng-model="email" /> </form>
EDIT: за комментарий относительно кнопки отправки см. Отправка формы нажатием enter без кнопки отправки что дает решение:
<input type="submit" style="position: absolute; left: -9999px; width: 1px; height: 1px;"/>
Если вам не нравится решение скрытой кнопки отправки, вам нужно будет привязать функцию контроллера к событию Enter keypress или keyup. Обычно для этого требуется обычай директива,но библиотека 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>
Я представляю другие удивительные директивы на мой твиттер и меня gist account.
Если у вас есть только один вход, можно использовать тег 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-нажатие клавиши,
<input type="text" ng-model="data" ng-keypress="($event.charCode==13)? myfunc() : return">
очень хорошая, чистая и простая директива с поддержкой 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-вот директива, которую я использовал для базового модального подтверждения / оповещения bootstrap, без необходимости
<form>
(просто выключите действие jQuery click для всего, что вам нравится, и добавьте
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); }); } }; });