web-dev-qa-db-fra.com

Envoyer le formulaire en appuyant sur Entrée avec AngularJS

Dans ce cas particulier, quelles options ai-je pour que ces entrées appellent une fonction lorsque je presse 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');
    };
}])
355
ali

Angular le supporte 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>

EDIT: Pour le commentaire concernant le bouton de soumission, voir Soumettre un formulaire en appuyant sur Entrée sans un bouton de soumission 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 masqué, vous devez associer une fonction de contrôleur à l'événement Saisir ou appuyer. Cela nécessite normalement une directive personnalisée, mais la bibliothèque AngularUI a déjà une solution Nice keypress configurée. Voir http://angular-ui.github.com/

Après avoir ajouté angularUI lib, votre code ressemblerait à ceci:

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

ou vous pouvez lier la touche Entrée à chaque champ individuel.

Consultez également les SO questions relatives à la création d'une directive keypres simple: Comment puis-je détecter onKeyUp dans AngularJS?

EDIT (2014-08-28): Au moment de l'écriture de cette réponse, ng-keypress/ng-keyup/ng-keydown n'existait pas sous forme de directives natives dans AngularJS. Dans les commentaires ci-dessous, @ darlan-alves a une très bonne solution avec:

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

514
eterps

Si vous voulez appeler une fonction sans 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 d’autres directives impressionnantes sur mon Twitter et mon compte Gist .

281
EpokK

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

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

Si vous avez plusieurs entrées, ou si vous ne souhaitez pas utiliser la balise de formulaire, ou si vous souhaitez associer la fonctionnalité de saisie de clé à un champ spécifique, vous pouvez l'ajouter à une entrée spécifique comme suit:

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

Je voulais quelque chose d'un peu plus extensible/sémantique que les réponses données alors j'ai écrit une directive qui prend un objet javascript de la même manière que la variable 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 lors du chargement de la directive (!)

Ainsi, 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]);
                    });
                }
            });
        };
    }]);
33
AlexFoxGill

Une autre approche consisterait à utiliser ng-keypress, 

<input type="text" ng-model="data" ng-keypress="($event.charCode==13)? myfunc() : return"> 

Soumettez une entrée en appuyant sur Entrée avec AngularJS - jsfiddle

23
Partha Roy

Très bonne, directive simple et propre avec shift + enter support

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);
                       }
                 }
            });
        }
    }
});
14
Vlatko

Si vous voulez aussi la validation des données

<!-- 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 le cadre de cette question.

Bonne chance.

5
Akash

Je voulais simplement souligner que dans le cas d’un bouton de soumission masqué, vous pouvez simplement utiliser la directive ngShow et la définir sur false comme suit:

HTML

<form ng-submit="myFunc()">
    <input type="text" name="username">
    <input type="submit" value="submit" ng-show="false">
</form>
2
landesko

Utilisez ng-submit et emballez simplement les deux entrées dans des balises de formulaire distinctes:

<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 de saisie dans sa propre balise de formulaire, ENTRÉE invoque la soumission sur l'un ou l'autre des formulaires. Si vous utilisez une balise de formulaire pour les deux, vous devrez inclure un bouton d'envoi.

1
Myclamm

FWIW - Voici une directive que j'ai utilisée pour un modal d'amorçage confirmation/alerte de base, sans avoir besoin d'un <form>

(il suffit de désactiver l'action de clic jQuery pour ce que vous voulez et d'ajouter data-easy-dismiss à votre balise 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);
            });
        }
    };
});
0
Andrew Appleby

Sera légèrement plus propre en utilisant une classe CSS au lieu de répéter les 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>
0
guya