Angularjs giriş doğrulama başarısız olduğunda form gönderilmesini önler


155

Kullanıcı adı ve şifrenin boş ve üç karakterden uzun olmadığını kontrol etmek için bazı istemci tarafı giriş doğrulaması ile angularjs kullanarak basit bir giriş formu yazıyorum. Aşağıdaki koda bakın:

<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>

Ve denetleyici:

var controller = function($scope) {

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

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

};

Sorun, login.submitgiriş geçerli olmasa bile işlevin çağrılmasıdır. Bu davranışı önlemek mümkün müdür?

Bir yan not olarak ben de bootstrap ve requirjs kullandığımı söyleyebilirim.



form etiketi olmadan kullanabilir miyiz ve hala form.valid ng-click üzerinde çalışacaktı!
Rizwan Patel

Yanıtlar:


329

Yapabilirsin:

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

Kontrolör kontrollerine gerek yoktur.


8
Bu kabul edilen cevap olmalı. Kontrol
Howie

10
"Kontrolör kontrolüne gerek yok" fikrine katılmıyorum. Gönder işlevinde ek doğrulama denetimleri yaparsak ne olur?
SlaterCodes

6
Yönergede ek doğrulama gerçekleştirin. Doğrulamayı $ setValidity ile güncelleyin.
TMB

@ b1tsh1ft Doğrulamanın geçerli durumunun, gönderimde anlaşılmak yerine her zaman bilinmesi tercih edilir. Bu açısalın validasyonunun bütün mesele bu. Kapsam bunu bilmiyorsa, geçersiz bir durumun görsel bir göstergesine sahip olamazsınız.
Kevin Beal

1
Ben bu yaklaşımı denedim, ama her ikisi de değerlendirir gibi görünüyor (yani &&ben gönderimin bir parçası olarak değeri geçen denedim ve değerin kendisinin "yanlış" olduğunu doğruladıktan sonra boole kısa devre değil
Archimedes Trajano

67

Gönder düğmesini şu şekilde değiştirin:

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

1
Mükemmel cevap. Harikasın!
Harsha.Vaswani

24
Bir giriş alanı odaktayken enter tuşuna basarsanız da formu gönderebilirsiniz!
fabsenet

2
@ Kırmızı: Yukarıdaki açıklamaya bakın.
Andrei Rînea

Düğmeyi devre dışı bırakmak genellikle bunu çözmenin en iyi yoludur, ancak OP'nin istediği bu değildir.
downhand

1
Form gönderilmesini önlemek için @Yashua yanıtı ile birlikte kullanıcıya görsel geri bildirim sağlamak için bu tekniği birleştirmek mükemmeldir. Teşekkürler!
tkarls

43

Bu yüzden TheHippo tarafından önerilen cevap benim için işe yaramadı, bunun yerine formu böyle bir işleve parametre olarak gönderme sona erdi:

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

Bu, formu denetleyici yönteminde kullanılabilir hale getirir:

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

Aynı sorunu yaşadım. Ancak yönteminizi kullanmak işe yaradı.
Panda4Man

Bu, Kabul Edilen Yanıttan biraz daha iyidir çünkü form. $ Geçerli denetimi HTML'de değil JS'de yapılır.
cellepo

Ancak, işlev göndermek için loginForm geçmek gerektiğini sanmıyorum: $ scope.loginform JS (en azından benim için) kullanılabilir olmalıdır, bu yüzden formu değiştirebilirsiniz. $ Geçerli $ scope.loginform . $ geçerli.
cellepo

13

Formlarınız nesne olarak otomatik olarak $ kapsamına alınır. Erişilebilir$scope[formName]

Aşağıda, orijinal kurulumunuzla çalışacak ve formun kendisini ng-gönder sırasında bir parametre olarak iletmek zorunda kalmadan çalışacak bir örnek bulunmaktadır.

var controller = function($scope) {

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

        }
    }

};

Çalışma örneği: http://plnkr.co/edit/BEWnrP?p=preview


4
$ Scope yerine "Denetleyici Olarak" gösterimini kullanırsanız forma nasıl erişirsiniz?
masimplo

@masimakopoulos: Bunun if(this.loginform.$invalid)yerine sadece .. kullanabilirsiniz ancak HTML'de forma isim vermelisiniz <form name="ctrl.loginform" ... Bu da <div ng-controller="controller as ctrl"..denetleyiciniz sözdiziminde kullandığınızı varsayar . Teşekkür @JoshCaroll
Bart

13

HTML:

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

Kumandanızda:

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

kontrolü, gönderme yöntemi içinde yapmak gerçekten gerekli mi? Bu, girdinin hem biçimlendirme (açısal yoluyla) hem de js kodundaki tüm ölçütleri karşılayıp karşılamadığını kontrol etmeniz gerektiği anlamına gelir. Bence açısal girdi geçersiz olduğunda onubmit çağırmamalısınız. bkz. benlesh.com/2012/11/angular-js-form-validation.html "Tüm form geçerli $ olana kadar ng-gönder çağrılamaz "
Runar Halse

Form geçerliyse gönderime izin vermemek için düğmeyi devre dışı bırakabilirsiniz. Formu bir ng-gönder kullanabilirsiniz. Açısal form doğrulamasını işlemezse event.preventDefault(), form göndermeyi durdurmanın yolu budur.
TheHippo

@RunarHalse Çeki yapmak gerçekten gerekli. Bu şekilde olmaması gerektiğine katılıyorum. Bağladığınız örnekte onsubmit yönteminin çağrılmamasının nedeni, bu örneğin novalidate set olmamasıdır. Tarayıcı, Angular değil olayların artmasını engelliyor. İşte onun nobalidate w / örnek: plnkr.co/edit/R0C8XA?p=preview . Formun gönderildiğine dikkat edin.
davidmdem

mükemmel sadece ne aradığını, açısal kullanarak form gönderme engellemek için bir yol
setebos

3

OP sorusu için doğrudan bir çözüm olmasa da, formunuz bir ng-appbağlam dahilindeyse , ancak Angular'ın bunu tamamen göz ardı etmesini istiyorsanız, bunu doğrudan ngNonBindableyönergeyi kullanarak yapabilirsiniz :

<form ng-non-bindable>
  ...
</form>

2

Sadece yukarıdaki cevaplara eklemek için,

Aşağıda gösterildiği gibi 2 normal düğme vardı. (Tür yok = "gönder" herhangi bir yerde)

<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>

Ne kadar denersem deneyim, form geçerli olduğunda enter tuşuna basıldığında , tüm formu temizleyerek "Formu Temizle" düğmesi çağrıldı.

Geçici bir çözüm olarak,

Devre dışı bırakılmış ve gizlenmiş bir kukla gönderme düğmesi eklemek zorunda kaldım. Ve bu sahte düğmenin aşağıda gösterildiği gibi diğer düğmelerin üstünde olması gerekiyordu .

<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>

Niyetim asla Enter'a boyun eğmek değildi, bu yüzden yukarıda verilen hack iyi çalışıyor.


form-on-özniteliğini formunuzdan kaldırarak da enter tuşuna basmayı bırakabilirsiniz
Kieran

1

Bu eski bir konu olduğunu biliyorum ama ben de bir katkı yapmak düşündüm. Benim çözümüm zaten cevap olarak işaretlenmiş gönderiye benzer. Bazı satır içi JavaScript denetimleri hile yapar.

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

1
Bir giriş alanı odaktayken enter tuşuna basarsanız da formu gönderebilirsiniz!
Yevgeniy Afanasyev

0

Geç olduğunu ve cevaplandığını biliyorum, ama yaptığım düzgün şeyleri paylaşmak istiyorum. Formun gönderilmesini kanca bir ng-validate yönergesi oluşturdum, sonra $ eval yanlış ise önleme-varsayılan sorunları:

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();            
    });
  };
});

HTML'nizde:

<form name="offering" method="post" action="offer" ng-validate="<boolean expression">
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.