【问题标题】:Why does jQuery Validate Adds Error to a Valid Field?为什么 jQuery Validate 会向有效字段添加错误?
【发布时间】:2016-03-20 22:07:35
【问题描述】:

我正在处理一个包含多个字段的表单,当“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 标签/错误类。它是一个空标签,但会导致表单字段下拉附加标签。

这是表单打开时的样子

这是输入数据后的表格

我意识到 jquery validate 确实对模糊事件进行了表单验证,我理解的那部分工作正常。问题是在有效字段中附加了错误元素,结果导致表单高度扩展,并且没有提供任何信息来说明正在发生的事情。

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

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

【问题讨论】:

  • The code you posted does not show the issue。请构建一个更完整的演示。
  • @Sparky 我同意并理解您在说什么,如果我没有在此处发布的代码中发现问题,我会打开我的开发环境让您查看有关正在发生的事情的更多详细信息。问题解决是我的错误,因为没有看到“成功:函数(数据)”,它应该是“提交处理程序:函数(数据)”。按照我的回答中所述进行此修复解决了那些验证字段占用“空间”的问题,而不是像此页面上的所有表单那样没有空间的预期结果。谢谢,您确实促使我仔细查看以发现错误。

标签: jquery forms jquery-validate


【解决方案1】:

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

它没有。该插件动态创建 empty 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

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

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

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

    } else {

    }
}

我认为这里有更多代码,OP 只是将其删除以进行发布。但是,我不应该做出这个假设,因为 success 选项显示了空的 label 元素……它们是空的,因为 success 函数没有用任何东西填充它们。

documentation for explanation of how success caused the issue:

如果指定,则显示错误标签以显示有效元素。如果给定一个字符串,它会作为一个类添加到标签中。 如果给定了一个函数,则使用标签(作为 jQuery 对象)和经过验证的输入(作为 DOM 元素)调用它。该标签可用于添加“ok!”之类的文本。

就 OP 的回答而言,他只是将单词 success 更改为 submitHandler...

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

    } else {

    }
}

这解决了这个问题,因为他删除了success 选项。更改为 submitHandler 似乎完全没有必要,因为现在 submitHandler 正在被看起来像废话的代码覆盖。

默认情况下,插件会提交到表单的action 属性URL。您可以选择使用 submitHandler 覆盖,例如通过 ajax 提交。否则,data 参数将代表form 对象,并且条件没有意义,因为data 永远不会等于"success"... 此外,如果它不明显,那么有一个空的条件语句是没有意义的。

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

否则……

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

请参阅this answer 了解更多信息。


编辑 2

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

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

http://jsfiddle.net/8rhmfwtL/

【讨论】:

  • “完全没有必要更改为 submitHandler ......”这是另一个假设......我确实有目的在提交表单时不使用表单控件上的操作......这是来自的 sudo它驻留在的整个应用程序...它是实际代码,但不是代码的所有元素,例如 AngularJS 控制器、服务等。进一步的假设是我需要创建一个自定义成功处理程序,对我来说这将更无用覆盖 submitHandler。
  • @aallord,我唯一的信息是你来这里寻求帮助时发布的信息,然后对为什么将success函数移动到submitHandler函数突然变得很困惑好好工作。在任何情况下,if (data == "success")submitHandler 中绝对不会做任何事情,因为函数的唯一参数永远不会等于"success"
【解决方案2】:

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

$("#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 {
            }
        }**
    })

加粗的“成功:函数(数据)”应该是

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

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

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

【讨论】:

  • 根据文档,success 函数用于在字段通过验证时显示错误消息元素。与其将success 更改为submitHandler,不如将​​其完全删除。为什么你首先要有这个函数,尤其是当条件为空的时候?...我假设你知道它在做什么,只是简单地缩写你的代码来发布。请看:jqueryvalidation.org/validate/#success
  • 至于将其更改为submitHandler,您应该意识到这根本没有意义。 submitHandler 只是控制提交的方式/位置的函数。传递给submitHandler 的唯一参数是form,它代表form 对象...不是data,该对象也永远不会匹配"success",因此其中的空条件语句也是无用的。
  • “表单”是一个对象,可以用“数据”或函数中的任何其他变量来表示。像 submitHandler: function(data) 基于程序员所代表的返回结果,无论出于何种原因,都可能不会将其标记为数据...条件是空的,因为在编写它之前我遇到了错误。最好在完成提交处理之前解决错误,同意吗?条件实际上会在 ajax 调用成功时落地。
  • 同意,该函数的唯一参数可以由您选择的任意单词表示。但是,在这种情况下,参数表示form 对象,永远不会等于"success"。查看控制台日志:jsfiddle.net/8rhmfwtL
【解决方案3】:

您可以尝试添加 onfocusout: false 在验证器中。喜欢

$("#frmAddCustomer").validate({
        debug: true,
        onfocusout: false,
        ...

【讨论】:

  • 不幸的是,这只是一个帮手,并不能真正解决我遇到的问题,因为 jquery validate 应该在 onblur (onfocusout) 发生时进行验证,以让用户以交互方式了解无效的数据输入。
猜你喜欢
  • 2012-05-13
  • 1970-01-01
  • 2016-02-16
  • 1970-01-01
  • 2011-04-15
  • 1970-01-01
  • 2011-12-18
  • 1970-01-01
相关资源
最近更新 更多