jQuery验证条件必需和组的错误消息

时间:2014-12-03 16:05:39

标签: jquery jquery-validate

在使用jQuery Validate插件时,我一直在努力尝试在3种不同的情况下正确显示自定义错误消息。

  • 如果我有一个集团,则只需要该集团的一名成员。
  • 复选框字段的自定义消息。
  • 在有条件地需要字段时显示错误消息。

我已经记下了这篇文章:How to show different error messages based on various conditions。它可能是解决我的问题的一部分吗?我也看了Custom error messages for Groups within the jQuery Validation plugin,但它似乎没有解决只有一个小组成员被要求并且没有解决我的问题的问题。

我是jQuery和小提琴的新手,并且有一个不正常的小提琴。我怀疑它是因为我没有链接到CSS中使用的图形,这些图形来自验证插件包中的Milk和Marketo示例。小提琴是http://jsfiddle.net/cloudmech/myvmb95d/23/

这是我正在使用的代码。

JQuery:

$(document).ready(function() {
    $('#00NU00000049YHZ').change(function(){
       var checked = $(this).is(':checked');
       $('#company_information').toggle(checked);
       $('#company').prop('disabled', !checked)
   }).change();

    var $CompHdwDon = $('#00NU00000049YHj'),
    $SchedPickup = $('#00NU00000049YHt');

    $('#w2lForm').validate({
        debug: true,
        rules:{
            company: {
                depends: function(element) {
                    var checked = $('#00NU00000049YHZ').is(':checked');
                    return (checked);
                minlength: 3
                    }
                },             
            phone: {
                require_from_group: [1, '.phone_group'],
                phoneUS: true,
            },
            Mobile: {
                require_from_group: [1, '.phone_group'],
                phoneUS: true,
            },
            CompHdwDon: {
                required: checked=true
            },              
            SchedPickup: {
                required: checked=true
            },      
        },
        messages: {
            company: {
                depends: function(element) {
                    var checked = $('#00NU00000049YHZ').is(':checked');
                    return (checked);
                required: "Please provide the name of your company"
                }
            },
            phone_group: {
                required: "Either your regular or mobile phone is required"
            },
            phone: {
                required: "Either your regular or mobile phone is required"
            },
            Mobile: {
                required: "Either your regular or mobile phone is required"
            },
            CompHdwDon: {
                required: "This box must be checked for us to pick up a donation"
            },      
            SchedPickup: {
                required: "This box must be checked to schedule a donation pickup"
            },      
        },  
        // the errorPlacement has to take the table layout into account
        errorPlacement: function(error, element) {
            var n = element.attr("name");
            if (n == "phone" || n == "Mobile")
                error.appendTo(element.parent().next());
            else if (element.is(":radio"))
                error.appendTo(element.parent().next().next());
            else if (element.is(':checkbox'))
                error.appendTo(element.parent().next());
            else 
                error.appendTo(element.parent().next());
        },
        // set this class to error-labels to indicate valid fields
        success: function(label) {
            // set   as text for IE
            label.html(" ").addClass("checked");
        },
        highlight: function(element, errorClass) {
            $(element).parent().next().find("." + errorClass).removeClass("checked");
        }
        // specifying a submitHandler prevents the default submit, good for the demo
    });

});

HTML:

<BODY>
<div id="page-content-inner" class="resize">
<form id="w2lForm" action="https://www.xxxxx.com/servlet/servlet.WebToLead?encoding=UTF-8" method="POST">
<input type=hidden name="retURL" value="http://www.google.com"> 
</br>
<TABLE >
<TR>
    <TD class="label">This is for a Company:</TD>
    <TD class="field"><input  id="00NU00000049YHZ" name="00NU00000049YHZ" type="checkbox" value="0"  /></TD>
    <TD class="status"></TD>
<!--  If is This is for a Company == false, hide line below. If = true, show line below  -->
    <TD class="label" colspan="2">
    <div id="company_information">
    <label id="cmpnylbl" for="company" class="label" >Company:
    <input  id="company" maxlength="40" name="company" size="20" type="text"  class="required" /></div></TD>
    <TD class="status"></TD>
</TR>
<!--- create phone group below and require 1 of the two --->
<TR>
    <TD class="label"><label for="phone">Phone:</label></TD>
    <TD class="field"><input id="phone" class="phone_group" maxlength="40" name="phone" size="20" type="text" /></TD>
    <TD class="status"></TD>
    <TD class="label"><label for="mobile">Mobile:</label></TD>
    <TD class="field"><input id="mobile" class="phone_group" maxlength="40" name="mobile" size="20" type="text" /></TD>
    <TD class="status"></TD>
</TR>
<TR>
    <TD class="label">Computer Hardware Donation:</TD>
    <TD class="field"><input id="00NU00000049YHj" name="00NU00000049YHj" type="checkbox" value="1" class="required" /></TD>
    <TD class="status"></TD>
    <TD class="label">Schedule Pickup:</TD>
    <TD class="field"><input id="00NU00000049YHt" name="00NU00000049YHt" type="checkbox" value="1" class="required" /></TD>
    <TD class="status"></TD>
</TR>
<TR><TD class="field" COLSPAN="4"><input type="submit" name="submit"></TD></TR>
</TABLE>
</form>
</div>
</BODY>

CSS:

body, input, select, textarea { font-family: verdana, arial, helvetica, sans-serif; font-size: 11px; }
img {
    border: 0px;
}

#resize{
    width: 500px;
}

.clear {
    clear: both;
}

input { border: 1px solid black; margin-bottom: .5em;  }

input.error { border: 2px solid red; }

label.error {
    display: block;
    color: red;
    font-style: italic;
    font-weight: normal;
    background: url('images/unchecked.gif') no-repeat;
    padding-left: 16px;
    margin-left: .3em;
}
label.valid {
    background: url('images/checked.gif') no-repeat;
    display: block;
    width: 16px;
    height: 16px;
}

form table td {
    padding: 5px;
}

form table input {
    width: 200px;
    padding: 3px;
    margin: 0px;
}

textarea {
    width: 400px
}

td.label {
    width: 150px;
}

tr.required td.label {
    font-weight: bold;
    background: url( 'images/backRequiredGray.gif') no-repeat right
        center;
}


td.field input.error, td.field select.error, tr.errorRow td.field input,tr.errorRow td.field select {
    border: 2px solid red;
    background-color: #FFFFD5;
    margin: 0px;
    color: red;
}

tr td.field div.formError {
    display: none;
    color: #FF0000;
}

tr.errorRow td.field div.formError {
    display: block;
    font-weight: normal;
}

#w2lForm .table {
  border-spacing: 0px;
  border-collapse: collapse;
  empty-cells: show;
}

#w2lForm .label {
  padding-top: 2px;
  padding-right: 8px;
  vertical-align: top;
  text-align: right;
  width: 125px;
  white-space: nowrap;
}

#w2lForm .field {
  padding-bottom: 10px;
  white-space: nowrap;
}

#w2lForm .status {
  padding-top: 2px;
  padding-left: 8px;
  vertical-align: top;
  width: 246px;
  white-space: nowrap;
}

#w2lForm .textfield {
  width: 150px;
}

#w2lForm label.error {
  background:url("images/unchecked.gif") no-repeat 0px 0px;
  padding-left: 16px;
  padding-bottom: 2px;
  font-weight: bold;
  color: #EA5200;
}

#w2lForm label.checked {
  background:url("images/checked.gif") no-repeat 0px 0px;
}

作为最后一个问题,当我将这一切全部工作时,我想使用显示的servlet发布它。我是否需要在jQuery中添加以下内容,是否需要构建Ajax处理程序或什么都不做?我观察到,当servlet的完整URL可用时,似乎提交“按原样”。

submitHandler: function(form) {
   form.submit();
}

修改jQuery:

$(document).ready(function() {

    $('#00NU00000049YHZ').change(function(){
       var checked = $(this).is(':checked');
       $('#company_information').toggle(checked);
       $('#company').prop('disabled', !checked)
   }).change();

    $('#00NU00000049YHZ').on('change', function () {  // fire on change
        $('[name="company"]').valid();  // evaluate rules on company
    });


    $('#w2lForm').validate({
        debug: true,

        rules:{
            company: {
                required: {
                    depends: function(element) {
                        return $('#00NU00000049YHZ').is(':checked');
                    }
                },
                minlength: 3
            },             
            phone: {
                require_from_group: [1, '.phone_group'],
                phoneUS: true,
            },
            Mobile: {
                require_from_group: [1, '.phone_group'],
                phoneUS: true,
            },
            "00NU00000049YHj": {
                required: true
            },              
            "00NU00000049YHt": {
                required: true
            },      
        },
        messages: {
            company: {
                required: "Please provide the name of your company",
                minlength:  "Please type at least {0} characters"
            },
            phone: {
                require_from_group: "Either your regular or mobile phone is required"
            },
            Mobile: {
                require_from_group: "Either your regular or mobile phone is required"
            },
            "00NU00000049YHj": {
                required: "This box must be checked for us to pick up a donation"
            },      
            "00NU00000049YHt": {
                required: "This box must be checked to schedule a donation pickup"
            },      
        },  
        // the errorPlacement has to take the table layout into account
        errorPlacement: function(error, element) {
            var n = element.attr("name");
            if (n == "phone" || n == "Mobile")
                error.appendTo(element.parent().next());
            else if (element.is(":radio"))
                error.appendTo(element.parent().next().next());
            else if (element.is(':checkbox'))
                error.appendTo(element.parent().next());
            else 
                error.appendTo(element.parent().next());
        },
        // set this class to error-labels to indicate valid fields
        success: function(label) {
            // set &nbsp; as text for IE
            label.html("&nbsp;").addClass("checked");
        },
        highlight: function(element, errorClass) {
            $(element).parent().next().find("." + errorClass).removeClass("checked");
        }

    });

});

1 个答案:

答案 0 :(得分:4)

你的最后一个问题......

仅当您想要更改插件的默认行为时,才需要submitHandler回调函数。默认行为是表单提交将被阻止,直到所有数据条目都通过验证,然后它将被提交到action元素的form属性中的URL。

此代码基本上是默认代码,因此整个submitHandler是多余的,可以省略.validate() ...

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

但是,如果您想通过ajax提交表单,那么您可以按照以下方式使用该表单...

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

其次,你的代码在这里真的被打破了......

rules:{
    company: {
        depends: function(element) {
            var checked = $('#00NU00000049YHZ').is(':checked');
            return (checked);
        minlength: 3
            }
        },
....
messages: {
    company: {
        depends: function(element) {
            var checked = $('#00NU00000049YHZ').is(':checked');
            return (checked);
        required: "Please provide the name of your company"
        }
    }, 

depends不是规则; depends是一个规则的属性,它只是简单地打开和关闭规则,并且您不能在函数内部浮动一个键:值对。这应该导致各种错误。并且你永远不会depends内看到messages,因为消息不依赖于任何内容......它只是附加到规则上。

据推测,您希望company字段required取决于另一个条件......

rules:{
    company: {
        required: {
            depends: function(element) {
                return $('#00NU00000049YHZ').is(':checked');
            }
        },
        minlength: 3
    },
    ....
},
messages: {
    company: {
        required: "Please provide the name of your company",
        minlength:  "Please type at least {0} characters"
    },
    ....
},
....

第三,这是什么?

CompHdwDon: {
    required: checked=true
},              
SchedPickup: {
    required: checked=true
},

checked=true方法的值只能是布尔值或函数(required)时,不能将depends作为值。

CompHdwDon: {
    required: true
},              
SchedPickup: {
    required: true
},

最后,require_from_group方法/规则将创建一个条件,即使您只希望组中的一个字段为required,错误消息也会显示在所有字段上。 The solution is to use the groups option, which will simply group all messages for this particular group of fields into one。然后可以使用errorPlacement选项实现消息的准确放置。


修改

例如,

您的代码。

rules: {
    Mobile: {
        require_from_group: [1, '.phone_group'],
        phoneUS: true
    },
},
messages: {
    Mobile: {
        required: "Either your regular or mobile phone is required"
    },
}

rules下的方法与messages下的方法不匹配...您可以保留一些但不能添加任何不存在的方法。

key:value下的相应messages对需要匹配...

messages: {
    ....
    Mobile: {
        require_from_group: "Either your regular or mobile phone is required"
    },
    ....

编辑2:

CompHdwDon: { // <- this should match the NAME of the field!
    required: true
},  

此代码完全没有任何效果,因为您没有name="CompHdwDon"字段。只有出现才能正常工作,因为您在复选框上有class="required"。在这种情况下,插件使用required class来设置规则。在.validate()内声明规则或将它们内联声明,但不需要同时执行这两项规则。

改变这个......

<TD class="label">Computer Hardware Donation:</TD>
<TD class="field"><input id="00NU00000049YHj" name="00NU00000049YHj" type="checkbox" value="1" class="required" /></TD>

进入这个...

<TD class="label">Computer Hardware Donation:</TD>
<TD class="field"><input id="CompHdwDon" name="CompHdwDon" type="checkbox" value="1" /></TD>

编辑3

highlight: function(element, errorClass) {
    $(element).parent().next().find("." + errorClass).removeClass("checked");
}

您无需在errorClass对象后附加句点。它已经内置。使用highlight时,您通常还需要unhighlight

您也不需要.find(errorClass),因为此类始终切换,highlight仅在字段无效时触发。另请注意,highlight仅针对正在评估的特定字段。

highlight: function(element, errorClass) {
    $(element).parent().next().removeClass("checked");
},
unhighlight: function(element, errorClass) {
    $(element).parent().next().addClass("checked");
}

编辑4

单击复选框时立即在另一个字段上触发错误消息意味着我们需要一个事件处理程序。然后我们只需触发.valid()方法来评估该字段的规则。

$('#00NU00000049YHZ').on('change', function () {  // fire on checkbox change
    $('[name="company"]').valid();  // evaluate rules on company
});

或者这......

// assuming your existing change handler is already working...
$('#00NU00000049YHZ').change(function(){
    var checked = $(this).is(':checked');
    $('#company_information').toggle(checked);
    $('#company').prop('disabled', !checked);
    $('[name="company"]').valid();  // evaluate rules on company
}).change();

为了安全起见,请在致电change后加上此.validate()处理程序。