Enviar formulario al presionar Enter con AngularJS
En este caso particular, ¿qué opciones tengo para hacer que estas entradas llamen a una función cuando presiono 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');
};
}])
Angular admite esto desde el primer momento. ¿ Has probado ngSubmit en tu elemento de formulario?
<form ng-submit="myFunc()" ng-controller="mycontroller">
<input type="text" ng-model="name" />
<br />
<input type="text" ng-model="email" />
</form>
EDITAR: Según el comentario sobre el botón de enviar, consulte Envío de un formulario presionando Intro sin un botón de envío que brinda la solución de:
<input type="submit" style="position: absolute; left: -9999px; width: 1px; height: 1px;"/>
Si no le gusta la solución del botón de envío oculto, deberá vincular una función de controlador al evento de pulsación de tecla Enter o keyup. Esto normalmente requiere una directiva personalizada, pero la biblioteca AngularUI ya tiene configurada una buena solución de pulsación de teclas. Ver http://angular-ui.github.com/
Después de agregar la biblioteca angularUI, su código sería algo como:
<form ui-keypress="{13:'myFunc($event)'}">
... input fields ...
</form>
o puede vincular la pulsación de la tecla Intro a cada campo individual.
Además, consulte estas preguntas SO para crear una directiva keypres simple: ¿ Cómo puedo detectar onKeyUp en AngularJS?
EDITAR (28/08/2014): En el momento en que se escribió esta respuesta, ng-keypress/ng-keyup/ng-keydown no existían como directivas nativas en AngularJS. En los comentarios a continuación, @darlan-alves tiene una solución bastante buena con:
<input ng-keyup="$event.keyCode == 13 && myFunc()"... />
Si desea llamar a una función sin formulario, puede usar mi directiva 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>
Envío otras directivas increíbles en mi Twitter y mi cuenta Gist .
Si solo tiene una entrada, puede usar la etiqueta de formulario.
<form ng-submit="myFunc()" ...>
Si tiene más de una entrada, no desea utilizar la etiqueta de formulario o desea adjuntar la función de tecla Intro a un campo específico, puede alinearla en una entrada específica de la siguiente manera:
<input ng-keyup="$event.keyCode == 13 && myFunc()" ...>
Quería algo un poco más extensible/semántico que las respuestas dadas, así que escribí una directiva que toma un objeto javascript de manera similar a la incorporada ngClass
:
HTML
<input key-bind="{ enter: 'go()', esc: 'clear()' }" type="text"></input>
Los valores del objeto se evalúan en el contexto del alcance de la directiva; asegúrese de que estén entre comillas simples, de lo contrario, todas las funciones se ejecutarán cuando se cargue la directiva (!)
Así por ejemplo:
esc : 'clear()'
en lugar deesc : 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]);
});
}
});
};
}]);