为什么jQuery Validate会在有效字段中添加错误?

时间:2016-03-20 22:07:36

标签: jquery forms jquery-validate

我正在处理一个包含多个字段的表单,以及何时" onblur"发生jquery validate将错误类/标签添加到有效字段。

这是我的表单html

<div id="diaAddCustomer" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static">
<div class="modal-dialog" style="background-color: #fff; width: 650px;">
    <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&nbsp;</span></button>
        <h4 class="modal-title">Add New Customer</h4>
    </div>
    <form class="form-horizontal" id="frmAddCustomer" name="frmAddCustomer" novalidate>
        <input type="hidden" id="addCustomerPersonID" name="addCustomerPersonID" value="">
        <div class="modal-body">
            <div class="form-group">
                <div class="col-md-3">
                    <label for="addCustomerName">Name:</label>
                </div>
                <div class="col-md-9">
                    <input type="text" class="form-control input-sm" id="addCustomerName" name="addCustomerName" value="">
                </div>
            </div>
            <h4>Billing Address</h4>
            <div class="form-group">
                <div class="col-md-3">
                    <label for="addCustomerAdd1">Address:</label>
                </div>
                <div class="col-md-9">
                    <input type="text" class="form-control input-sm" id="addCustomerAdd1" name="addCustomerAdd1" value="">
                </div>
            </div>
            <div class="form-group">
                <div class="col-md-3">
                    <label for="addCustomerAdd2"></label>
                </div>
                <div class="col-md-9">
                    <input type="text" class="form-control input-sm" id="addCustomerAdd2" name="addCustomerAdd2" value="">
                </div>
            </div>
            <div class="form-group">
                <div class="col-md-3">
                    <label for="addCustomerCity">City:</label>
                </div>
                <div class="col-md-9">
                    <input type="text" class="form-control input-sm" id="addCustomerCity" name="addCustomerCity" value="">
                </div>
            </div>
            <div class="form-group">
                <div class="col-md-3">
                    <label for="addCustomerState">State:</label>
                </div>
                <div class="col-md-4">
                    <input type="text" class="form-control input-sm" id="addCustomerState" name="addCustomerState" value="">
                </div>
                <div class="col-md-2">
                    <label for="addCustomerZip">Zip:</label>
                </div>
                <div class="col-md-3">
                    <input type="text" class="form-control input-sm" id="addCustomerZip" name="addCustomerZip" value="" onkeyup="valNumber($(this))">
                </div>
            </div>
            <div class="form-group">
                <div class="col-md-3">
                    <label for="addCustomerPhone">Phone:</label>
                </div>
                <div class="col-md-4">
                    <input type="text" class="form-control input-sm" id="addCustomerPhone" name="addCustomerPhone" onkeyup="valNumber($(this))" onblur="formatPhone($(this))" onfocus="removePhoneFormat($(this))" value="">
                </div>
                <div class="col-md-2">
                    <label for="addCustomerPhoneType">Type:</label>
                </div>
                <div class="col-md-3">
                    <select class="form-control input-sm" id="addCustomerPhonetype" name="addCustomerPhoneType">
                        <option value=""> Please Select...</option>
                        <option value="cell"> Cell</option>
                        <option value="fax"> Fax</option>
                        <option value="phone"> Phone</option>
                    </select>
                </div>
            </div>
            <div class="form-group">
                <div class="col-md-3">
                    <label for="addCustomerEmail">Email:</label>
                </div>
                <div class="col-md-9">
                    <input type="text" class="form-control input-sm" id="addCustomerEmail" name="addCustomerEmail" value="">
                </div>
            </div>
            <h4>Shipping Address <span style="font-size: 10pt;"><input type="checkbox" id="ckbSameShip" ng-click="setShipAddress()"> Same As Billing</span></h4>
            <div class="form-group">
                <div class="col-md-3">
                    <label for="addCustomerShipAdd1">Address:</label>
                </div>
                <div class="col-md-9">
                    <input type="text" class="form-control input-sm" id="addCustomerShipAdd1" name="addCustomerShipAdd1" value="">
                </div>
            </div>
            <div class="form-group">
                <div class="col-md-3">
                    <label for="addCustomerShipAdd2"></label>
                </div>
                <div class="col-md-9">
                    <input type="text" class="form-control input-sm" id="addCustomerShipAdd2" name="addCustomerShipAdd2" value="">
                </div>
            </div>
            <div class="form-group">
                <div class="col-md-3">
                    <label for="addCustomerShipCity">City:</label>
                </div>
                <div class="col-md-9">
                    <input type="text" class="form-control input-sm" id="addCustomerShipCity" name="addCustomerShipCity" value="">
                </div>
            </div>
            <div class="form-group">
                <div class="col-md-3">
                    <label for="addCustomerShipState">State:</label>
                </div>
                <div class="col-md-4">
                    <input type="text" class="form-control input-sm" id="addCustomerShipState" name="addCustomerShipState" value="">
                </div>
                <div class="col-md-2">
                    <label for="addCustomerShipZip">Zip:</label>
                </div>
                <div class="col-md-3">
                    <input type="text" class="form-control input-sm" id="addCustomerShipZip" name="addCustomerShipZip" value="" onkeyup="valNumber($(this))">
                </div>
            </div>
            <div class="form-group">
                <div class="col-md-3">
                    <label for="addCustomerShipPhone">Phone:</label>
                </div>
                <div class="col-md-4">
                    <input type="text" class="form-control input-sm" id="addCustomerShipPhone" name="addCustomerShipPhone" onkeyup="valNumber($(this))" onblur="formatPhone($(this))" onfocus="removePhoneFormat($(this))" value="">
                </div>
                <div class="col-md-2">
                    <label for="addCustomerShipPhoneType">Type:</label>
                </div>
                <div class="col-md-3">
                    <select class="form-control input-sm" id="addCustomerShipPhonetype" name="addCustomerShipPhoneType">
                        <option value=""> Please Select...</option>
                        <option value="cell"> Cell</option>
                        <option value="fax"> Fax</option>
                        <option value="phone"> Phone</option>
                    </select>
                </div>
            </div>
        </div>
        <div class="modal-footer">
            <button type="submit" class="btn btn-sm btn-primary"><i class="glyphicon glyphicon-plus"></i> Add Customer</button>
            <button type="button" class="btn btn-sm btn-default" data-dismiss="modal"><i class="glyphicon glyphicon-ban-circle"></i> Cancel</button>
        </div>
    </form>
</div>

这是我的验证脚本

$scope.openAddCustomerWdw = function(pID){
        $("#diaAddCustomer").on("shown.bs.modal", function(){
            $("#addCustomerPersonID").val(pID);
            $("#addCustomerName").val("");
            $("#addCustomerAdd1").val("");
            $("#addCustomerAdd2").val("");
            $("#addCustomerCity").val("");
            $("#addCustomerState").val("");
            $("#addCustomerZip").val("");
            $("#addCustomerPhone").val("");
            $("#addCustomerPhoneType").val("");
            $("#addCustomerEmail").val("");
            $("#addCustomerShipAdd1").val("");
            $("#addCustomerShipAdd2").val("");
            $("#addCustomerShipCity").val("");
            $("#addCustomerShipState").val("");
            $("#addCustomerShipZip").val("");
            $("#addCusomterShipPhone").val("");
            $("#addCustomerShipPhoneType").val("");
            $("#addCustomerName").select();
        });
        $("#diaAddCustomer").modal("show");
        $("#frmAddCustomer").validate({
            debug: true,
            rules: {
                addCustomerName: { required: true },
                addCustomerAdd1: { required: true },
                addCustomerCity: { required: true },
                addCustomerState: { required: true },
                addCustomerZip: { required: true },
                addCustomerPhone: { required: true, phoneUS: true },
                addCustomerPhoneType: { required: true },
                addCustomerEmail: { required: function(){
                    return $("#addCustomerEmail").length > 0;
                }, email: true },
                addCustomerShipAdd1: { required: true },
                addCustomerShipCity: { required: true },
                addCustomerShipZip: { required: true },
                addCustomerShipPhone: { required: true, phoneUS: true },
                addCustomerShipPhoneType: { required: true }
            },
            messages: {
                addCustomerName: { required: "Name is Required" },
                addCustomerAdd1: { required: "Address is Required" },
                addCustomerCity: { required: "City is Required" },
                addCustomerState: { required: "State is Required" },
                addCustomerZip: { required: "Zip Code is Required" },
                addCustomerPhone: { required: "Valid Phone Required", phoneUS: "Valid Phone Required" },
                addCustomerPhoneType: { required: "Phone Type Required" },
                addCustomerEmail: { required: "Valid Email Required", email: "Valid Email Required" },
                addCustomerShipAdd1: { required: "Address is Required" },
                addCustomerShipCity: { required: "City is Required" },
                addCustomerShipState: { required: "State is Required" },
                addCustomerShipZip: { required: "Zip Code is Required" },
                addCustomerShipPhone: { required: "Valid Phone Required", phoneUS: "Valid Phone Required" },
                addCustomerShipPhoneType: { required: "Phone Type is Required" }
            },
            success: function(data){
                if(data == "success"){

                } else {

                }
            }
        })
    }

当表单打开时,html如上所示,没有应用jquery标签/错误类。在第二个地址字段以外的任何字段中输入文本时,在发生onblur时应用jquery标签/错误类。它是一个空标签,但会导致表单字段下拉为附加标签。

这是打开时表单的样子

Form when opened

这是输入数据后的表格

Form after data entered

我意识到jquery validate对blur事件进行了表单验证,我知道这部分工作正常。问题是有效字段中的附加错误元素以及导致表单在高度上扩展的结果,并且没有向正在发生的事情提供信息。

我尝试过使用debug:true,查看控制台窗口并尝试以不同方式跟踪此错误,遗憾的是似乎没有任何其他错误信息可供使用。

非常感谢帮助我指出错误在代码中的正确方向。

3 个答案:

答案 0 :(得分:0)

  

为什么jQuery Validate会在有效字段中添加错误?

没有。该插件动态创建 label元素,以包含任何未来的验证错误消息。然后,当验证错误发生时,将填充label元素并根据需要切换

  

问题是有效字段中的附加错误元素以及导致表单高度扩展的结果,并且没有提供正在发生的事情的信息。

debug选项仅用于指出.validate()方法中各种可能的语法错误。但是,您的问题是由HTML和/或CSS引起的,因此,此插件无法知道此问题。

正如您在本演示中所看到的,您的jQuery Validate代码与您的问题无关,因为布局完全不受隐藏/空label元素的影响:

http://jsfiddle.net/d0n5L8qj/

在这里发布的关于jQuery Validate的数千个问题中,我从未见过有人报告过这种情况。通常,空或隐藏元素将占用布局中的零空间。由于某些完全未知的原因(您没有显示足够的代码),您的特定布局会受到这些空隐藏元素的影响。您需要检查实时DOM和/或CSS,以找出导致这些空label元素占用空间的根本原因。否则,您必须create a demo 重现问题,以便我们检查DOM和/或CSS。

修改

来自the OP's own answer

  

我不知道如何或为什么在我的代码中进行此更正会将验证字段更改为不再占用我原始帖子中显示的空间,但是进行此修订确实可以阻止此问题的发生。

我不应该认为这是故意的......

success: function(data){
    if(data == "success"){

    } else {

    }
}

我认为这里有更多代码,OP只是将其删除以便发布。但是,我不应该做出这样的假设,因为success选项显示空的label元素...它们是空的,因为success函数没有填充它们什么都有。

请参阅documentation for explanation of how success caused the issue

  

如果指定,则显示错误标签以显示有效元素。如果给出了String,则将其作为类添加到标签中。 如果给出了一个Function,则使用标签(作为jQuery对象)和验证的输入(作为DOM元素)调用它。标签可用于添加文本,例如&#34; ok!&#34;。

就OP的答案而言,他只是将success改为submitHandler ......

submitHandler: function(data){
    if(data == "success"){

    } else {

    }
}

这解决了这个问题只是因为他删除了success选项。改为submitHandler似乎完全没必要了,因为现在submitHandler被看似无意义的代码覆盖了。

默认情况下,该插件会提交到表单的action属性网址。您可以选择使用submitHandler覆盖,例如通过ajax提交。否则,data参数将代表form对象,条件没有意义,因为data永远不会等于"success" ...同样,如果它不是很明显,没有必要使用空的条件语句。

submitHandler: function(form){
    form.submit();  // <-default
}

...否则

submitHandler: function(form){
    // ajax code
    return false;
}

有关详细信息,请参阅this answer

编辑2

是的,我意识到submitHandler的论证可以用任意词来表示。但是,即使您将其重命名为form,此函数的唯一参数也始终代表data对象。

请参阅以下演示。确保表单填写正确,点击提交,然后查看控制台的日志......

http://jsfiddle.net/8rhmfwtL/

答案 1 :(得分:0)

今晚我偶然发现了解决方案,尽管我无法完全解释为什么会导致上述问题。问题出在验证码上。如上所述

$("#frmAddCustomer").validate({
        debug: true,
        rules: {
            addCustomerName: { required: true },
            addCustomerAdd1: { required: true },
            addCustomerCity: { required: true },
            addCustomerState: { required: true },
            addCustomerZip: { required: true },
            addCustomerPhone: { required: true, phoneUS: true },
            addCustomerPhoneType: { required: true },
            addCustomerEmail: { required: function(){
                return $("#addCustomerEmail").length > 0;
            }, email: true },
            addCustomerShipAdd1: { required: true },
            addCustomerShipCity: { required: true },
            addCustomerShipZip: { required: true },
            addCustomerShipPhone: { required: true, phoneUS: true },
            addCustomerShipPhoneType: { required: true }
        },
        messages: {
            addCustomerName: { required: "Name is Required" },
            addCustomerAdd1: { required: "Address is Required" },
            addCustomerCity: { required: "City is Required" },
            addCustomerState: { required: "State is Required" },
            addCustomerZip: { required: "Zip Code is Required" },
            addCustomerPhone: { required: "Valid Phone Required", phoneUS: "Valid Phone Required" },
            addCustomerPhoneType: { required: "Phone Type Required" },
            addCustomerEmail: { required: "Valid Email Required", email: "Valid Email Required" },
            addCustomerShipAdd1: { required: "Address is Required" },
            addCustomerShipCity: { required: "City is Required" },
            addCustomerShipState: { required: "State is Required" },
            addCustomerShipZip: { required: "Zip Code is Required" },
            addCustomerShipPhone: { required: "Valid Phone Required", phoneUS: "Valid Phone Required" },
            addCustomerShipPhoneType: { required: "Phone Type is Required" }
        },
        **success: function(data){
            if(data == "success"){
            } else {
            }
        }**
    })

粗体&#34;成功:功能(数据)&#34;应该是

submitHandler: function(data){
   if(data == "success"){
   } else {
   }
}

我不知道如何或为什么在我的代码中进行此更正会将验证字段更改为不再占用空间,如我原始帖子中所示,但进行此修订确实可以阻止此问题的发生。

经过几个小时的搜索后我无法找到这个问题,并且在@Sparky的评论中,在数以千计的JQuery Validate问题中他们从未见过这种情况。我也无法找到逻辑推理如何/为什么会导致此处发布问题。

答案 2 :(得分:-1)

您可以尝试添加 验证器中的$("#frmAddCustomer").validate({ debug: true, onfocusout: false, ... 。像

angular.isUndefined(value)