【发布时间】:2016-08-19 12:56:07
【问题描述】:
我创建了一个非常标准的复选框 JQuery 验证示例:https://jsfiddle.net/rbL62zm8/1/
为清楚起见,此问题的代码中省略了 console.log 语句。
验证rules 需要选择数字或字符串类型。如果选择了 Number,则还必须选择数字类型(Int、Float 或 Double)。
var validationRules = {
debug: true,
rules: {
'type': {
// Number or String
required: true,
},
'numeric': {
// Int, Float or Double.
required: '#typeNumber:checked'
}
},
messages: {
'type': {
required: 'A data type is required.'
},
'numeric': {
required: 'A numeric data type is required.'
}
},
onclick: function(element) {
$(element).valid();
},
submitHandler: function(form) {
$("#validationMsg").html("The form is valid.");
return false;
},
errorPlacement: function(label, element) {
$("#validationMsg").html(label);
},
}
对应的HTML表单:
<form id="mainForm" name="mainForm" method='post' action=''>
<input type="checkbox" name="type" class="type-group" id="typeNumber" value="Number">
<label for="typeNumber">Number</label>
<input type="checkbox" name="type" class="type-group" id="typeString" value="String" checked>
<label for="typeString">String</label>
<br />
<input type="checkbox" name="numeric" class="numeric-group" id="numericInt" value="Int">
<label for="numericInt">Int</label>
<input type="checkbox" name="numeric" class="numeric-group" id="numericFloat" value="Float">
<label for="numericFloat">Float</label>
<input type="checkbox" name="numeric" class="numeric-group" id="numericDouble" value="Double">
<label for="numericDouble">Double</label>
<br />
<input type='submit' name='Submit' value='Submit' />
<input type='reset' name='Reset' value='Reset' />
</form>
<div id="validationMsg"></div>
表单的默认状态确保 String 复选框被勾选:
我添加了一个onclick 实现,试图在选中或取消选中复选框时验证表单。
用例 #1
- 运行 JSFiddle。
- 取消选中字符串复选框。
结果:显示错误信息,正确。
用例 #2
- 运行 JSFiddle。
- 取消选中字符串复选框。
- 勾选字符串复选框。
结果:显示错误消息并保持可见。这似乎不一致,因为显示错误消息(取消勾选复选框)的操作被反转,但错误消息没有更新。
问题: 如何在状态更改时验证所有复选框?
更新
我在validation configuration object 中添加了invalidHandler:
invalidHandler: function(form, validator) {
var errors = validator.numberOfInvalids();
console.log('Number of invalids: %s', errors);
},
JSFiddle:https://jsfiddle.net/xz1a43fm/
invalidHandler 函数仅在表单处于无效状态时调用。因此,勾选 String 复选框会使表单进入有效状态,并且不会调用 invalidHandler。
submitHandler 是我能找到的与 invalidHandler 对应的最接近的东西 - 但是它只被称为 onSubmit 而不是 onClick。
最终解决方案
我有三个要求:
- 实时验证:在用户与表单交互时验证复选框,而不仅仅是在提交时。
-
双向依赖:验证双向依赖。 IE。如果
Number被打勾,Float、Int或Double必须打勾,而且,如果Float、Int或Double打勾,Number必须打勾。 - 请勿破解:请勿在大型自定义验证方法中重写内置规则。
实时验证:实现自定义onclick 函数很常见,但是我遗漏了两个关键细节:
- 验证整个表单,而不是单个元素。通过在整个表单上调用
valid(),可以评估复选框组之间的所有相互依赖关系。 - 检查有效状态并在需要时手动清除错误消息(如 @ZirboFilip 建议的那样)。
最终的onclick 处理程序:
onclick: function(element) {
// Validate the entire form.
var valid = $('#mainForm').valid();
// Clear error message manually if appropriate.
if (valid) {
$("#validationMsg").html('');
}
}
双向依赖: required 属性非常适合单向依赖,但不适用于复选框组依赖。一个合理的规则可能是:
'type': {
required: true,
},
'numeric': {
required: '#typeNumber:checked',
}
但是,这仅表明如果选中了任何类型(数字或字符串),则需要数字类型。因此以下是有效的:
...这不是我想要的。我添加了一个自定义验证方法:
jQuery.validator.addMethod("checkDependencies", function(value, element) {
// return true if field is ok or should be ignored.
var intChecked = $('#numericInt').prop('checked');
var floatChecked = $('#numericFloat').prop('checked');
var doubleChecked = $('#numericDouble').prop('checked');
var numberChecked = $('#typeNumber').prop('checked');
var stringChecked = $('#typeString').prop('checked');
var numericTypeChecked = intChecked || floatChecked || doubleChecked;
if (!numberChecked && stringChecked) {
return !numericTypeChecked;
}
// Fall-back on built in rules for everything else.
return true;
});
在解决我的第三个要求时,我将在下面更详细地讨论这个问题。
not hack:我只有一个未被内置规则和依赖项涵盖的其他要求,即该字符串不是选择int,float或double时的有效类型.我在自定义规则中对此进行了编码(上面的代码)。相关代码重复如下:
if (!numberChecked && stringChecked) {
return !numericTypeChecked;
}
// Fall-back on built in rules for everything else.
return true;
但是,在此检查之后,我返回 true。虽然在同一规则中编写其他组合很诱人,但通过返回 true,我继续使用 required 规则,即:
'numeric': {
required: '#typeNumber:checked',
}
最终的 JSFiddler:https://jsfiddle.net/bmg2dcha/1/
【问题讨论】:
-
提交时可以同时勾选“Number”和“String”还是只勾选1个?
-
两者都应该被允许。
标签: javascript jquery jquery-validate