いくつかのフォームを検証するために、優れたjQuery Validateプラグインを使用しています。1つのフォームで、ユーザーがフィールドのグループの少なくとも1つに入力することを確認する必要があります。私はかなり良い解決策を持っていると思い、それを共有したいと思いました。 考えられる改善点があれば提案してください。
これを行うための組み込みの方法が見つからなかったので、レベッカマーフィーのカスタム検証メソッドを検索して見つけました。これは非常に役に立ちました。
私はこれを3つの方法で改善しました:
- フィールドのグループのセレクターを渡すには
- 検証に合格するために入力する必要があるグループの数を指定するには
- それらの1つが検証に合格するとすぐに、グループ内のすべての入力を検証に合格すると表示する。(最後にNick Craverへの叫びを参照してください。)
したがって、「セレクターYに一致するX入力が少なくとも入力されている必要があります」と言うことができます。
最終結果は、次のようなマークアップです。
<input class="productinfo" name="partnumber">
<input class="productinfo" name="description">
...このようなルールのグループです:
// 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"]
}
項目#3は、.checked
検証が成功したときにエラーメッセージにのクラスを追加することを前提としています。ここで示すように、これは次のように行うことができます。
success: function(label) {
label.html(" ").addClass("checked");
}
上記のデモのように、CSSを使用してそれぞれspan.error
にX画像を背景として指定します。ただし、クラスがなければ.checked
、チェックマーク画像を取得します。
これまでの私のコードは次のとおりです。
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."));
やったー!
大声で叫ぶ
今、その叫び声のために-元々、私のコードは、他の一致するフィールドのエラーメッセージを再検証するのではなく、盲目的に隠しました。 、ユーザーが送信しようとするまで非表示になります。これは、上記のコメントに記載されているフィードバックループを回避する方法がわからなかったためです。私は方法があるはずだと知っていたので、私は質問をしました、そしてニック・クレイバーは私に啓発しました。ありがとう、ニック!
解決した質問
これはもともと「これを共有して、誰かが改善を提案できるかどうかを確認してください」という種類の質問でした。私はまだフィードバックを歓迎しますが、現時点ではかなり完成していると思います。(短くすることもできますが、読みやすく、必ずしも簡潔ではないようにしたいと思います。)だから楽しんでください!
更新-jQuery検証の一部になりました
これは、2012年4月3日にjQuery Validationに正式に追加されました。