Wyłącz przycisk przesyłania, gdy formularz jest nieprawidłowy w AngularJS


174

Mam taki formularz:

<form name="myForm">
    <input name="myText" type="text" ng-model="mytext" required />
    <button disabled="{{ myForm.$invalid }}">Save</button>
</form>

Jak widać, przycisk jest wyłączony, jeśli wejście jest puste, ale nie zmienia się z powrotem na włączony, gdy zawiera tekst. Jak mogę to zrobić?


Odpowiedzi:


339

Musisz użyć nazwy swojego formularza, a także ng-disabled: Oto demo na Plunker

<form name="myForm">
    <input name="myText" type="text" ng-model="mytext" required />
    <button ng-disabled="myForm.$invalid">Save</button>
</form>

Przepraszam, używam go teraz. Jednak nadal jest wyłączony, nawet jeśli pole tekstowe zawiera tekst
— ali

1
+1 Przypadkowo właśnie czytałem ten twój wspaniały post: benlesh.com/2012/11/angular-js-form-validation.html
— Ben

co jeśli nie mam formularza? Czy mogę to zrobić również na elemencie div?
— VsMaX

1
@MichaelCwienczek technicznie, można dodać NG-formularz do znacznika div: <div ng-form="myForm"> ... stuff here .. </div>. Chociaż, jeśli przesyłasz wartość z danych wejściowych, po naciśnięciu przycisku, bardzo polecam użycie <form/>tagu, jeśli nie ma innego powodu niż pozwala użytkownikowi nacisnąć [ENTER] i przesłać formularz. Ale prawdopodobnie stanowi to również lepszą praktykę z powodu takich kwestii, jak problemy z dostępnością.
— Ben Lesh

2
@BenLesh, co jeśli przycisku przesyłania nie ma w moim formularzu, a mimo to muszę go wyłączyć, jeśli formularz jest nieprawidłowy.
— Green Wizard

33

Aby dodać do tej odpowiedzi. Właśnie się dowiedziałem, że również się zepsuje, jeśli użyjesz łącznika w nazwie formularza (Angular 1.3):

Więc to nie zadziała:

<form name="my-form">
    <input name="myText" type="text" ng-model="mytext" required />
    <button ng-disabled="my-form.$invalid">Save</button>
</form>

3
Tak, nazwa formularza powinna być w wielbłądzie dla wszystkich walidacji formularza AngularJS.
— Dubilla


A więc co się stanie, jeśli formularz jest członkiem zestawu formularzy i dlatego wymaga się, aby nazwa zawierała łącznik (np. „My_formset_name-0”)?
— trubliphone

2
W powyższym przykładzie uważam, że myForm.$invalidpowinno nadal działać, więc w twoim przypadku myślę, że my_formset_name0.$invalidpowinno działać.
— wvdz

29

Wybrana odpowiedź jest poprawna, ale ktoś taki jak ja może mieć problemy z walidacją asynchroniczną przy wysyłaniu żądania do serwera - przycisk nie będzie wyłączony podczas przetwarzania danego żądania, więc przycisk będzie mrugał, co dla użytkowników wygląda dość dziwnie.

Aby to unieważnić, wystarczy obsłużyć stan $ pending formularza:

<form name="myForm">
  <input name="myText" type="text" ng-model="mytext" required />
  <button ng-disabled="myForm.$invalid || myForm.$pending">Save</button>
</form>

Bardzo dziękuję za rozwiązanie do walidacji asynchronicznej!
— Martin Brandl

Powinieneś po prostu użyć !myForm.$validtego, który obsługuje również oczekujące problemy asynchroniczne. itnext.io/valid-and-invalid-in-angular-forms-61cfa3f2a0cd
— SavageCore

6

Jeśli korzystasz z Reactive Forms, możesz użyć tego:

<button [disabled]="!contactForm.valid" type="submit" class="btn btn-lg btn primary" (click)="printSomething()">Submit</button>

2
Chociaż jest to ważna rada dla „Angular”, ta odpowiedź jest nieprawidłowa dla „AngularJS”. Mianowicie, (click)i [disabled]nie są poprawnym kodem AngularJS, ani Reactive Forms nie są częścią frameworka AngularJS. „Angular to nazwa Angulara
— dapperdan1985

1

Możemy utworzyć prostą dyrektywę i wyłączyć przycisk, aż wszystkie obowiązkowe pola zostaną wypełnione.

angular.module('sampleapp').directive('disableBtn',
function() {
 return {
  restrict : 'A',
  link : function(scope, element, attrs) {
   var $el = $(element);
   var submitBtn = $el.find('button[type="submit"]');
   var _name = attrs.name;
   scope.$watch(_name + '.$valid', function(val) {
    if (val) {
     submitBtn.removeAttr('disabled');
    } else {
     submitBtn.attr('disabled', 'disabled');
    }
   });
  }
 };
}
);

Aby uzyskać więcej informacji, kliknij tutaj


Twoja metoda rozwiązania działa dla mnie z niewielkimi zmianami. Dziękuję
— Tatipaka

Dlaczego miałbyś to robić, skoro natywne dyrektywy ng-disabledw angular 1.x i [disabled]angular 2 | 4.x są znacznie lepiej przetestowane niż to? Po drugie, dlaczego mamy dyrektywę, która jest ograniczona do formularza, aby wyłączyć zagnieżdżony przycisk, jest super specyficzna. Źle przemyślane rozwiązanie IMO.
— David Barker

Powyżej znajduje się przykładowa dyrektywa, oryginalna ma wiele scenariuszy, takich jak zagnieżdżone pole wyboru itp. I nie chcę bałaganić mojego kodu HTML, dodając w każdej formie, zamiast tego ta dyrektywa zajmie się wszystkimi rzeczami.
— Prashobh

1

<form name="myForm">
        <input name="myText" type="text" ng-model="mytext" required/>
        <button ng-disabled="myForm.$pristine|| myForm.$invalid">Save</button>
</form>

Jeśli chcesz być nieco bardziej rygorystyczny

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.