Disabilita il pulsante di invio quando il modulo non è valido con AngularJS


174

Ho la mia forma in questo modo:

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

Come puoi vedere, il pulsante è disabilitato se l'input è vuoto ma non torna ad essere abilitato quando contiene testo. Come posso farlo funzionare?


Risposte:


339

Devi usare il nome del tuo modulo, oltre a ng-disabled: ecco una demo su Plunker

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

Scusa, lo uso adesso. Tuttavia, è ancora disabilitato anche quando la casella di testo contiene testo
ali

1
+1 Per coincidenza, stavo solo leggendo questo tuo grande post: benlesh.com/2012/11/angular-js-form-validation.html
Ben

cosa succede se non ho un modulo? Posso farlo anche sull'elemento div?
VsMaX,

1
@MichaelCwienczek tecnicamente, è possibile aggiungere ng-forma a un tag div: <div ng-form="myForm"> ... stuff here .. </div>. Tuttavia, se stai inviando un valore dagli input, alla pressione del pulsante, ti consiglio vivamente di utilizzare un <form/>tag, se non altro per consentire a un utente di premere [INVIO] e inviare il modulo. Ma probabilmente costituisce anche una migliore pratica a causa di problemi di accessibilità.
Ben Lesh,

2
@BenLesh, se il pulsante di invio non si trova nel mio modulo e devo disabilitarlo se il modulo non è valido.
Mago verde

33

Da aggiungere a questa risposta. Ho appena scoperto che si romperà anche se usi un trattino nel nome del tuo modulo (Angolare 1.3):

Quindi questo non funzionerà:

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

3
Sì, il nome del modulo deve essere in maiuscolo per eventuali convalide del modulo AngularJS.
dubilla,

7
come regola empirica, tutte le espressioni js come riconoscono gli oggetti in forma di camelcase, mentre trattino è per html come sintassi
ecoologic

Quindi, cosa succede se il modulo è un membro di un formset e pertanto deve contenere un nome con un trattino (come "my_formset_name-0")?
trubliphone

2
Nell'esempio sopra, credo che myForm.$invaliddovrebbe ancora funzionare, quindi nel tuo caso, penso che my_formset_name0.$invaliddovrebbe funzionare.
wvdz,

29

La risposta selezionata è corretta, ma qualcuno come me potrebbe avere problemi con la convalida asincrona con l'invio della richiesta al lato server - il pulsante non verrà disabilitato durante l'elaborazione della richiesta, quindi il pulsante lampeggerà, il che sembra piuttosto strano per gli utenti.

Per annullare ciò, devi solo gestire $ lo stato del modulo in sospeso:

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

Grazie mille per la soluzione di convalida asincrona!
Martin Brandl

Dovresti semplicemente utilizzare anche !myForm.$validquesto per gestire i problemi in sospeso asincroni. itnext.io/valid-and-invalid-in-angular-forms-61cfa3f2a0cd
SavageCore

6

Se stai usando i moduli reattivi puoi usare questo:

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

2
Sebbene questo sia un consiglio valido per "Angular", questa risposta non è valida per "AngularJS". Vale a dire, (click)e [disabled]non sono validi i codici AngularJS, né Reactive Forms fa parte del framework AngularJS. "Angular è il nome dell'Angular di oggi e di domani. AngularJS è il nome di tutte le versioni v1.x
dapperdan1985,

1

Siamo in grado di creare una semplice direttiva e disabilitare il pulsante fino a quando tutti i campi obbligatori sono compilati.

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

Per maggiori informazioni clicca qui


Il tuo metodo di soluzione funziona per me con piccole modifiche. Grazie
Tatipaka,

Perché dovresti farlo quando ci sono direttive native ng-disabledin angolare 1.xe [disabled]angolare 2 | 4.x che sono molto meglio testate di così ?. In secondo luogo, perché avere una direttiva con ambito in un modulo per disabilitare un pulsante nidificato, è super specifica. Una soluzione mal pensata IMO.
David Barker,

Sopra c'è una direttiva di esempio, l'originale ha molti scenari come la casella di controllo nidificata, ecc. E non voglio disordinare il mio codice html aggiungendo in ogni forma, invece questa direttiva si occuperà di tutto.
Prashobh,

1

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

Se vuoi essere un po 'più severo

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.