jQuery Validation是一个非常优秀的前端验证插件,默认支持多种常用的验证规则,如非空,范围,最大(小)值等等,设定规则的方式也是灵活多样。下面通过分析1.12.0的源代码进行深度解析。
1. 设定验证规则的方式
jQuery Validation支持多种设定验证规则的方式
1) classRules
通过在元素的class 上设定验证规则
<tr>
<td class="label"><label for="password1">Password:</label></td>
<td class="field">
<input id="password1" class="required password" maxlength="40" name="password1" size="20" type="password" tabindex="12" value="" />
</td>
</tr>
2) attributeRules
直接在元素上使用验证规则的名称
<p>
<label for="phone">Phone</label>
<input id="phone" name="phone" required type="number" rangelength="[2,8]">
</p>
3) dataRules
使用html5 data-*自定义属性。关于html5自定义属性的小知识如下:
1. 通过代码读取或者设置自定义属性的时候需要去掉前缀data-*。 比如自定义属性是data-location-code, 则js设值代码为:
element.dataset.locationCode = 'BJ';
但如果在CSS中使用选择器,需要全名,如:
<style type="text/css"> [data-location-code] {color: red;} </style>
2. 如果属性名称中除了data-外,还包含连字符(-),则需要转成驼峰命名方式。见上面例子。
言归正传,jQuery Validation的设置方式如下: <label for="cemail">E-Mail *</label>
<input id="cemail" name="email" data-rule-required="true" data-rule-email="true" data-msg-required="Please enter your email address" data-msg-email="Please enter a valid email address" />
4) staticRules
初始化Validator的时候,通过参数设定的规则
// validate signup form on keyup and submit
$("#signupForm").validate({
rules: {
firstname: "required",
lastname: "required",
username: {
required: true,
minlength: 2
},
password: {
required: true,
minlength: 5
},
confirm_password: {
required: true,
minlength: 5,
equalTo: "#password"
},
email: {
required: true,
email: true
},
topic: {
required: "#newsletter:checked",
minlength: 2
},
agree: "required"
},
messages: {
firstname: "Please enter your firstname",
lastname: "Please enter your lastname",
username: {
required: "Please enter a username",
minlength: "Your username must consist of at least 2 characters"
},
password: {
required: "Please provide a password",
minlength: "Your password must be at least 5 characters long"
},
confirm_password: {
required: "Please provide a password",
minlength: "Your password must be at least 5 characters long",
equalTo: "Please enter the same password as above"
},
email: "Please enter a valid email address",
agree: "Please accept our policy"
}
});
注意这里的firstname, lastname都是指定form里面元素的名称。
总体而言,classRules和attributeRules,前者通过污染class来设置规则,后者使用非html标准属性来设置规则, 都不是我推荐的方式。
建议大家在实际开发中使用staticRules和dataRules。
可以多种方法一起使用,最后规则会被合并,优先级是 4) > 3) > 2) > 1).
注:原来的版本如1.9 曾支持使用$.metadata插件提供的功能设置规则,新版本已经没有了。
2. 关于Validate() 函数
一个页面可以包含多个form, 加载完毕后,即可针对每个form调用validate() 进行初始化。如下面代码:
<script type="text/javascript">
$(document).ready(function () {
$("#commentForm").validate();
$("#commentForm2").validate({
messages: {
email: {
required: 'Enter this!'
}
}
});
});
</script>
这里的validate()方法并不是做实际的验证工作,只是返回一个针对当前form的验证器对象(validator)。里面主要做了哪些事情呢?
1) validate(options) 函数首先检查是否创建过 validator, 如果创建过则直接返回,否则继续新对象。
// check if a validator for this form was already created
var validator = $.data( this[0], "validator" );
if ( validator ) {
return validator;
}
validate传入的options, 会被合并到$.validator的defaults参数列表里面。因此这里可以针对form做不同的参数设定。
2) 初始化validator
最重要的一点是在form上统一监控特定类型元素的特定事件,以便激发验证。这是如何做到的呢?见代码:
function delegate(event) {
var validator = $.data(this[0].form, "validator"),
eventType = "on" + event.type.replace(/^validate/, ""),
settings = validator.settings;
if ( settings[eventType] && !this.is( settings.ignore ) ) {
settings[eventType].call(validator, this[0], event);
}
}
$(this.currentForm)
.validateDelegate(":text, [type='password'], [type='file'], select, textarea, " +
"[type='number'], [type='search'] ,[type='tel'], [type='url'], " +
"[type='email'], [type='datetime'], [type='date'], [type='month'], " +
"[type='week'], [type='time'], [type='datetime-local'], " +
"[type='range'], [type='color'] ",
"focusin focusout keyup", delegate)
.validateDelegate("[type='radio'], [type='checkbox'], select, option", "click", delegate);
if ( this.settings.invalidHandler ) {
$(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);
}
3) 对 submit行为的处理
如果设定validator.settings.onsubmit = true, 则监控form里面type=submit元素的click事件,对onSubmit, submit进行函数绑定。
jquery validator 可以通过设定在submit元素 上设定class="cancel", 来避免激发验证。
至此,验证的初始化完成。
下一篇我们来分析验证是怎样进行的。