jQuery 验证:对多个单选按钮有效的规则仅对第一个单选按钮触发

jQuery Validate: Rule active for multiple radiobuttons only fires for the first one

您可以运行底部的代码片段:附件正确发生了N次,但实际方法只执行了一次。此问题发生在动态生成的表单中。

我在 jQuery 验证器中有以下自定义规则,适用于我表单上的所有单选按钮。

    // Destroy and re-initialize Form Validator (dynamically repopulated form)
    var validator = $('#activityQuestionsForm').validate();
    validator.destroy();
    $(form).validate({ .. }); // with configuration

    // Define custom validation method
    $.validator.addMethod('childAnswersVisible', function(value, element) {
         // .. Custom function goes here.. returns true/false
    });

    ...

    // Attach custom validation method to all radiobuttons
    if ($(element).is("#activityQuestionsForm input[type=radio]")) {
        $(element).rules("add", {childAnswersVisible : true});
    }

我有 3 个单选按钮。创建表单后,我看到 rules("add") 附件正确执行了 3 次。所以所有 3 个单选按钮现在都附加了自定义验证。

我在 addMethod 中的自定义验证定义中也有一个断点(见上文,我有 .. Custom function goes here.. returns true/false),在提交表单时,我看到那个块 只执行一次——对于第一个单选按钮。有谁知道为什么?提交表单时,我希望断点被击中 3 次,每个单选按钮一次,以便为每个单选按钮做出决定。

// Construct a dynamic form with 3 radiobuttons
var html = '<form id="activityQuestionsForm">' + 
           '   <input type="radio" name="choices" id="62"> 62 <br> ' +
           '   <input type="radio" name="choices" id="63"> 63 <br> ' +
           '   <input type="radio" name="choices" id="64"> 64 <br> ' +
           '<input type="submit">' + 
           '</form>';
           
$(html).appendTo('body');

$.validator.addMethod('childAnswersVisible', function(value, element) {
   alert('Running custom method');
   return true;
});

$('#activityQuestionsForm').validate();

$("#activityQuestionsForm input[type=radio]").each(function(index) {
   $(this).rules("add", {childAnswersVisible : true});
   alert('Attached custom method for: ' + $(this).attr('id'));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.15.0/jquery.validate.min.js"></script>

编辑:

所有三个单选按钮都具有相同的 name 属性....

var html = '<form id="activityQuestionsForm">' + 
       '   <input type="radio" name="choices" id="62"> 62 <br> ' +
       '   <input type="radio" name="choices" id="63"> 63 <br> ' +
       '   <input type="radio" name="choices" id="64"> 64 <br> ' +
       '<input type="submit">' + 
       '</form>';

因此,this plugin considers this group of radios as a single input for this form。因此,将规则应用于三个按钮中的每一个是多余的;验证规则和消息是同时针对所有三个按钮的,而不是单独的。实际验证将产生一条用于按钮分组的消息。

If you need each button to have it's own validation, then each one needs a unique name

var html = '<form id="activityQuestionsForm">' + 
       '   <input type="radio" name="choices1" id="62"> 62 <br> ' +
       '   <input type="radio" name="choices2" id="63"> 63 <br> ' +
       '   <input type="radio" name="choices3" id="64"> 64 <br> ' +
       '<input type="submit">' + 
       '</form>';

参见:jsfiddle.net/fo1jbu0v/

Documentation:

Mandated: A name attribute is required for all input elements needing validation, and the plugin will not work without this. A name attribute must also be unique to the form, as this is how the plugin keeps track of all input elements. However, each group of radio or checkbox elements will share the same name since the value of this grouping represents a single piece of the form data.


编辑前OP的原代码:

// Attach custom validation method to all radiobuttons
if ($(element).is("#activityQuestionsForm input[type=radio]")) {
    $(element).rules("add", {childAnswersVisible : true});
}

没有理由将 .rules() 放在条件中,因为您可以直接将其附加到 jQuery 选择器。

$("#activityQuestionsForm input[type=radio]").rules("add", {childAnswersVisible : true});

无论如何,你的整个问题是因为这个插件的方法只在选择多个元素时附加到 first 元素。

正确的解决方案是将其包裹在 .each() 中,以便将此规则附加到所有匹配的元素。

$("#activityQuestionsForm input[type=radio]").each(function() {
    $(this).rules("add", {childAnswersVisible : true});
});

参考1: jqueryvalidation.org/reference/#link-validating-multiple-forms-on-one-page

1 - 尽管文档专门针对 .validate() 方法,但此概念适用于此插件提供的所有方法,包括 .rules()