Sto usando l'eccellente plugin jQuery Validate per convalidare alcuni moduli. In un modulo, devo assicurarmi che l'utente compili almeno uno di un gruppo di campi. Penso di avere una buona soluzione e volevo condividerla. Si prega di suggerire eventuali miglioramenti che si possono pensare.
Non trovando un modo integrato per farlo, ho cercato e trovato il metodo di convalida personalizzato di Rebecca Murphey , che è stato molto utile.
L'ho migliorato in tre modi:
- Per farti passare un selettore per il gruppo di campi
- Per consentirti di specificare quanti componenti di quel gruppo devono essere riempiti affinché la convalida passi
- Per mostrare tutti gli input nel gruppo come convalida in corso non appena uno di essi supera la convalida. (Vedi il grido a Nick Craver alla fine.)
Quindi puoi dire "almeno X input che corrispondono al selettore Y devono essere riempiti".
Il risultato finale, con un markup come questo:
<input class="productinfo" name="partnumber">
<input class="productinfo" name="description">
... è un gruppo di regole come questo:
// 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"]
}
L'articolo 3 presuppone che tu stia aggiungendo una classe di .checked
ai tuoi messaggi di errore dopo la convalida riuscita. Puoi farlo come segue, come dimostrato qui .
success: function(label) {
label.html(" ").addClass("checked");
}
Come nella demo collegata sopra, uso i CSS per dare a ciascuno span.error
un'immagine X come sfondo, a meno che non abbia la classe .checked
, nel qual caso ottiene un'immagine del segno di spunta.
Ecco il mio codice finora:
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."));
Evviva!
Gridare
Ora per quel grido - in origine, il mio codice nascondeva ciecamente i messaggi di errore sugli altri campi corrispondenti invece di convalidarli nuovamente, il che significava che se c'era un altro problema (come "sono consentiti solo i numeri e hai inserito lettere") , è stato nascosto fino a quando l'utente non ha provato a inviare. Questo perché non sapevo come evitare il ciclo di feedback menzionato nei commenti sopra. Sapevo che doveva esserci un modo, quindi ho posto una domanda e Nick Craver mi ha illuminato. Grazie Nick!
Domanda risolta
Questa era originariamente una domanda tipo "fammi condividere questo e vedi se qualcuno può suggerire miglioramenti". Anche se accetterei comunque il feedback, penso che sia abbastanza completo a questo punto. (Potrebbe essere più breve, ma voglio che sia facile da leggere e non necessariamente conciso.) Quindi divertiti!
Aggiornamento: ora fa parte di jQuery Validation
Questo è stato ufficialmente aggiunto a jQuery Validation il 4/3/2012.