Ich verwende das ausgezeichnete jQuery Validate Plugin , um einige Formulare zu validieren. In einem Formular muss ich sicherstellen, dass der Benutzer mindestens eines aus einer Gruppe von Feldern ausfüllt. Ich denke, ich habe eine ziemlich gute Lösung und wollte sie teilen. Bitte schlagen Sie Verbesserungen vor, die Sie sich vorstellen können.
Als ich keine eingebaute Möglichkeit fand, dies zu tun, suchte und fand ich Rebecca Murpheys benutzerdefinierte Validierungsmethode , die sehr hilfreich war.
Ich habe dies auf drei Arten verbessert:
- Damit Sie einen Selektor für die Feldgruppe übergeben können
- Damit können Sie angeben, wie viele dieser Gruppen gefüllt werden müssen, damit die Validierung erfolgreich ist
- Anzeigen aller Eingaben in der Gruppe als bestandene Validierung, sobald eine von ihnen die Validierung besteht. (Siehe Gruß an Nick Craver am Ende.)
Sie können also sagen, dass mindestens X Eingänge, die mit dem Selektor Y übereinstimmen, gefüllt sein müssen.
Das Endergebnis mit einem solchen Markup:
<input class="productinfo" name="partnumber">
<input class="productinfo" name="description">
... ist eine Gruppe von Regeln wie diese:
// 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"]
}
Bei Punkt 3 wird davon ausgegangen, dass Sie .checked
Ihren Fehlermeldungen nach erfolgreicher Validierung eine Klasse von hinzufügen . Sie können dies wie folgt tun, wie hier gezeigt .
success: function(label) {
label.html(" ").addClass("checked");
}
Wie in der oben verlinkten Demo verwende ich CSS, um jedem span.error
ein X-Bild als Hintergrund zu geben, es sei denn, es hat die Klasse .checked
. In diesem Fall erhält es ein Häkchenbild.
Hier ist mein Code bisher:
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."));
Hurra!
Ruf raus
Nun zu diesem Shout-Out - ursprünglich hat mein Code die Fehlermeldungen in den anderen übereinstimmenden Feldern nur blind ausgeblendet, anstatt sie erneut zu validieren. Dies bedeutete, dass bei einem anderen Problem (wie "Nur Zahlen sind zulässig und Sie haben Buchstaben eingegeben") wurde es ausgeblendet, bis der Benutzer versuchte, es einzureichen. Dies lag daran, dass ich nicht wusste, wie ich die in den obigen Kommentaren erwähnte Rückkopplungsschleife vermeiden sollte. Ich wusste, dass es einen Weg geben musste, also stellte ich eine Frage und Nick Craver erleuchtete mich. Danke, Nick!
Frage gelöst
Dies war ursprünglich eine Art Frage "Lassen Sie mich dies teilen und sehen, ob jemand Verbesserungen vorschlagen kann". Obwohl ich Feedback immer noch begrüßen würde, denke ich, dass es zu diesem Zeitpunkt ziemlich vollständig ist. (Es könnte kürzer sein, aber ich möchte, dass es leicht zu lesen und nicht unbedingt prägnant ist.) Also einfach genießen!
Update - jetzt Teil der jQuery-Validierung
Dies wurde am 03.04.2012 offiziell zur jQuery-Validierung hinzugefügt.