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.
quelle
Antworten:
Das ist eine hervorragende Lösung, Nathan. Vielen Dank.
Hier ist eine Möglichkeit, wie der obige Code funktioniert, falls jemand Probleme bei der Integration hat, wie ich es getan habe:
Code in der Datei Additional-Methods.js :
Code in der HTML- Datei:
Vergessen Sie nicht, die Datei Additional-Methods.js einzuschließen!
quelle
require_from_group: [1,".partnumber"]
und...[1,".contactname"]
sicherzustellen, dass Sie die richtigen Dinge validieren.Schöne Lösung. Ich hatte jedoch das Problem, dass andere erforderliche Regeln nicht funktionierten. Das Ausführen von .valid () für das Formular hat dieses Problem für mich behoben.
quelle
validator.formSubmit = true
. In der Require-from-Group-Methode überprüfe ich dann, ob dieses Flag vorhanden ist. Wenn es da ist, mache ich es$(element.form).valid();
, sonst mache ich esfields.valid();
.Danke Sean. Dadurch wurde das Problem behoben, bei dem der Code andere Regeln ignorierte.
Ich habe auch einige Änderungen vorgenommen, damit die Meldung "Bitte mindestens 1 Feld ausfüllen .." in einem separaten Div angezeigt wird, anstatt in jedem Feld.
in Form validieren Skript setzen
füge dies irgendwo auf der Seite hinzu
Fügen Sie der Methode require_from_group die Funktion addMethod hinzu
quelle
Ich habe einen Patch eingereicht , der nicht unter den Problemen der aktuellen Version leidet (wobei die Option "Erforderlich" in anderen Bereichen nicht mehr ordnungsgemäß funktioniert). Eine Diskussion der Probleme mit der aktuellen Version findet auf Github statt .
Beispiel unter http://jsfiddle.net/f887W/10/
quelle
Das Starten eines Variablennamens mit $ ist in PHP erforderlich, in Javascript jedoch ziemlich seltsam (IMHO). Ich glaube auch, dass Sie es zweimal als "$ module" und einmal als "module" bezeichnen, oder? Es scheint, dass dieser Code nicht funktionieren sollte.
Ich bin mir auch nicht sicher, ob es sich um die normale Syntax des jQuery-Plugins handelt, aber ich kann über Ihrem addMethod-Aufruf Kommentare hinzufügen, um zu erklären, was Sie erreichen. Selbst mit Ihrer obigen Textbeschreibung ist es schwierig, dem Code zu folgen, da ich nicht weiß, auf welche Feldmenge: gefüllt, Wert, Element oder Selektor sich beziehen. Vielleicht ist das meiste davon für jemanden offensichtlich, der mit dem Validate-Plugin vertraut ist. Beurteilen Sie also, was die richtige Menge an Erklärungen ist.
Vielleicht könnten Sie ein paar Variablen ausbrechen, um den Code selbst zu dokumentieren. mögen,
(Vorausgesetzt, ich habe die Bedeutung dieser Teile Ihres Codes verstanden! :))
Ich bin mir nicht ganz sicher, was "Modul" eigentlich bedeutet - gibt es einen genaueren Namen, den Sie dieser Variablen geben könnten?
Insgesamt ein schöner Code!
quelle
Da das Formular, an dem ich arbeite, mehrere geklonte Regionen mit gruppierten Eingaben wie diesen enthält, habe ich ein zusätzliches Argument an den Konstruktor require_from_group übergeben und genau eine Zeile Ihrer Funktion addMethod geändert:
Auf diese Weise kann ein Selektor, eine ID oder ein Elementname einmal übergeben werden:
und der Validator beschränkt die Validierung auf Elemente mit dieser Klasse nur innerhalb jeder Feldmenge, anstatt zu versuchen, alle klassifizierten .reqgrp-Elemente im Formular zu zählen.
quelle
Hier ist mein Riss bei der Antwort von Rocket Hazmat: Ich versuche, das Problem anderer definierter Felder zu lösen, die ebenfalls validiert werden müssen, markiere aber alle Felder als gültig, wenn eines erfolgreich ausgefüllt wurde.
Das einzige verbleibende Problem dabei ist jetzt der Randfall, in dem das Feld leer, dann gefüllt und dann wieder leer ist. In diesem Fall wird der Fehler auf das einzelne Feld und nicht auf die Gruppe angewendet. Aber das scheint so unwahrscheinlich, dass es mit irgendeiner Frequenz passiert, und es funktioniert in diesem Fall technisch immer noch.
quelle
Ich hatte Probleme mit anderen Regeln, die im Zusammenhang damit nicht überprüft wurden. Deshalb habe ich Folgendes geändert:
Dazu:
Ich habe auch einige (persönliche) Verbesserungen vorgenommen, und dies ist die Version, die ich verwende:
quelle
Danke, Nathan. Du hast mir eine Menge Zeit gespart.
Ich muss jedoch beachten, dass diese Regel nicht bereit für jQuery.noConflict () ist. Man muss also alle $ durch jQuery ersetzen, um beispielsweise damit arbeiten zu können.
var $j = jQuery.noConflict()
Und ich habe die Frage: Wie würde ich dafür sorgen, dass es sich wie eine eingebaute Regel verhält? Wenn ich beispielsweise eine E-Mail eingebe, verschwindet die Meldung "Bitte geben Sie eine gültige E-Mail-Adresse ein" automatisch, aber wenn ich eines der Gruppenfelder ausfülle, bleibt die Fehlermeldung bestehen.
quelle