Soumettre le formulaire en appuyant sur Entrer avec AngularJS
dans ce cas particulier, quelles options dois-je utiliser pour que ces entrées appellent une fonction lorsque j'appuie sur Entrée?
// 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 réponses
soutient angulaire de ce hors de la boîte. Avez-vous essayé ngSubmit sur votre élément de formulaire?
<form ng-submit="myFunc()" ng-controller="mycontroller">
<input type="text" ng-model="name" />
<br />
<input type="text" ng-model="email" />
</form>
modifier: selon le commentaire concernant le bouton Soumettre, voir soumettre un formulaire en appuyant sur ENTRER sans un bouton Soumettre qui donne la solution de:
<input type="submit" style="position: absolute; left: -9999px; width: 1px; height: 1px;"/>
si vous n'aimez pas la solution de bouton submit caché, vous aurez besoin de lier une fonction de contrôleur à la touche Enter ou Evénement keyup. Cela nécessite normalement une directive personnalisée, mais la bibliothèque AngularUI a déjà mis en place une solution de keypress agréable. Voir http://angular-ui.github.com /
après avoir ajouté la lib angularUI, votre code serait quelque chose comme:
<form ui-keypress="{13:'myFunc($event)'}">
... input fields ...
</form>
ou vous pouvez lier le clavier enter à chaque champ individuel.
Voir aussi ces questions pour créer une simple directive keypres: Comment détecter onKeyUp à AngularJS?
EDIT (2014-08-28): au moment où cette réponse a été écrite, ng-keypress/ng-keyup/ng-keydown n'existait pas en tant que directives natives dans AngularJS. Dans les commentaires ci-dessous @darlan-alves a une assez bonne solution avec:
<input ng-keyup="$event.keyCode == 13 && myFunc()"... />
si vous voulez appeler une fonction Sans formulaire, vous pouvez utiliser ma directive 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>
je soumets d'autres directives impressionnantes sur Mon twitter et mon compte gist .
si vous n'avez qu'une entrée, vous pouvez utiliser l'étiquette de formulaire.
<form ng-submit="myFunc()" ...>
Si vous avez plus d'une entrée, ou ne voulez pas utiliser la balise form, ou souhaitez joindre la touche entrée de la fonctionnalité à un domaine spécifique, vous pouvez l'inclure à une entrée spécifique comme suit:
<input ng-keyup="$event.keyCode == 13 && myFunc()" ...>
je voulais quelque chose d'un peu plus extensible / sémantique que les réponses données donc j'ai écrit une directive qui prend un objet javascript d'une manière similaire à la intégrée ngClass
:
HTML
<input key-bind="{ enter: 'go()', esc: 'clear()' }" type="text"></input>
Les valeurs de l'objet sont évaluées dans le contexte de la directive - s'assurer qu'ils sont enfermés dans des guillemets simples, sinon toutes les fonctions seront exécutées lorsque la directive est chargé(!)
So exemple:
esc : 'clear()'
au lieu 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]);
});
}
});
};
}]);
une autre approche serait d'utiliser ng-keypress,
<input type="text" ng-model="data" ng-keypress="($event.charCode==13)? myfunc() : return">
soumettre une entrée en appuyant sur Entrée avec AngularJS-jsfiddle
directive très bonne, propre et simple avec support 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);
}
}
});
}
}
});
Si vous souhaitez que les données de validation trop
<!-- 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>
l'ajout important ici est $loginForm.$valid
qui validera le formulaire avant d'exécuter la fonction. Vous devrez ajouter d'autres attributs pour la validation, ce qui dépasse la portée de cette question.
Bonne Chance.
j'ai juste voulu souligner que dans le cas d'avoir un bouton submit caché, vous pouvez simplement utiliser la directive ngShow et la mettre à false comme ceci:
HTML
<form ng-submit="myFunc()">
<input type="text" name="username">
<input type="submit" value="submit" ng-show="false">
</form>
utiliser ng-submit et juste envelopper les deux entrées dans des étiquettes de formulaire séparées:
<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>
enveloppant chaque champ d'entrée dans sa propre étiquette de formulaire permet à ENTER d'invoquer submit sur l'un ou l'autre formulaire. Si vous utilisez une étiquette de formulaire pour les deux, vous devrez inclure un bouton Soumettre.
sera légèrement plus net en utilisant une classe CSS au lieu de répéter des styles en ligne.
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-Voici une directive que j'ai utilisée pour un bootstrap modal de base confirm/alert, sans avoir besoin d'un <form>
(il suffit d'échanger l'action jQuery click pour ce que vous voulez, et ajouter data-easy-dismiss
à votre étiquette modale)
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);
});
}
};
});