attach: form = this; var options; if(userOptions) options = methods._saveOptions(form, userOptions); else options = form.data('jqv');options.validateAttribute = (form.find("[data-validation-engine*=validate]").length) ? "data-validation-engine" : "class"; if (options.binded) { form.on(options.validationEventTrigger, "["+options.validateAttribute+"*=validate]:not([type=checkbox]):not([type=radio]):not(.datepicker)", methods._onFieldEvent); form.on("click", "["+options.validateAttribute+"*=validate][type=checkbox],["+options.validateAttribute+"*=validate][type=radio]", methods._onFieldEvent); form.on(options.validationEventTrigger,"["+options.validateAttribute+"*=validate][class*=datepicker]", {"delay": 300}, methods._onFieldEvent); } if (options.autoPositionUpdate) { $(window).bind("resize", { "noAnimation": true, "formElem": form }, methods.updatePromptsPosition); } //为拥有data-validation-engine-skip属性的a标签和button,input标签,类拥有validate-skip字段的a标签和button,input标签绑定click事件。 form.on("click","a[data-validation-engine-skip], a[class*='validate-skip'], button[data-validation-engine-skip], button[class*='validate-skip'], input[data-validation-engine-skip], input[class*='validate-skip']", methods._submitButtonClick); form.removeData('jqv_submitButton');form.on("submit", methods._onSubmitEvent);; }
绑定了基本上控件的触发事件,这里还要提到的是在我们提交form的时候,会触发插件内容的submit的监听事件,实际上插件会在你提交之前再去帮你检查一遍控件。如果全满足条件了,则将会提交。可以看到很多的控件基本上绑定触发的事件都是method._onFieldEvent方法
这里我们拿_onFieldEvent来看一下。
_onFieldEvent: function(event) { var field = $(this); options = form.data('jqv');//读取jqv属性信息 options.eventTrigger = "field"; // validate the current field window.setTimeout(function() { methods._validateField(field, options); if (options.InvalidFields.length == 0 && options.onFieldSuccess) { options.onFieldSuccess(); } else if (options.InvalidFields.length > 0 && options.onFieldFailure) { options.onFieldFailure(); } }, (event.data) ? event.data.delay : 0); }
将执行函数放入setTimeout中,这里考虑到一个datepicker插件的问题。
这里_validateField的全部代码就不贴了,分析一下里面几块重要的部分
getRules = /validate\[(.*)\]/.exec(rulesParsing);(!getRules) str = getRules[1];rules = str.split(/\[|,|\]/);(var i = 0; i < rules.length; i++) { rules[i] = rules[i].replace(" ", "");(rules[i] === '') { delete rules[i];//删除空的规则 } }
这里是对rules的解析,将原来的例子修改一下
这里为什么不直接写validate[required,email],或者是validate[required,xx[email]](xx不是custom)了?带着这些疑问,我们来看一下源码。
源码中getRules使用的是exec来获取匹配的结果文本,这里的匹配结果是[validate[reuqired,custom[email]] text-input,required,custom[email]]。再看str,它的值为required,custom[email],再经过split分隔,rule将变为[required,custom,email,''],最后经过for循环遍历将将空字符串的成员delete掉,最后结果是[required,custom,email,undefined]。至于为什么要加这个custom,不急,我们慢慢看。
其实这个插件将控件需要执行的验证规则都写在了class类中,也就是说我们在validate[]中写了一些规则,那么控件将会执行这些规则,其实required则表示为必填,email则表示为输入email格式。两者必须同时满足。
源码下面会再经历一次for循环,但是注意,这里多了一个switch判断,将rules中有的规则一一过滤出来,执行相应的方法。如果你留心看一下这个switch,你就会发现,这里面根本没有email的选择类型,所以说你直接在页面上写成validate[required,email]是不会有效果的。我们可以看到有custom的判断。进入看一下这个custom,到底是什么
case "custom": errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._custom); break;
_getErrorMessage这个方法说白了,就是获取错误信息,执行传入的回相对应的调函数