Deaktivieren Sie die Schaltfläche "Senden", wenn das Formular mit AngularJS ungültig ist

174

Ich habe meine Form so:

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

Wie Sie vielleicht sehen, ist die Schaltfläche deaktiviert, wenn die Eingabe leer ist, sie wird jedoch nicht wieder aktiviert, wenn sie Text enthält. Wie kann ich es zum Laufen bringen?

ali
quelle

Antworten:

339

Sie müssen den Namen Ihres Formulars sowie ng-disabled verwenden: Hier ist eine Demo zu Plunker

<form name="myForm">
    <input name="myText" type="text" ng-model="mytext" required />
    <button ng-disabled="myForm.$invalid">Save</button>
</form>
Ben Lesh
quelle
Entschuldigung, ich benutze es jetzt. Es ist jedoch weiterhin deaktiviert, auch wenn das Textfeld Text enthält
ali
1
+1 Zufälligerweise habe ich gerade Ihren großartigen Beitrag gelesen
Ben
Was ist, wenn ich kein Formular habe? Kann ich das auch auf div element machen?
VsMaX
1
@MichaelCwienczek technisch gesehen können Sie einem div-Tag ng-form hinzufügen : <div ng-form="myForm"> ... stuff here .. </div>. Wenn Sie jedoch einen Wert von Eingaben per Knopfdruck übermitteln, empfehle ich dringend , ein <form/>Tag zu verwenden, wenn ein Benutzer aus keinem anderen Grund [ENTER] drücken und das Formular senden kann. Aber es ist wahrscheinlich auch eine bessere Praxis, wenn es um Zugänglichkeit geht.
Ben Lesh
2
@ BenLesh, was ist, wenn sich die Schaltfläche "Senden" nicht in meinem Formular befindet und ich sie trotzdem deaktivieren muss, wenn das Formular ungültig ist.
Grüner Zauberer
33

Zu dieser Antwort hinzufügen. Ich habe gerade herausgefunden, dass es auch zusammenbricht, wenn Sie einen Bindestrich in Ihrem Formularnamen verwenden (Winkel 1.3):

Das wird also nicht funktionieren:

<form name="my-form">
    <input name="myText" type="text" ng-model="mytext" required />
    <button ng-disabled="my-form.$invalid">Save</button>
</form>
wvdz
quelle
3
Ja, der Formularname sollte für alle AngularJS-Formularvalidierungen in Kamelbuchstaben angegeben werden.
Dubilla
7
Als Faustregel gilt, dass alle js-ähnlichen Ausdrücke Objekte in der Camelcase-Form erkennen, während der Bindestrich für HTML-ähnliche Syntax gilt
ecoologic
Was passiert also, wenn das Formular Mitglied eines Formularsatzes ist und daher einen Namen mit einem Bindestrich enthalten muss (z. B. "my_formset_name-0")?
Trubliphone
2
Im obigen Beispiel sollte es meiner Meinung myForm.$invalidnach immer noch funktionieren. In Ihrem Fall würde ich denken, my_formset_name0.$invaliddass es funktionieren sollte.
wvdz
29

Die ausgewählte Antwort ist korrekt, aber jemand wie ich hat möglicherweise Probleme mit der asynchronen Validierung beim Senden einer Anfrage an den Server. Die Schaltfläche wird während der Verarbeitung einer bestimmten Anforderung nicht deaktiviert, sodass die Schaltfläche blinkt, was für die Benutzer ziemlich seltsam aussieht.

Um dies aufzuheben, müssen Sie nur den Status $ ausstehend des Formulars verarbeiten:

<form name="myForm">
  <input name="myText" type="text" ng-model="mytext" required />
  <button ng-disabled="myForm.$invalid || myForm.$pending">Save</button>
</form>
Ivan Sokalskiy
quelle
Vielen Dank für die asynchrone Validierungslösung!
Martin Brandl
Sie sollten nur verwenden !myForm.$valid, um auch asynchrone ausstehende Probleme zu behandeln. itnext.io/valid-and-invalid-in-angular-forms-61cfa3f2a0cd
SavageCore
6

Wenn Sie reaktive Formulare verwenden, können Sie Folgendes verwenden:

<button [disabled]="!contactForm.valid" type="submit" class="btn btn-lg btn primary" (click)="printSomething()">Submit</button>
Nelul
quelle
2
Obwohl dies ein gültiger Hinweis für "Angular" ist, ist diese Antwort für "AngularJS" ungültig. Das heißt, (click)und [disabled]sind nicht gültig AngularJS Code, noch sind Reactive Bildet einen Teil des AngularJS Rahmen. "Angular ist der Name für den Angular von heute und morgen. AngularJS ist der Name für alle v1.x-Versionen von Angular" angular.io/guide/ajs-quick-reference
dapperdan1985
1

Wir können eine einfache Anweisung erstellen und die Schaltfläche deaktivieren, bis alle Pflichtfelder ausgefüllt sind.

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

Für weitere Informationen klicken Sie hier

Prashobh
quelle
Ihre Lösungsmethode funktioniert bei mir mit kleinen Änderungen. Vielen Dank
Tatipaka
Warum sollten Sie dies tun, wenn es native Anweisungen ng-disabledin Winkel 1.x und [disabled]in Winkel 2 | 4.x gibt, die viel besser getestet werden? Zweitens, warum sollte eine Direktive, die auf ein Formular beschränkt ist, um eine verschachtelte Schaltfläche zu deaktivieren, sehr spezifisch sein? Eine schlecht durchdachte Lösung IMO.
David Barker
Oben ist eine Beispielanweisung, Original hat viele Szenarien wie verschachtelte Kontrollkästchen usw. und ich möchte meinen HTML-Code nicht durch Hinzufügen in jeder Form durcheinander bringen, stattdessen kümmert sich diese Anweisung um alle Dinge.
Prashobh
1

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

Wenn Sie etwas strenger sein wollen

Cengkuru Michael
quelle