jQuery验证 - 根据其他字段更改“必需”属性

时间:2009-11-16 14:14:24

标签: javascript jquery validation

我在我正在构建的表单上使用jQuery Validation插件(http://docs.jquery.com/Plugins/Validation)。表单由6个字段集组成,每个字段集包含3个文本输入,用于电子邮件地址,名字和姓氏。标记的简化版本如下:

<form id="ref" action="submit.php" method="post">
    <fieldset id="ref_1">
        <input id="ref_1_email" type="text" />
        <input id="ref_1_fname" type="text" />
        <input id="ref_1_lname" type="text" />
    </fieldset>
    <fieldset id="ref_2">
        <input id="ref_2_email" type="text" />
        <input id="ref_2_fname" type="text" />
        <input id="ref_2_lname" type="text" />
    </fieldset>
    <fieldset id="ref_3">
        <input id="ref_3_email" type="text" />
        <input id="ref_3_fname" type="text" />
        <input id="ref_3_lname" type="text" />
    </fieldset>
</form>

依此类推,直至ref_6。但是,用户不一定需要完成每个字段 - 他们可能只选择填写字段集#ref_1和fieldset#ref_2中的输入,并将其他字段留空。但是,如果他们输入例如ref_1的电子邮件,则还需要ref_1的名字和姓氏。所以我需要做的是检查字段集中的所有3个输入。如果它们都是空白的,则可以忽略它们,但是如果填写了其中一个输入,则必须同时完成两个邻居。到目前为止,我所有的尝试都非常繁琐(观察每个人的变化,然后评估是否空洞......),任何帮助都会非常感激。

由于

更新

我发现了一个类似问题的帖子,建议的解决方案是:

$('#emailToName2').keyup(function () {
    $('#emailToAddress2').toggleClass('required', $(this).val());
});

但是这需要为每一个输入重复上述逻辑,这对我来说似乎有些过分。什么是更有活力的方法?

干杯!

5 个答案:

答案 0 :(得分:3)

您可以在指示需要字段时指定expressioncallback。然后,验证插件将在验证字段之前评估表达式或回调。

以下是一个例子:

$("#ref").validate({
  rules: {
    ref_1_email: {
      required: function(element) {
        return $("#ref_1_fname").val() || $("ref_1_lname").val();
      }
    }
  }
});
$("#ref_1_email").blur(function() {
  $("#ref_1_fname").valid();
  $("#ref_1_lname").valid();
});

你可以做一些重构,你不必为每个领域重复所有这些...

答案 1 :(得分:3)

您可以编写自己的自定义验证类,评估两个输入中的另一个是否已完成。

例如

jQuery.validator.addMethod('MyOwnValidator', function(value, element) {
    var required = false;
    $(element).parent().children('input').each(function() {
       if($(this).val() && $(this).attr('id') != $(element).attr('id')){
           required = true;
       }
    });
    return !required;
});

这将评估任何兄弟输入是否有值,如果有,则需要调用输入。

答案 2 :(得分:0)

没有尝试过,也没有写好:

$("#ref input").keyup(function () {
 $(this).parents("fieldset").children("input").toggleClass("required", $(this).val());
});

答案 3 :(得分:0)

你不能在一个循环中完成所有操作,因为你需要在切换类之前检查兄弟姐妹。但是,您可以定义一个可以检查和应用的小循环函数,但是您需要多次调用它来维护逻辑。

试试这个:

var loop = function(target, fn) {
    var t = 0, fn = fn || function(){};
    $(target).siblings().andSelf().each(function(i, el) {
        t += $(el).val().length;
        fn(el);
    });
    return t;
}
$('fieldset input').each(function() {
    $(this).bind('blur', function(e) {
        if(loop(e.target)) {
            loop(e.target, function(el) {
                $(el).toggleClass('required', !$(el).val().length);
            })
        } else {
            loop(e.target, function(el) {
                $(el).removeClass('required');
            })
        }
    });
});

答案 4 :(得分:0)

刚刚为一个项目调查此事。根据文档,以下内容应该做你想要的。

首次在表单上调用validate时,请执行以下操作:

$("#emailRecsForm").validate({
   rules: {
       ref_1_email: {
         required: ("#ref_1_fname:filled" || "#ref_1_lname:filled"),
         email: true
       },
       ref_1_fname: {
         required: ("#ref_1_email:filled" || "#ref_1_lname:filled")
       },
       ref_1_lname: {
         required: ("#ref_1_email:filled" || "#ref_1_fname:filled")
       },

       ref_2_email: {
         required: ("#ref_2_fname:filled" || "#ref_2_lname:filled"),
         email: true
       },
       // And so on...
   }
});

另外,请确保您的inputname属性与id相同。

我自己并没有真正尝试过,但是按the docs判断(请参阅required(dependency-expression)),它应该有效。