369 votes

Soumettre le formulaire en appuyant sur Entrée avec AngularJS

Dans ce cas particulier, quelles sont les options dont je dispose pour que ces entrées appellent une fonction lorsque j'appuie sur la touche 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');
    };
}])

522voto

eterps Points 7567

Angular prend cela en charge dès le départ. 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>

EDIT : Pour le commentaire concernant le bouton de soumission, voir Soumission d'un formulaire en appuyant sur la touche Entrée sans bouton de soumission ce qui donne la solution de :

<input type="submit" style="position: absolute; left: -9999px; width: 1px; height: 1px;"/>

Si vous n'aimez pas la solution du bouton d'envoi caché, vous devrez lier une fonction de contrôleur à l'événement d'appui sur la touche Enter ou à l'événement keyup. Cela nécessite normalement une directive personnalisée, mais la bibliothèque AngularUI dispose déjà d'une solution de pression de touche intéressante. Voir http://angular-ui.github.com/

Après avoir ajouté la librairie angularUI, votre code serait quelque chose comme :

<form ui-keypress="{13:'myFunc($event)'}">
  ... input fields ...
</form>

ou vous pouvez lier la touche d'entrée à chaque champ individuel.

Vous pouvez également consulter les questions du SO pour créer une directive keypres simple : Comment détecter onKeyUp dans AngularJS ?

MODIFIER (2014-08-28) : Au moment où cette réponse a été écrite, ng-keypress/ng-keyup/ng-keydown n'existaient 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()"... />

9 votes

Cela ne fonctionne que si j'ai un bouton d'envoi à l'intérieur du formulaire, également.

0 votes

Je vais y aller avec la directive personnalisée, je ne peux pas utiliser angular-ui. Merci

0 votes

Qu'en est-il de ng-change ?

289voto

EpokK Points 11131

Si vous voulez appeler la fonction sans la forme, 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 aux autres d'impressionnantes directives sur mon twitter et mon compte gist .

2 votes

Existe-t-il un moyen astucieux de faire en sorte que cela se déclenche chaque fois qu'ils appuient sur la touche "Entrée" sur votre page ?

1 votes

@EpokK Je veux désactiver la touche d'entrée pour tout le formulaire, comment puis-je faire cela ? (Je veux éviter la soumission du formulaire avec la touche Entrée)

0 votes

@AntonioMax Vous pourriez simplement avoir un drapeau supplémentaire dans la directive qui vérifie si vous voulez que la personne puisse soumettre ou non.

201voto

Jo Jo Points 506

Si vous n'avez qu'une seule entrée, vous pouvez utiliser la balise form.

<form ng-submit="myFunc()" ...>

Si vous avez plus d'une entrée, ou si vous ne voulez pas utiliser la balise de formulaire, ou si vous voulez attacher la fonctionnalité de touche d'entrée à un champ spécifique, vous pouvez la mettre en ligne sur une entrée spécifique comme suit :

<input ng-keyup="$event.keyCode == 13 && myFunc()" ...>

3 votes

Il s'agit d'une manière intelligente de faire cela sans même avoir à écrire votre propre directive.

62 votes

Encore plus court : <input ng-keyup="$event.keyCode == 13 && myFunc()"... />

0 votes

Cela fonctionne très bien, j'ai utilisé la directive ng-keyup, mais j'ai un gros problème avec elle, si je n'ai qu'un seul champ de texte, il soumet le formulaire complet (postback) mais je ne veux pas cela. J'ai déjà essayé ng-keyup="$event.keyCode == 13 && onTextBoxKeyUp($event)" et dans la fonction "event.preventDefault() ;", mais ça n'a pas aidé ;(

34voto

Alex G Points 1939

Je voulais quelque chose d'un peu plus extensible/sémantique que les réponses données. J'ai donc écrit une directive qui prend un objet javascript d'une manière similaire à la directive 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 portée de la directive - assurez-vous qu'elles sont placées entre guillemets simples, sinon toutes les fonctions seront exécutées lorsque la directive sera chargée ( !).

Donc, par 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]);
                    });
                }
            });
        };
    }]);

0 votes

J'obtiens une erreur d'analyse HTML d'angluarjs lorsque j'essaie d'ajouter une variable de type chaîne dans la fonction. key-bind="{ enter : 'vm.doTheThing('myVar')'' }"

0 votes

J'ai également remarqué que si j'utilise une fonction avec un objet comme variable, la fonction se produit plus d'une fois. Le code ci-dessous supprime plus de 2 éléments lorsque je l'exécute. key-bind="{ enter : 'vm.removeItem(item)' }"

1 votes

@MaylorTaylor pour le premier numéro, utilisez différents types de citations, par exemple. 'vm.doTheThing("myVar")'

0voto

guya Points 601

L'utilisation d'une classe CSS au lieu de la répétition des styles en ligne sera légèrement plus soignée.

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>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X