我在表单上使用jQuery Validation plugin。我有一些可选的字段组,但需要“全部或全部” - 如果您在组中填充一个输入,则必须填写所有字段。
例如,假设用户可以输入一个位置 - 街道,城市,州和邮政编码 - 或多个位置。你不必进入第二个位置,但是如果你这样做,就不能给这个城市;我也需要那个状态和拉链。
为了解决这个问题,我写了一个自定义规则 - 实际上只是my previous rule,require_from_group
的微调。这个名为skip_or_fill_minimum
。以下是您使用它的方式:
var validationrules = {
rules: {
location2address: {
skip_or_fill_minimum: [4,'.location2']
}
//This input will validate if all 4 `.location2` inputs are filled,
//or if all of them are left blank
}
var validator = $("#formtovalidate").validate(validationrules);
以下是自定义规则的代码:
jQuery.validator.addMethod("skip_or_fill_minimum", function(value, element, options) {
var numberRequired = options[0];
var selector = options[1];
//Look for our selector within the parent form
var numberFilled = $(selector, element.form).filter(function() {
// Each field is kept if it has a value
return $(this).val();
}).length;
var valid = numberFilled >= numberRequired || numberFilled === 0;
//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 all the
//elements check all the others which check all the others which
//check all the others...
//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);
//.valid() means "validate using all applicable rules" (which includes this one)
fields.data('being_validated', true);
fields.validate(); //Changed from fields.valid();
fields.data('being_validated', false);
}
return valid;
// {0} below is the 0th item in the options field
}, jQuery.format("Please either skip these fields or fill at least {0} of them."));
我主要发布此内容,以便搜索网络搜索解决方案的其他人可以找到它。仍然 - 有没有人看到改善这种情况的方法?
2012年4月3日这是officially added to jQuery Validation。
答案 0 :(得分:4)
我的缩短版和“优化版”(更多链接+使用验证器自定义提供的选择器)。并希望减少选择操作。
你的规则仍然会遇到同样的错误 - 我的意思是删除error
类以及与我们的选择器匹配的所有元素上的错误标签并不正确。想象一下,您需要设置4个字段,但有5个字段。用户填写4个字段。第五个他没有填充,但在那个领域,你另外设置了required
和email
。这样,电子邮件的错误消息也会被删除,尽管他还没有解决它。
jQuery.validator.addMethod("skip_or_fill_minimum", function(value, element, options) {
var elems = $(element).parents('form').find(options[1]);
var numberFilled = elems.filter(':filled').size();
if (numberFilled >= options[0] || numberFilled == 0) {
elems.removeClass('error');
elems.next('label.error').not('.checked').text('').addClass('checked');
return true;
} else {
elems.addClass('error');
}
}, jQuery.format("Please either skip these fields or fill at least {0} of them."));
答案 1 :(得分:1)
我花了很长时间才找到上面提到的针对该问题的修复,其中该组上方的字段无法验证。
如果将 .valid <)更改为 .validate()添加到密切相关的问题 - here和{{很多人都在问这个问题。
此修复程序会阻止在键或模糊事件上显示或删除所有组标签。我发现here非常有助于解决这个问题。
注意: stackoverflow帮助我找到了很多答案,但这是我的第一个实际贡献。感谢大家将这个解决方案整合在一起
答案 2 :(得分:1)
这是我发给SO的第一篇文章,所以我希望我能正确地做到这一点,但是在接受的解决方案中似乎存在错误。我已为location2address
块(或rules
块添加了右括号,具体取决于您的查看方式。)
var validationrules = {
rules: {
location2address: {
skip_or_fill_minimum: [4,'.location2']
}
}
//This input will validate if all 4 `.location2` inputs are filled,
//or if all of them are left blank
}
var validator = $("#groovetime_entry").validate(validationrules);
答案 3 :(得分:0)
我需要稍微不同的东西。它是一个搜索表单,其中包含名字或姓氏中的任何一个或两个和/或其他4个搜索条件。
我希望他们跳过或只输入一个(或x)。我修改了上面的代码:
jQuery.validator.addMethod("skip_or_fill_only_x", function (value, element, options) {
var numberRequired = options[0];
var selector = options[1];
var numberFilled = $(selector, element.form).filter(function () {
return $(this).val();
}).length;
//Changed this line from "numberFilled >=" to "numberFilled ==="
var valid = numberFilled === numberRequired || numberFilled === 0;
if (!$(element).data('being_validated')) {
var fields = $(selector, element.form);
fields.data('being_validated', true);
fields.validate();
fields.data('being_validated', false);
}
return valid;
//Adjusted message
}, jQuery.format("Please either skip these fields or only fill {0} of them."));
完整的实现如下所示:
$('#advancedSearchForm').validate({
errorLabelContainer: '#advancedErrors',
rules: {
FirstName: {
require_from_group: [1, '.mygroup']
},
LastName: {
require_from_group: [1, '.mygroup']
},
countryCodeAdvanced: {
skip_or_fill_only_x: [1, '.location2']
},
location: {
skip_or_fill_only_x: [1, '.location2']
},
PositionTitle: {
skip_or_fill_only_x: [1, '.location2']
},
FunctionalArea: {
skip_or_fill_only_x: [1, '.location2']
}
},
groups: {
mygroup: "FirstName LastName",
location2: "countryCodeAdvanced location PositionTitle FunctionalArea"
}
});
jQuery.validator.addMethod("skip_or_fill_only_x", function (value, element, options) {
var numberRequired = options[0];
var selector = options[1];
var numberFilled = $(selector, element.form).filter(function () {
return $(this).val();
}).length;
var valid = numberFilled === numberRequired || numberFilled === 0;
if (!$(element).data('being_validated')) {
var fields = $(selector, element.form);
fields.data('being_validated', true);
fields.validate();
fields.data('being_validated', false);
}
return valid;
}, jQuery.format("Please either skip these fields or only fill {0} of them."));