jqueryvalidate-";跳过这些字段,或至少填写其中的X个“;

jqueryvalidate-";跳过这些字段,或至少填写其中的X个“;,jquery,validation,Jquery,Validation,我在我的表格上使用。我有一些字段组是可选的,但必须是“全部或无”-如果在一个组中填写一个输入,则必须填写所有输入 例如,假设用户可以输入一个位置(街道、城市、州和邮政编码)或多个位置。你不必输入第二个位置,但如果输入了,只输入城市是不行的;我也需要州政府和拉链 为了解决这个问题,我编写了一个自定义规则——实际上只是对组中的,require\u的一个小小调整。这一个被称为“跳过”或“填充”最小值。以下是您如何使用它: var validationrules = { rules: { l

我在我的表格上使用。我有一些字段组是可选的,但必须是“全部或无”-如果在一个组中填写一个输入,则必须填写所有输入

例如,假设用户可以输入一个位置(街道、城市、州和邮政编码)或多个位置。你不必输入第二个位置,但如果输入了,只输入城市是不行的;我也需要州政府和拉链

为了解决这个问题,我编写了一个自定义规则——实际上只是对组中的,
require\u
的一个小小调整。这一个被称为“跳过”或“填充”最小值。以下是您如何使用它:

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."));
我主要是发布这篇文章,以便其他在网上搜索解决方案的人能够找到它。仍然-有人找到改进的方法吗?

更新-现在是jQuery验证的一部分 这是在2012年4月3日。

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

仍然存在与规则相同的错误--我的意思是,删除
error
类和与选择器匹配的所有元素上的错误标签并不是真正正确的。假设需要设置4个字段,但有5个字段。用户填写4个字段。第五个字段未填写,但在该字段中,您另外设置了
必填项
电子邮件
。这样,电子邮件的错误消息也会被删除,尽管他还没有解决它

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

我花了很长时间才找到上面提到的解决方案,解决了组上面的字段无法得到验证的问题

如果将.valid()

但此修复程序会阻止在关键点或模糊事件中显示或删除所有组标签。我发现这对解决这个问题很有帮助


注意:stackoverflow在过去帮助我找到了很多答案,但这是我第一次真正的贡献。感谢所有人汇集此解决方案

这是我第一次发布SO,所以我希望我做的是正确的,但是在接受的解决方案中似乎有一个错误。我已经为
location2address
块(或者
rules
块,取决于您如何看待它)添加了结束括号


我需要一些稍微不同的东西。这是一个包含姓名或姓氏和/或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."));

好建议。在某种程度上,为了成为一个清晰的示例,我的代码故意冗长,但我可以从您的代码中学到一些东西。非常感谢。另外,关于删除错误的错误行为,您是对的。有什么解决方法吗?2010年4月9日更新,优雅的部分可以重新检查其他组成员,而不会造成无限循环。这一逻辑是由Nick Craver提供的——请参见我的相关规则问题:更新于2010年8月22日——将fields.data上的.valid()改为.validate();valid()导致整个表单通过验证,而只有这些字段返回true。
    $('#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."));