jQuery Validate - 要求填充组中的至少一个字段

Nat*_*ong 98 validation jquery jquery-plugins jquery-validate

我正在使用优秀的jQuery Validate插件来验证某些表单.在一种形式上,我需要确保用户填写一组字段中的至少一个.我想我有一个很好的解决方案,想分享它. 请提出您可以想到的任何改进建议.

找不到这样做的内置方法,我搜索并找到了Rebecca Murphey的自定义验证方法,这非常有用.

我通过三种方式改进了这个:

  1. 让您传入一组字段的选择器
  2. 允许您指定必须填充该组的数量才能通过验证
  3. 一旦其中一个输入通过验证,就将组中的所有输入显示为通过验证.(见呼喊出到尼克Craver在结束).

所以你可以说"至少必须填充匹配选择器Y的X输入."

最终结果,标记如下:

<input class="productinfo" name="partnumber">
<input class="productinfo" name="description">
Run Code Online (Sandbox Code Playgroud)

......是一组这样的规则:

// 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"]
}
Run Code Online (Sandbox Code Playgroud)

项目#3假定您.checked在成功验证后添加了一类错误消息.你可以这样做如下,这里展示.

success: function(label) {  
        label.html(" ").addClass("checked"); 
}
Run Code Online (Sandbox Code Playgroud)

正如在上面链接的演示中,我使用CSS给每个span.errorX图像作为其背景,除非它有类.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."));
Run Code Online (Sandbox Code Playgroud)

万岁!

喊出来

现在为了那个喊叫 - 最初,我的代码只是盲目地隐藏其他匹配字段上的错误消息而不是重新验证它们,这意味着如果还有另一个问题(比如'只允许数字而你输入字母') ,它一直隐藏,直到用户试图提交.这是因为我不知道如何避免上述评论中提到的反馈循环.我知道必须有办法,所以我问了一个问题,尼克克拉弗开悟了我.谢谢,尼克!

问题解决了

这本来是"让我分享一下,看看是否有人可以提出改进"的问题.虽然我仍然欢迎反馈,但我认为这一点非常完整.(它可能更短,但我希望它易于阅读,而不一定简洁.)所以只是享受!

更新 - 现在是jQuery验证的一部分

这已于2012年4月3 日正式添加到jQuery验证中.

小智 21

这是一个出色的解决方案内森.非常感谢.

这是使上述代码工作的一种方法,以防有人遇到麻烦整合它,就像我做的那样:

additional-methods.js文件中的代码:

jQuery.validator.addMethod("require_from_group", function(value, element, options) {
...// Nathan's code without any changes
}, jQuery.format("Please fill out at least {0} of these fields."));

// "filone" is the class we will use for the input elements at this example
jQuery.validator.addClassRules("fillone", {
    require_from_group: [1,".fillone"]
});
Run Code Online (Sandbox Code Playgroud)

html文件中的代码:

<input id="field1" class="fillone" type="text" value="" name="field1" />
<input id="field2" class="fillone" type="text" value="" name="field2" />
<input id="field3" class="fillone" type="text" value="" name="field3" />
<input id="field4" class="fillone" type="text" value="" name="field4" />
Run Code Online (Sandbox Code Playgroud)

别忘了包含additional-methods.js文件!


sea*_*ean 6

好的解决方案 但是,我遇到了其他必要规则不起作用的问题.针对表单执行.valid()为我解决了这个问题.

if(!$(element).data('being_validated')) {
  var fields = $(selector, element.form);
  fields.data('being_validated', true); 
  $(element.form).valid();
  fields.data('being_validated', false);
}
Run Code Online (Sandbox Code Playgroud)


Mic*_*ach 3

PHP 中需要以 $ 开头的变量名,但在 Javascript 中却很奇怪(恕我直言)。另外,我相信您将其称为“$module”两次,一次“module”,对吗?看来这段代码不应该工作。

另外,我不确定这是否是正常的 jQuery 插件语法,但我可能会在 addMethod 调用上方添加注释,解释您完成的任务。即使有上面​​的文字描述,也很难遵循代码,因为我不熟悉 fieldset、:filled、value、element 或 selector 所指的内容。也许其中大部分内容对于熟悉验证插件的人来说是显而易见的,因此请判断什么是正确的解释量。

也许你可以分解一些变量来自我记录代码;喜欢,

var atLeastOneFilled = module.find(...).length > 0;
if (atLeastOneFilled) {
  var stillMarkedWithErrors = module.find(...).next(...).not(...);
  stillMarkedWithErrors.text("").addClass(...)
Run Code Online (Sandbox Code Playgroud)

(假设我确实理解这些代码块的含义!:))

实际上,我不太确定“模块”的含义 - 您可以为该变量指定更具体的名称吗?

总体而言,不错的代码!