在项目中经常遇到,表单可以动态追加多行。但是追加的行中,input 文本框的name会重复。如果用jquery validator ,它只支持验证第一个input,后面的name相同的input不会被验证,怎么办呐?经过研究源码,提出了解决办法。
基于jQuery Validation Plugin - v1.14.0 - 6/30/2015改造
完整版下载
在defaults默认配置中增加 duplicateValid,用户可自己配置是否开启重复name验证
$.extend($.validator, {
defaults: {
duplicateValid: false,
messages: {},
groups: {},
rules: {},
改造checkForm函数,核心思想:根据name找到多个元素,for循环一一验证
checkForm: function () {
this.prepareForm();
for (var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++) {
if (this.findByName(elements[i].name).length != undefined && this.findByName(elements[i].name).length > 1 && this.settings.duplicateValid) {
for (var cnt = 0; cnt < this.findByName(elements[i].name).length; cnt++) {
try {
this.check(this.findByName(elements[i].name)[cnt])
} catch (e) {
window.console && console.log(e)
}
}
} else {
this.check(elements[i])
}
}
return this.valid()
}
改造showLabel函数
showLabel: function (element, message) {
var place, group, errorID, error = this.errorsFor(element), elementID = this.idOrName(element),
describedBy = $(element).attr("aria-describedby");
var index = this.duplicateElementsIndex(element);
if (error.length) {
error.removeClass(this.settings.validClass).addClass(this.settings.errorClass);
error.html(message)
} else {
error = $("<" + this.settings.errorElement + ">").attr("id", elementID + "-error").addClass(this.settings.errorClass).html(message || "");
place = error;
if (this.settings.wrapper) {
place = error.hide().show().wrap("<" + this.settings.wrapper + "/>").parent()
}
if (this.labelContainer.length) {
this.labelContainer.append(place)
} else if (this.settings.errorPlacement) {
this.settings.errorPlacement(place, $(element))
} else {
place.insertAfter(element)
}
if (error.is("label")) {
var elementIDTemp = this.settings.duplicateValid ? elementID + "-" + index : elementID;
error.attr("for", elementIDTemp)
} else if (error.parents("label[for='" + elementID + "']").length === 0) {
errorID = error.attr("id").replace(/(:|\.|\[|\]|\$)/g, "\\$1");
if (!describedBy) {
describedBy = errorID
} else if (!describedBy.match(new RegExp("\\b" + errorID + "\\b"))) {
describedBy += " " + errorID
}
var describedByTemp = this.settings.duplicateValid ? describedBy + "-" + index : describedBy;
$(element).attr("aria-describedby", describedByTemp);
group = this.groups[element.name];
if (group) {
$.each(this.groups, function (name, testgroup) {
if (testgroup === group) {
$("[name='" + name + "']", this.currentForm).attr("aria-describedby", error.attr("id"))
}
})
}
}
}
if (!message && this.settings.success) {
error.text("");
if (typeof this.settings.success === "string") {
error.addClass(this.settings.success)
} else {
this.settings.success(error, element)
}
}
this.toShow = this.toShow.add(error)
}
改造errorsFor函数
errorsFor: function (element) {
var index = this.duplicateElementsIndex(element);
var name = this.idOrName(element), describer = $(element).attr("aria-describedby");
var nameTemp = this.settings.duplicateValid ? name + "-" + index : name;
var selector = "label[for='" + nameTemp + "'], label[for='" + nameTemp + "'] *";
if (describer) {
selector = selector + ", #" + describer.replace(/\s+/g, ", #")
}
return this.errors().filter(selector)
}
大功告成。
调用实例
formValidation = $("#esfyw").validate({
duplicateValid:true,//验证重复元素
errorPlacement:function(error,element) {
if(element.is("input")){
error.appendTo(element.parent().parent().parent().prev());
}else if(element.is("select")){
error.appendTo(element.parent().parent().prev());
}
} ,
submitHandler:function(form){
ajaxPost(callbackfunction , callbackFailFunction);
},
rules: {
districtCode:{
required:true
}
}
});