function - detectar - Enviar formulario al presionar Enter con AngularJS
enviar formulario angularjs (11)
En este caso particular, ¿qué opciones tengo para hacer que estas entradas llamen una función cuando presiono Entrar?
// 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'');
};
}])
Angular soporta esto fuera de la caja. ¿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 envío, vea Enviar un formulario presionando el botón Entrar sin un botón de envío que ofrece la solución de:
<input type="submit" style="position: absolute; left: -9999px; width: 1px; height: 1px;"/>
Si no le gusta la solución de botón de envío oculto, tendrá que vincular una función de controlador al evento Presionar tecla o evento 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, tu código sería algo así como:
<form ui-keypress="{13:''myFunc($event)''}">
... input fields ...
</form>
o puede enlazar la tecla enter a cada campo individual.
Además, vea estas preguntas SO para crear una directiva simple de keypres: ¿Cómo puedo detectar onKeyUp en AngularJS?
EDITAR (2014-08-28): Cuando 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()"... />
Directiva muy buena, limpia y simple con cambio + ingresar soporte:
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);
}
}
});
}
}
});
FWIW - Aquí hay una directiva que he usado para un modo básico de inicio / confirmación de alerta, sin la necesidad de un <form>
(simplemente cambia la acción de jQuery click para lo que quieras y agrega data-easy-dismiss
a tu etiqueta modal)
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);
});
}
};
});
Otro enfoque sería utilizar ng-keypress,
<input type="text" ng-model="data" ng-keypress="($event.charCode==13)? myfunc() : return">
Enviar una entrada al presionar Enter con AngularJS - jsfiddle
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 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 encerrados entre comillas simples; de lo contrario, todas las funciones se ejecutarán cuando se cargue la directiva (!)
Así por ejemplo: esc : ''clear()''
lugar de 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]);
});
}
});
};
}]);
Será un poco más limpio usando una clase CSS en lugar de repetir estilos en línea.
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>
Si desea llamar a la 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>
Presento otras directivas increíbles en mi cuenta de Twitter y mi gist .
Si solo tiene una entrada, puede usar la etiqueta de formulario.
<form ng-submit="myFunc()" ...>
Si tiene más de una entrada, o no desea usar la etiqueta de formulario, o si desea adjuntar la funcionalidad de tecla de entrada a un campo específico, puede incluirla en una entrada específica de la siguiente manera:
<input ng-keyup="$event.keyCode == 13 && myFunc()" ...>
Solo quería señalar que en el caso de tener un botón de envío oculto, puede usar la directiva ngShow y establecerlo como falso así:
HTML
<form ng-submit="myFunc()">
<input type="text" name="username">
<input type="submit" value="submit" ng-show="false">
</form>
Use ng-submit y simplemente ajuste ambas entradas en etiquetas de formulario separadas:
<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>
Al ajustar cada campo de entrada en su propia etiqueta de formulario, ENTER puede invocar el envío en cualquiera de los formularios. Si usa una etiqueta de formulario para ambos, deberá incluir un botón de envío.
Si quieres validación de datos también
<!-- 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>
La adición importante aquí es $loginForm.$valid
que validará el formulario antes de ejecutar la función. Tendrá que agregar otros atributos para la validación que está fuera del alcance de esta pregunta.
Buena suerte.