具有多个输入的.form-group上的jQuery验证

时间:2016-12-30 19:47:20

标签: javascript jquery jquery-validate

使用jQuery Validation插件,我为我的Bootstrap form定义了以下内容:

$(".form-with-validation").validate({
    errorClass: "help-block",
    errorElement: "span",
    highlight: function(element) {
        $(element).closest('.form-group').addClass('has-error');
    },
    unhighlight: function(element) {
        $(element).closest('.form-group').removeClass('has-error');
    }
});

它适用于简单的表单。但是,当highlight包含需要验证的多个输入(内联)时,unhighlight.form-group的部分不起作用:

<div class="form-group">
    <label class="col-md-4 control-label">State &amp; Zip</label>
    <div class="col-md-3">
        <select class="form-control required" name="state">
            ...
        </select>
    </div>
    <div class="col-md-3">
        <input type="text" class="form-control required" name="zip">
    </div>
</div>

问题在于,例如,一旦选择状态,输入就会变为有效,并且其.form-group失去.has-error,即使兄弟输入(即zip)仍然无效(即在其下方有.help-block个范围):

enter image description here

因此,我将unhighlight部分更改为以下内容:

unhighlight: function(element) {
    var formGroup = $(element).closest('.form-group');
    var formGroupIsValid = true;
    formGroup.find('input').each(function(){
        if (! $(this).valid())
            formGroupIsValid = false;
    });
    if (formGroupIsValid)
        formGroup.removeClass('has-error');
}

然而我收到以下错误:

Uncaught RangeError: Maximum call stack size exceeded

任何想法为什么?我尝试了很多方法,但每次都出现同样的错误。

修改

如果可能的话,我更愿意坚持div.form-group .has-error课程(因为造型)。

编辑2

Jsfiddle来证明这个问题。

4 个答案:

答案 0 :(得分:2)

这是我最终解决的问题。它比我想象的要简单。正如人们之前指出的那样,任何form-group一次只能包含一个form-control。因此,最简单的解决方案是在第一个form-group内放置第二个form-control,然后将第二个<div class="form-group"> <label class="col-md-4 control-label">State &amp; Zip</label> <div class="col-md-6"> <div class="row"> <div class="col-sm-6"> <select class="form-control required" name="state"> ... </select> </div> <div class="col-sm-6 form-group" style="margin-bottom:0;padding-right:0"> <input type="text" class="form-control required" name="zip"> </div> </div> </div> </div> 放在那里:

<dependency>
        <groupId>org.jsoup</groupId>
        <artifactId>jsoup</artifactId>
        <version>1.10.2</version>
</dependency>

只需几个CSS样式,这样做效果很好,看起来很好。这是一个jsfiddle

答案 1 :(得分:1)

您正在调用一个调用另一个函数的函数,依此类推,直到达到调用堆栈限制。当您致电.each时,我将假设问题出在.valid()循环中。

你不应该做任何这些。您应该专门针对输入定位某些内容,而不是定位form-group,这样您就不必更改unhightlight函数。例如:

<div class="form-group">
    <label class="col-md-4 control-label">State &amp; Zip</label>
    <div class="col-md-3 inputToValidate">
        <select class="form-control required" name="state">
            ...
        </select>
    </div>
    <div class="col-md-3 inputToValidate">
        <input type="text" class="form-control required" name="zip">
    </div>
</div>

然后将JavaScript代码更新为:

$(".form-with-validation").validate({
    errorClass: "help-block",
    errorElement: "span",
    highlight: function(element) {
        $(element).closest('.inputToValidate').addClass('has-error');
    },
    unhighlight: function(element) {
        $(element).closest('.inputToValidate').removeClass('has-error');
    }
});

答案 2 :(得分:1)

  

如果可能的话,我更喜欢坚持使用.has-error类的div.form-group

插件提供的选项无法实现。在要验证的元素上切换有效/无效类。可以修改highlightunhighlight函数,以使用jQuery DOM遍历等在其他元素上切换类。

但是,您希望逻辑能够使父容器&#34;无效&#34;当它的任何一个孩子都无效时......插件没有装备。只要无效的子元素触发父元素的错误类,任何有效的子元素都会将有效的类应用于同一个父元素。

一种解决方法是外部 keyupchange处理程序,它查看所有兄弟输入元素上的类并相应地切换其父类。基于您自己的代码和未经测试的......

$('input, select').on('keyup change', function() {
    var formGroup = $(this).closest('.form-group');
    var formGroupIsValid = true;
    formGroup.find('input, select').each(function(){
        if (! $(this).valid()) {
            formGroupIsValid = false;
        }
    });
    if (formGroupIsValid) {
        formGroup.removeClass('has-error');
    } else {
        formGroup.addClass('has-error');
    }
});
  

我收到以下错误:Uncaught RangeError: Maximum call stack size exceeded ....有什么想法?

是的,您正在.valid()方法(通过.validate())中调用unhighlight方法。因此,在此方法中调用$(this).valid()只会导致再次调用unhighlight ......等等。

答案 3 :(得分:-1)

您不必使用带验证的表单类,您可以通过选择inputToValidate类来定位要验证的所有表单字段。它也简单得多。您可能也想使用toggleClass。

$(".inputToValidaten").validate({
    errorClass: "help-block",
    errorElement: "span",
    highlight: function(element) {
        $(this).toggleClass('has-error');
    },
    unhighlight: function(element) {
        $(this).toggleClass('has-error');
    }
});

更新和编辑

行。所以这里的代码将适用于任何带有form-control类的嵌套表单字段。它将上升并使用form-group类获取最接近的元素,然后将验证代码添加到其中。

$(".form-control").validate({
    errorClass: "help-block",
    errorElement: "span",
    highlight: function(e) {
        $(e.target).closest('.form-group').toggleClass('has-error');
    },
    unhighlight: function(e) {
        $(e.target).closest('.form-group').toggleClass('has-error');
    }
});