在上一篇"ASP.NET MVC异步验证是如何工作的02,异步验证表单元素的创建"中了解了ASP.NET异步验证是如何创建表单元素的,本篇体验jquery.validate.unobtrusive.js
异步验证的全过程。
在jquery.validate.unobtrusive.js
文件的尾部看到了如下的一个调用:
$(function () {
$jQval.unobtrusive.parse(document);
});
可见,通过把当前页的document对象传给$jQval.unobtrusive.parse
方法,使该页的表单元素能被异步验证。parse方法的主要作用是对所有的表单进行异步验证。
{
parse: function (selector) {
$(selector).find(":input[data-val=true]").each(function () {
$jQval.unobtrusive.parseElement(this, true);
});
var $forms = $(selector)
.parents("form")
.andSelf()
.add($(selector).find("form"))
.filter("form");
$forms.each(function () {
var info = validationInfo(this);
if (info) {
info.attachValidation();
}
});
}
}
以上,首先遍历data-val=true
的input元素,调用$jQval.unobtrusive.parseElement
方法,把存在于html元素中的、有关异步验证的信息抓取出来封装成jquery.validate.unobtrusive.js
能识别的元数据。$jQval.unobtrusive.parseElement
方法的第一个参数表示被验证的表单元素。第二个参数为true时,表示跳过对表单元素的验证,如果只验证一个元素就设置成true,如果验证多个元素就设置成false,默认为false。
在validationInfo
这个对象中,包含了异步验证所需要的一切信息,当调用attachValidation
方法的时候,就会把封装在validationInfo
对象中的所有验证规则传给validate
方法。
有关validationInfo
的细节:
data_validation = "unobtrusiveValidation";
function validationInfo(form) {
var $form = $(form),
result = $form.data(data_validation),
onResetProxy = $.proxy(onReset, form);
if (!result) {
result = {
options: { // options structure passed to jQuery Validate's validate() method
errorClass: "input-validation-error",
errorElement: "span",
errorPlacement: $.proxy(onError, form),
invalidHandler: $.proxy(onErrors, form),
messages: {},
rules: {},
success: $.proxy(onSuccess, form)
},
attachValidation: function () {
$form
.unbind("reset." + data_validation, onResetProxy)
.bind("reset." + data_validation, onResetProxy)
.validate(this.options);
},
validate: function () { // a validation function that is called by unobtrusive Ajax
$form.validate();
return $form.valid();
}
};
$form.data(data_validation, result);
}
return result;
}
以上,在validationInfo
的构造函数中,通过$form.data
方法,可以获取或设置unobtrusiveValidation
的值。在unobtrusiveValidation
这个对象中,包含了异步验证所需要的信息:
1、名为options
的json对象,包含了验证规则、错误信息等。
2、attachValidation
方法用来给form绑定自定义事件,每次调用或解除reset.unobtrusiveValidation
方法都会调用onReset
方法。
function onReset(event) { // 'this' is the form element
var $form = $(this);
$form.data("validator").resetForm();
$form.find(".control-group").removeClass("error");
$form.find(".validation-summary-errors")
.addClass("validation-summary-valid")
.removeClass("validation-summary-errors");
$form.find(".field-validation-error")
.addClass("field-validation-valid")
.removeClass("field-validation-error")
.removeData("unobtrusiveContainer")
.find(">*") // If we were using valmsg-replace, get the underlying error
.removeData("unobtrusiveContainer");
}
3、validate
表示可以自定义验证事件。
而在把validationInfo
对象中的所有验证规则传给validate
方法的时候,真正起作用的是$.validator.unobtrusive.adapters
,这样html中以data-*
开头的才能被validate
方法读懂。如果需要自定义异步验证规则,需要通过jQuery.validator.unobtrusive.adapters.add(adapterName, [params], function(element, form, message, params, rules,messages){})
方法来实现。
其中,adapterName
与data-val-ruleName
中的ruleName
匹配。通过adapter可以扩展如下:
jQuery.validator.unobtrusive.adapters.addBool(adapterName, [ruleName]);
jQuery.validator.unobtrusive.adapters.addSingleVal(adapterName, attribute, [ruleName]);
jQuery.validator.unobtrusive.adapters.addMinMax(adapterName, minRuleName, maxRuleName, minMaxRuleName, [minAttribute, [maxAttribute]]);