在项目中经常遇到,表单可以动态追加多行。但是追加的行中,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 } } });