jQuery Validate – “跳过这些字段,或至少填写其中的X”

我正在我的表单上使用jQuery Validation插件 。 我有一些可选的字段组,但需要“全部或全部” – 如果您在组中填写一个输入,则必须填写所有字段。

例如,假设用户可以输入一个位置 – 街道,城市,州和拉链 – 或多个位置。 您不必进入第二个位置,但如果您这样做,那么仅仅给这个城市是不行的; 我也需要那个状态和拉链。

为了解决这个问题,我编写了一个自定义规则 – 实际上只是我之前规则的一个微小调整, 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.")); 

我主要发布这个post,以便搜索网络搜索解决方案的其他人可以找到它。 仍然 – 有没有人看到改善这种情况的方法?

更新 – 现在是jQueryvalidation的一部分

这已于2012年4月3日正式添加到jQueryvalidation中。

我的缩短和“优化”版本(更多链接+使用validation器自定义提供的选择器)。 并希望减少选择操作。

仍然遭受你的规则所做的相同的错误 – 我的意思是删除error类和所有符合我们的选择器的元素上的错误标签是不正确的。 想象一下,您需要设置4个字段,但有5个字段。用户填写4个字段。 第五个他没有填充,但在那个领域,你另外设置requiredemail 。 这样,电子邮件的错误消息也会被删除,尽管他还没有解决它。

 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.")); 

我花了很长时间才找到上面提到的修复问题,其中组上方的字段无法validation。

如果将.valid()更改为.validate()被添加到密切相关的问题中会很好 – 这里和这里有许多人都在询问它。

此修复程序会阻止在键或模糊事件上显示或删除所有组标签。 我发现jitter的if if else语句对解决这个问题非常有帮助。

注意: stackoverflow帮助我找到了许多答案,但这是我的第一个实际贡献。 感谢大家将这个解决方案整合在一起

这是我发给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); 

我需要稍微不同的东西。 它是一个搜索表单,其中包含任意一个或两个名字和/或其他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."));