改造jquery validator ,支持多个name相同的验证

陶淳
2023-12-01

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

            }
            }
             });
 类似资料: