Jquery - 验证所有字段有效的多个字段(分组字段)

时间:2012-09-21 21:13:36

标签: jquery validation jquery-validate wicket

我一直在努力让多个字段的验证以通用方式工作。我的表单有一个父跨度,有两个文本字段,当一个或两个文本字段验证失败时,跨度应该用errorclass突出显示,在我的情况下,两个文本字段周围有一个红色框,当两个字段都有效时,跨度应该不突出显示。但实际行为是,如果第一个文本框被赋予有效值,则jquery highlight / unhighlight函数正在删除两个字段周围的errorClass / redbox,即使尚未传递第二个字段的必需/正则表达式验证。我已经编写了一个自定义方法,并为两个texbox添加了额外的验证规则,对tesboxes进行了分组,但没有一个正在工作,我实际上是jquery的新手,无法从我现在的位置继续,所以任何帮助都是非常感谢。

示例代码

setUpValidations:function(){

    $.validator.addMethod(
        'regex', function(value, element, param) {
            var regex = new RegExp(param);
            return regex.test(value);
        }, 'Regex failed'
    );

   $.validator.addMethod(
        'validateGroupFields', function(value, element) {
        var spanElement = $(element).closest('span');
        var spanChildren = listChildren(spanElement);
        var result = true;
                   spanChildren.each( function(index, value) {
            //alert("index" + index + "value" + value);
                if((this).valid() == true)
                {   
                    $(this).siblings('div.errorbuble1').hide();
                }else {
                    result = false;
                }
            });
            return result;
        }, 'Group validation failed'
    );

function listChildren(element) {
        var children = $(element).find(':input');
        return children;
    };

    $.validator.setDefaults({

        highlight: function(element) {
            $(element).closest('span').attr('class','error');
        },

        unhighlight: function(element) {
            $(element).closest('span').attr('class','');
        },

        onfocusout: function(element, event) {
            if ( !this.checkable(element) || !this.optional(element)) {
                this.element(element);
                $(element).siblings('div.errorbuble1').hide();
            }
        },

        onfocusin: function(element) {
            if( (element.name in this.submitted) && !$(element).valid()){
                    $(element).siblings('div.errorbuble1').show();
            }
        },

        onclick: function(element, event) {
        // click on selects, radiobuttons and checkboxes
            if(element.type === 'radio' || element.type === 'checkbox'){
                this.element(element);
            }
            else if( (element.name in this.submitted)){ //select
                this.element(element);
            }
        },


    });
},

 onValidate : function () {

    $('#form11').validate({
        errorClass: 'newError',

       submithandler: function(form11){
          (form11).submit();
       },

       invalidHandler: function(form, validator) {
        submitted = true;
        },

       rules : {
               'errorIndicator2:textField3':{
                 required:true,
                 regex : { 
                     param : /^[0-9]+$/
                 },
         validateGroupFields: true
             },
             'errorIndicator2:textField4':{
                 required:true,
                 regex : { 
                     param : /^[a-z]+$/
                 },
              validateGroupFields: true
             },
           },
          groups: {
    nameGroup: "errorIndicator2:textField3
             errorIndicator2:textField4"
        },

           showErrors: function(errorMap, errorList) {
            this.defaultShowErrors();
            if (submitted) {
                $('div.errorbuble1').hide();
                submitted = false;
            }
        },

           errorElement: "div",
       wrapper: "div", // a wrapper around the error message

       errorPlacement: function(error, element) {

            offset = element.offset();

            error.addClass('errorbuble1');  // add a class to the wrapper
            error.css('position', 'absolute');
            error.css('left', offset.left + (element.outerWidth()) + 5);
            error.css('top', offset.top + (element.outerHeight())/3);   
            error.insertAfter(element);  
       },


           var submitted = false;
       $(document).ready(function(){

JavaScriptValidator.setUpValidations();
JavaScriptValidator.onValidate();

$("[type=submit]").on({
    click: function(event) {
    JavaScriptValidator.onValidate();
    }
    });
});


 <h3>Error box around two fields:</h3> 
<span wicket:id="errorIndicator2"> 
<table>
    <tbody><tr>
    <td>Number:</td><td><input wicket:id="textField3" name="errorIndicator2:textField3" type="text"></td>
    </tr>
    <tr>
    <td>Alpha</td><td><input wicket:id="textField4" name="errorIndicator2:textField4" type="text"></td>
    </tr>
</tbody></table>
<!-- error popup div gets added here -->

2 个答案:

答案 0 :(得分:1)

在unhighlight函数中,在从容器中删除错误类之前,必须检查同一容器中的所有其他字段是否有效。像

这样的东西
$('input,select', $(element).closest('span')).not(element)

应该选择同一容器中的所有其他表单元素。但是,您可能会遇到递归问题(我没有尝试过您的情况,但请参阅require_from_group方法的discssion)。

此外,您不应该通过attr方法设置类。该元素可能具有其他用于其他目的的类,您可以在设置/取消设置错误类时将其删除。改为使用jQuery addClass和removeClass函数:

$(element).closest('span').addClass('error');
$(element).closest('span').removeClass('error');

答案 1 :(得分:1)

在高亮回调中调用元素(),$(...)。valid()或form()等验证方法将导致无限循环,但您可以使用验证器实例属性'invalid'维护无效字段列表。

$("form").validate({
    highlight: function (element, errorClass, validClass) {
        $(element).closest('div.container').addClass('errorClass');
    },
    unhighlight: function (element, errorClass, validClass) {
        var validator = this, result = true;

        // check for invalid elements here
        $(element).closest('div.container').find(':input').each(function () {
            if (validator.invalid[this.name] !== undefined) {
                result = false;
            }
        });
        if (result) {
            $(element).closest('div.container').removeClass('errorClass')
        }
    }
});

感谢@Adam让我走上了正确的轨道fiddle here