Saya menggunakan Plugin jQuery Validate yang sangat baik untuk memvalidasi beberapa formulir. Pada satu formulir, saya perlu memastikan bahwa pengguna mengisi setidaknya satu dari sekelompok bidang. Saya rasa saya punya solusi yang cukup bagus, dan ingin membagikannya. Harap sarankan perbaikan apa pun yang dapat Anda pikirkan.
Karena tidak menemukan cara bawaan untuk melakukan ini, saya mencari dan menemukan metode validasi khusus Rebecca Murphey , yang sangat membantu.
Saya meningkatkan ini dengan tiga cara:
- Untuk membiarkan Anda meneruskan pemilih untuk grup bidang
- Untuk membiarkan Anda menentukan berapa banyak dari grup itu yang harus diisi agar validasi lulus
- Untuk menampilkan semua input dalam grup sebagai lolos validasi segera setelah salah satunya lolos validasi. (Lihat teriakan untuk Nick Craver di bagian akhir.)
Jadi bisa dibilang "setidaknya X masukan yang cocok dengan pemilih Y harus diisi."
Hasil akhirnya, dengan markup seperti ini:
<input class="productinfo" name="partnumber">
<input class="productinfo" name="description">
... adalah sekelompok aturan seperti ini:
// Both these inputs input will validate if
// at least 1 input with class 'productinfo' is filled
partnumber: {
require_from_group: [1,".productinfo"]
}
description: {
require_from_group: [1,".productinfo"]
}
Item # 3 mengasumsikan bahwa Anda menambahkan kelas .checked
ke pesan kesalahan Anda setelah validasi berhasil. Anda dapat melakukan ini sebagai berikut, seperti yang ditunjukkan di sini .
success: function(label) {
label.html(" ").addClass("checked");
}
Seperti pada demo yang ditautkan di atas, saya menggunakan CSS untuk memberikan setiap span.error
gambar X sebagai latar belakangnya, kecuali jika ia memiliki kelasnya.checked
, dalam hal ini gambar itu mendapat gambar tanda centang.
Inilah kode saya sejauh ini:
jQuery.validator.addMethod("require_from_group", function(value, element, options) {
var numberRequired = options[0];
var selector = options[1];
//Look for our selector within the parent form
var validOrNot = $(selector, element.form).filter(function() {
// Each field is kept if it has a value
return $(this).val();
// Set to true if there are enough, else to false
}).length >= numberRequired;
// The elegent part - this element needs to check the others that match the
// selector, but we don't want to set off a feedback loop where each element
// has to check each other element. It would be like:
// Element 1: "I might be valid if you're valid. Are you?"
// Element 2: "Let's see. I might be valid if YOU'RE valid. Are you?"
// Element 1: "Let's see. I might be valid if YOU'RE valid. Are you?"
// ...etc, until we get a "too much recursion" error.
//
// So instead we
// 1) Flag all matching elements as 'currently being validated'
// using jQuery's .data()
// 2) Re-run validation on each of them. Since the others are now
// flagged as being in the process, they will skip this section,
// and therefore won't turn around and validate everything else
// 3) Once that's done, we remove the 'currently being validated' flag
// from all the elements
if(!$(element).data('being_validated')) {
var fields = $(selector, element.form);
fields.data('being_validated', true);
// .valid() means "validate using all applicable rules" (which
// includes this one)
fields.valid();
fields.data('being_validated', false);
}
return validOrNot;
// {0} below is the 0th item in the options field
}, jQuery.format("Please fill out at least {0} of these fields."));
Hore!
Teriak
Sekarang untuk teriakan itu - awalnya, kode saya hanya secara membabi buta menyembunyikan pesan kesalahan di bidang lain yang cocok alih-alih memvalidasinya ulang, yang berarti bahwa jika ada masalah lain (seperti 'hanya angka yang diizinkan dan Anda memasukkan huruf') , itu disembunyikan sampai pengguna mencoba mengirim. Ini karena saya tidak tahu bagaimana menghindari loop umpan balik yang disebutkan dalam komentar di atas. Saya tahu pasti ada jalan, jadi saya mengajukan pertanyaan , dan Nick Craver mencerahkan saya. Terima kasih, Nick!
Pertanyaan Terselesaikan
Ini awalnya adalah pertanyaan semacam "biarkan saya berbagi ini dan melihat apakah ada yang bisa menyarankan perbaikan". Meskipun saya masih menerima umpan balik, saya pikir itu cukup lengkap untuk saat ini. (Bisa lebih pendek, tapi saya ingin mudah dibaca dan belum tentu ringkas.) Jadi nikmatilah!
Perbarui - sekarang menjadi bagian dari jQuery Validation
Ini secara resmi ditambahkan ke jQuery Validation pada 4/3/2012.
sumber
Jawaban:
Itu solusi yang sangat baik, Nathan. Terima kasih banyak.
Berikut cara membuat kode di atas berfungsi, jika seseorang mengalami masalah dalam mengintegrasikannya, seperti yang saya lakukan:
Kode di dalam file tambahan-metode.js :
Kode di dalam file html :
Jangan lupa untuk menyertakan file tambahan-metode.js!
sumber
require_from_group: [1,".partnumber"]
dan...[1,".contactname"]
untuk memastikan Anda memvalidasi hal yang benar.Solusi bagus. Namun, saya memiliki masalah aturan lain yang diperlukan tidak berfungsi. Menjalankan .valid () terhadap formulir memperbaiki masalah ini untuk saya.
sumber
validator.formSubmit = true
. Dalam metode require-from-group saya kemudian memeriksa flag tersebut; jika itu ada saya lakukan$(element.form).valid();
, kalau tidak saya lakukanfields.valid();
.Terima kasih sean. Itu memperbaiki masalah yang saya alami dengan kode yang mengabaikan aturan lain.
Saya juga membuat beberapa perubahan sehingga pesan 'Harap isi setidaknya 1 bidang ..' muncul di div terpisah, bukan setelah semua bidang.
masukkan ke dalam bentuk skrip validasi
tambahkan ini di suatu tempat di halaman
tambahkan ke fungsi addMethod metode require_from_group
sumber
Saya telah mengirimkan tambalan yang tidak mengalami masalah yang terjadi pada versi saat ini (di mana opsi "diperlukan" berhenti berfungsi dengan baik di bidang lain, diskusi tentang masalah dengan versi saat ini ada di github .
Contoh di http://jsfiddle.net/f887W/10/
sumber
Memulai nama variabel dengan $ diperlukan dalam PHP, tetapi cukup aneh (IMHO) dalam Javascript. Juga, saya yakin Anda menyebutnya sebagai "$ module" dua kali dan "module" sekali, bukan? Tampaknya kode ini seharusnya tidak berfungsi.
Juga, saya tidak yakin apakah itu sintaks plugin jQuery normal, tetapi saya mungkin menambahkan komentar di atas panggilan addMethod Anda, menjelaskan apa yang Anda capai. Bahkan dengan deskripsi teks Anda di atas, sulit untuk mengikuti kode, karena saya tidak paham dengan apa yang dimaksud fieldset,: terisi, nilai, elemen, atau selektor. Mungkin sebagian besar dari ini jelas bagi seseorang yang akrab dengan plugin Validasi, jadi gunakan penilaian tentang berapa jumlah penjelasan yang tepat.
Mungkin Anda bisa membuat beberapa vars untuk mendokumentasikan sendiri kode tersebut; Suka,
(dengan asumsi saya benar-benar mengerti arti dari potongan kode Anda ini! :))
Saya tidak begitu yakin apa artinya "modul", sebenarnya - apakah ada nama yang lebih spesifik yang dapat Anda berikan untuk variabel ini?
Kode yang bagus, secara keseluruhan!
sumber
Karena formulir yang saya kerjakan memiliki beberapa daerah kloning dengan masukan yang dikelompokkan seperti ini, saya memberikan argumen tambahan ke konstruktor require_from_group, mengubah tepat satu baris fungsi addMethod Anda:
dan dengan cara ini pemilih, ID, atau nama elemen dapat diberikan satu kali:
dan validator akan membatasi validasi ke elemen dengan kelas itu hanya di dalam setiap fieldset, daripada mencoba menghitung semua elemen yang digolongkan .reqgrp di formulir.
sumber
Inilah retakan saya pada jawaban Rocket Hazmat, mencoba menyelesaikan masalah bidang lain yang ditentukan juga perlu divalidasi, tetapi menandai semua bidang sebagai valid pada pengisian yang berhasil.
Satu-satunya masalah yang tersisa dengan ini sekarang adalah kasus tepi di mana bidang tersebut kosong, lalu diisi, lalu kosongkan lagi ... dalam hal ini kesalahan akan diterapkan ke bidang tunggal bukan grup. Tetapi tampaknya sangat tidak mungkin terjadi dengan frekuensi apa pun dan secara teknis masih berfungsi dalam kasus itu.
sumber
Saya mengalami masalah dengan aturan lain yang tidak diperiksa sehubungan dengan ini, jadi saya mengubah:
Untuk ini:
Saya juga membuat beberapa peningkatan (pribadi), dan ini adalah versi yang saya gunakan:
sumber
Terima kasih, Nathan. Anda menghemat banyak waktu.
Namun, saya harus memperhatikan bahwa aturan ini belum siap jQuery.noConflict (). Jadi, seseorang harus mengganti semua $ dengan jQuery untuk bekerja, katakanlah,
var $j = jQuery.noConflict()
Dan saya punya pertanyaan: bagaimana saya membuatnya berperilaku seperti aturan bawaan? Misalnya, jika saya memasukkan email, pesan "Harap masukkan email yang valid" menghilang secara otomatis tetapi jika saya mengisi salah satu kolom grup pesan kesalahan tetap ada.
sumber