Nonaktifkan tombol kirim ketika formulir tidak valid dengan AngularJS

174

Saya memiliki formulir saya seperti ini:

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

Seperti yang Anda lihat, tombol dinonaktifkan jika input kosong tetapi tidak berubah kembali menjadi diaktifkan ketika berisi teks. Bagaimana saya bisa membuatnya bekerja?

ali
sumber

Jawaban:

339

Anda harus menggunakan nama formulir Anda, dan juga non -aktif: Ini demo di Plunker

<form name="myForm">
    <input name="myText" type="text" ng-model="mytext" required />
    <button ng-disabled="myForm.$invalid">Save</button>
</form>
Ben Lesh
sumber
Maaf, saya menggunakannya sekarang. Namun, itu masih dinonaktifkan bahkan ketika kotak teks berisi teks
ali
1
+1 Secara kebetulan, saya baru saja membaca tulisan Anda yang luar biasa ini: benlesh.com/2012/11/angular-js-form-validation.html
Ben
bagaimana jika saya tidak memiliki formulir? Bisakah saya melakukannya juga pada elemen div?
VsMaX
1
@MichaelCwienczek teknis, Anda dapat menambahkan ng-bentuk untuk tag div: <div ng-form="myForm"> ... stuff here .. </div>. Meskipun, jika Anda mengirimkan nilai dari input, dengan menekan tombol, saya sangat merekomendasikan menggunakan <form/>tag, jika tidak ada alasan lain selain itu memungkinkan pengguna untuk menekan [ENTER] dan mengirimkan formulir. Tetapi itu juga kemungkinan merupakan praktik yang lebih baik karena hal-hal seperti masalah aksesibilitas.
Ben Lesh
2
@ BenLesh, bagaimana jika tombol kirim tidak di dalam formulir saya dan saya masih harus menonaktifkannya jika formulir tidak valid.
Penyihir Hijau
33

Untuk menambah jawaban ini. Saya baru tahu bahwa itu juga akan rusak jika Anda menggunakan tanda hubung dalam nama formulir Anda (Angular 1.3):

Jadi ini tidak akan berfungsi:

<form name="my-form">
    <input name="myText" type="text" ng-model="mytext" required />
    <button ng-disabled="my-form.$invalid">Save</button>
</form>
wvdz
sumber
3
Ya, nama formulir harus dalam huruf unta untuk validasi formulir AngularJS apa pun.
dubilla
7
sebagai aturan praktis, semua js seperti ekspresi akan mengenali objek dalam bentuk camelcase, sementara tanda hubung adalah untuk html seperti sintaks
ecoologic
Jadi, apa yang terjadi jika form tersebut adalah anggota dari suatu formset, dan oleh karena itu diharuskan memiliki nama dengan tanda hubung di dalamnya (seperti "my_formset_name-0")?
trubliphone
2
Dalam contoh di atas, saya yakin myForm.$invalidmasih akan berfungsi, jadi dalam kasus Anda, saya pikir my_formset_name0.$invalidharus bekerja.
wvdz
29

Respons yang dipilih sudah benar, tetapi seseorang seperti saya, mungkin memiliki masalah dengan validasi async dengan mengirim permintaan ke sisi server - tombol tidak akan dinonaktifkan selama pemrosesan permintaan yang diberikan, sehingga tombol akan berkedip, yang terlihat cukup aneh bagi pengguna.

Untuk membatalkan ini, Anda hanya perlu menangani bentuk $ pending dari formulir:

<form name="myForm">
  <input name="myText" type="text" ng-model="mytext" required />
  <button ng-disabled="myForm.$invalid || myForm.$pending">Save</button>
</form>
Ivan Sokalskiy
sumber
Terima kasih banyak atas solusi validasi async!
Martin Brandl
Anda hanya harus menggunakan !myForm.$validyang menangani masalah Pending async juga. itnext.io/valid-and-invalid-in-angular-forms-61cfa3f2a0cd
SavageCore
6

Jika Anda menggunakan Formulir Reaktif, Anda dapat menggunakan ini:

<button [disabled]="!contactForm.valid" type="submit" class="btn btn-lg btn primary" (click)="printSomething()">Submit</button>
Nelul
sumber
2
Meskipun ini adalah saran yang valid untuk "Angular", jawaban ini tidak valid untuk "AngularJS". Yaitu, (click)dan [disabled]bukan kode AngularJS yang valid, juga bukan Reaktif yang merupakan bagian dari kerangka kerja AngularJS. "Angular adalah nama untuk Angular hari ini dan besok. AngularJS adalah nama untuk semua versi v1.x Angular" angular.io/guide/ajs-quick-reference
dapperdan1985
1

Kami dapat membuat arahan sederhana dan menonaktifkan tombol sampai semua bidang wajib diisi.

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

Untuk Info Lebih Lanjut klik di sini

Prashobh
sumber
Metode solusi Anda bekerja untuk saya dengan sedikit perubahan. Terima kasih
Tatipaka
Mengapa Anda melakukan ini ketika ada arahan asli ng-disableddi sudut 1.x dan [disabled]di sudut 2 | 4.x yang jauh lebih baik diuji daripada ini ?. Kedua, mengapa memiliki arahan yang mencakup ke bentuk untuk menonaktifkan tombol bersarang, itu super spesifik. IMO solusi yang dipikirkan dengan buruk.
David Barker
Di atas adalah contoh direktif, asli memiliki banyak skenario seperti kotak centang bersarang dll dan saya tidak ingin mengacaukan kode html saya dengan menambahkan dalam setiap bentuk, sebaliknya arahan ini akan mengurus semua hal.
Prashobh
1

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

Jika Anda ingin sedikit lebih ketat

Cengkuru Michael
sumber