我正在使用出色的jQuery Validate插件来验证某些表单。在一个表单上,我需要确保用户填写一组字段中的至少一个。我认为我有一个很好的解决方案,并希望与大家分享。 请提出您可以想到的任何改进。
我没有找到任何内置方法来执行此操作,因此搜索并找到了Rebecca Murphey的自定义验证方法,该方法非常有帮助。
我通过三种方式对此进行了改进:
- 让您传递一组字段的选择器
- 为了让您指定该组中必须填充多少组才能通过验证
- 一旦其中一个输入通过验证,就将该组中的所有输入显示为通过验证。(请参阅对尼克·克雷弗大喊大叫。)
因此,您可以说“必须至少填充与选择器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图像提供背景,除非它具有class .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."));
万岁!
喊出来
现在,大声疾呼-最初,我的代码只是盲目地将错误消息隐藏在其他匹配字段上,而不是重新验证它们,这意味着如果还有另一个问题(例如“只允许输入数字并且您输入了字母”) ,直到用户尝试提交之前它一直被隐藏。这是因为我不知道如何避免上面评论中提到的反馈循环。我知道一定有办法,所以我问了一个问题,尼克·克拉弗(Nick Craver)启发了我。谢谢,尼克!
问题解决
这最初是“让我分享这一点,看看是否有人可以提出改进建议”这类问题。虽然我仍然欢迎反馈,但是我认为到此为止已经很完整了。(它可能会更短一些,但我希望它易于阅读,但不一定要简洁。)那就尽情享受吧!
更新-现在是jQuery验证的一部分
这已在2012年4月3 日正式添加到jQuery Validation中。