web-dev-qa-db-fra.com

Angularjs empêche la soumission du formulaire lorsque la validation d'entrée échoue

J'écris un formulaire de connexion simple en utilisant angularjs avec une validation d'entrée côté client pour vérifier que le nom d'utilisateur et le mot de passe ne sont pas vides et ne comportent pas plus de trois caractères. Voir le code ci-dessous:

<form name="loginform" novalidate ng-submit="login.submit()" class="css-form">
    <fieldset>

        <div class="control-group input-prepend">
            <span class="add-on"><i class="icon-user"></i></span>
            <input type="text" ng-model="login.username" name="username" required ng-minlength="3" placeholder="username" />
        </div>

        <div class="control-group input-prepend">
            <span class="add-on"><i class="icon-lock"></i></span>
            <input type="password" ng-model="login.password" name="password" required ng-minlength="3" placeholder="" />
        </div>

        <div class="control-group">
            <input class="btn" type="submit" value="Log in">
        </div>

    </fieldset>
</form>

Et le contrôleur:

var controller = function($scope) {

    $scope.login = {
        submit: function() {

            Console.info($scope.login.username + ' ' + $scope.login.password);
        }
    }

};

Le problème est que la fonction login.submit sera appelée même si l'entrée n'est pas valide. Est-il possible d'empêcher ce comportement?

En remarque, je peux mentionner que j’utilise bootstrap et requirejs également.

152
Runar Halse

Tu peux faire:

<form name="loginform" novalidate ng-submit="loginform.$valid && login.submit()">

Pas besoin de vérification du contrôleur.

324
cyberwombat

Remplacez le bouton d'envoi par:

<button type="submit" ng-disabled="loginform.$invalid">Login</button>
67
Bijan

Donc, la réponse suggérée par TheHippo n'a pas fonctionné pour moi, à la place, j'ai fini par envoyer le formulaire en tant que paramètre à la fonction, comme ceci:

<form name="loginform" novalidate ng-submit="login.submit(loginForm)" class="css-form">

Cela rend le formulaire disponible dans la méthode du contrôleur:

$scope.login = {
    submit : function(form) {
        if(form.$valid)....
    }
43
Runar Halse

Vos formulaires sont automatiquement placés dans $ scope en tant qu'objet. On peut y accéder via $scope[formName]

Vous trouverez ci-dessous un exemple qui fonctionnera avec votre configuration d'origine sans avoir à passer le formulaire lui-même en tant que paramètre dans ng-submit.

var controller = function($scope) {

    $scope.login = {
        submit: function() {
            if($scope.loginform.$invalid) return false;

        }
    }

};

Exemple de travail: http://plnkr.co/edit/BEWnrP?p=preview

13
davidmdem

HTML:

<div class="control-group">
    <input class="btn" type="submit" value="Log in" ng-click="login.onSubmit($event)">
</div>

Dans votre contrôleur:

$scope.login = {
    onSubmit: function(event) {
        if (dataIsntValid) {
            displayErrors();
            event.preventDefault();
        }
        else {
            submitData();
        }
    }
}
12
TheHippo

Bien que ce ne soit pas une solution directe pour la question des PO, si votre formulaire se trouve dans un contexte ng-app, mais que vous voulez que Angular l'ignore complètement, vous pouvez le faire explicitement à l'aide de ngNonBindable directive:

<form ng-non-bindable>
  ...
</form>
3
Ian Clark

Juste pour ajouter aux réponses ci-dessus,

J'avais 2 boutons réguliers comme indiqué ci-dessous. (Aucun type = "submit" n'importe où)

<button ng-click="clearAll();" class="btn btn-default">Clear Form</button>
<button ng-disabled="form.$invalid" ng-click="submit();"class="btn btn-primary pull-right">Submit</button>

Peu importe combien j'ai essayé, en appuyant sur Entrée une fois que le formulaire était valide, le bouton "Effacer le formulaire" a été appelé, effaçant le formulaire entier.

Pour contourner le problème,

J'ai dû ajouter un bouton de soumission factice qui était désactivé et masqué. Et ce bouton factice devait être au-dessus de tous les autres boutons comme indiqué ci-dessous.

<button type="submit" ng-hide="true" ng-disabled="true">Dummy</button>

<button ng-click="clearAll();" class="btn btn-default">Clear Form</button>

<button ng-disabled="form.$invalid" ng-click="submit();"class="btn btn-primary pull-right">Submit</button>

Bien, mon intention était de ne jamais soumettre sur Enter, donc le hack ci-dessus fonctionne parfaitement.

2
vighnu

Je sais que c'est un vieux fil, mais je pensais aussi apporter ma contribution. Ma solution étant similaire au message déjà marqué comme une réponse. Certaines vérifications JavaScript en ligne font l'affaire.

ng-click="form.$invalid ? alert('Please correct the form') : saveTask(task)"
1
JTC

Je sais qu'il est tard et qu'on m'a répondu, mais j'aimerais partager les trucs intéressants que j'ai faits. J'ai créé une directive ng-validate qui relie la forme au formulaire, puis émet une commande prevent-default si $ eval est false:

app.directive('ngValidate', function() {
  return function(scope, element, attrs) {
    if (!element.is('form'))
        throw new Error("ng-validate must be set on a form elment!");

    element.bind("submit", function(event) {
        if (!scope.$eval(attrs.ngValidate, {'$event': event}))
            event.preventDefault();
        if (!scope.$$phase)
            scope.$digest();            
    });
  };
});

Dans votre html:

<form name="offering" method="post" action="offer" ng-validate="<boolean expression">
0
Ran Cohen