jqeury validate 相同name值的解决办法
2016-04-14 21:55
495 查看
前一段时间学习了jquery validate 的使用,还满心欢喜的觉得以后终于可以规范化的去写表单验证了。不然,碰到使用validate 检查相同name 值的问题着实难到我了。
juqery validate 自打设计之初就没想着能够验证表单中多个name 值相同的字段,以至于连官方源码中都有这么一句:
Select only the first element for each name, and only those with rules specified
找了半天bug的我此时的心是崩溃的,但是也只能不断找解决办法(得亏我有一颗作死的心)。
经过资料的查阅和源码的解读,这段代码是这样的(位于源码的615-643):
其中有这么一句:
name等于当前元素的name属性,然后再看会发现底部的rulesCache 是一个缓存,采用一个闭包的形式长驻内存。
再回到这个判断,如果当前name已经存在rulesCache 中,则直接返回false,就跳过不检查了。总算是明白那句它头上那行注释的原因了。
那么,接下来的问题就是:怎么解决它?
其实就是把这一句
改成:
优先使用id 来赋值name 就行了。
以为这就完了?还是太天真。到了这一步,成功了一大半,但是并不完美。插件已经能够检测相同name 表单字段,但是,默认的表单聚焦永远都只会出现在相同name 字段的第一个。抓狂啊啊啊。或许你会想直接丢弃表单聚焦,但是我就不!继续跟你作!
再看文档会发现validate 有个配置参数showErrors,通过赋值一个函数来决定检测到表单错误的提示:
稍微解释一下,函数的两个参数,errorMap是每个对应错误表单字段的提示信息数组,errorList 是带有字段dom值和其他一些信息的数组。所以这里就直接通过取出errorList 中的第一个数据的dom对象,聚焦,完事。
别着急→_→ ,其实还没完,这里外层需要一个if 来判断errorList 的长度是否为1,因为在你输入表单的过程中,validate 会不断调用这个函数,如果你不判断,就是一堆的报错信息。
大功告成,再来说一下最后那句
这句的意思就是调用插件原生的错误显示方式,当然你不喜欢可以去掉,自己随便写。
最后,希望大家在jqeury validate的坑中学到知识。顺便贴上一段不用修改源代码文件的方法:
juqery validate 自打设计之初就没想着能够验证表单中多个name 值相同的字段,以至于连官方源码中都有这么一句:
// Select only the first element for each name, and only those with rules specified if ( name in rulesCache || !validator.objectLength( $( this ).rules() ) ) { return false; }
Select only the first element for each name, and only those with rules specified
找了半天bug的我此时的心是崩溃的,但是也只能不断找解决办法(得亏我有一颗作死的心)。
经过资料的查阅和源码的解读,这段代码是这样的(位于源码的615-643):
elements: function() {
var validator = this,
rulesCache = {};
// Select all valid inputs inside the form (no submit or reset buttons)
return $( this.currentForm )
.find( "input, select, textarea, [contenteditable]" )
.not( ":submit, :reset, :image, :disabled" )
.not( this.settings.ignore )
.filter( function() {
var name = this.name || $( this ).attr( "name" ); // For contenteditable
if ( !name && validator.settings.debug && window.console ) {
console.error( "%o has no name assigned", this );
}
// Set form expando on contenteditable
if ( this.hasAttribute( "contenteditable" ) ) {
this.form = $( this ).closest( "form" )[ 0 ];
}
// Select only the first element for each name, and only those with rules specified if ( name in rulesCache || !validator.objectLength( $( this ).rules() ) ) { return false; }
rulesCache[ name ] = true;
return true;
} );
},
其中有这么一句:
var name = this.name || $( this ).attr( "name" ); // For contenteditable
name等于当前元素的name属性,然后再看会发现底部的rulesCache 是一个缓存,采用一个闭包的形式长驻内存。
// Select only the first element for each name, and only those with rules specified if ( name in rulesCache || !validator.objectLength( $( this ).rules() ) ) { return false; }
再回到这个判断,如果当前name已经存在rulesCache 中,则直接返回false,就跳过不检查了。总算是明白那句它头上那行注释的原因了。
那么,接下来的问题就是:怎么解决它?
其实就是把这一句
var name = this.name || $( this ).attr( "name" ); // For contenteditable
改成:
var name = this.id || this.name || $( this ).attr( "name" ); // For contenteditable
优先使用id 来赋值name 就行了。
以为这就完了?还是太天真。到了这一步,成功了一大半,但是并不完美。插件已经能够检测相同name 表单字段,但是,默认的表单聚焦永远都只会出现在相同name 字段的第一个。抓狂啊啊啊。或许你会想直接丢弃表单聚焦,但是我就不!继续跟你作!
再看文档会发现validate 有个配置参数showErrors,通过赋值一个函数来决定检测到表单错误的提示:
showErrors:function(errorMap,errorList) { if(errorList.length){ errorList[0].element.focus(); } this.defaultShowErrors(); },
稍微解释一下,函数的两个参数,errorMap是每个对应错误表单字段的提示信息数组,errorList 是带有字段dom值和其他一些信息的数组。所以这里就直接通过取出errorList 中的第一个数据的dom对象,聚焦,完事。
别着急→_→ ,其实还没完,这里外层需要一个if 来判断errorList 的长度是否为1,因为在你输入表单的过程中,validate 会不断调用这个函数,如果你不判断,就是一堆的报错信息。
大功告成,再来说一下最后那句
this.defaultShowErrors();
这句的意思就是调用插件原生的错误显示方式,当然你不喜欢可以去掉,自己随便写。
最后,希望大家在jqeury validate的坑中学到知识。顺便贴上一段不用修改源代码文件的方法:
if($.validator){ $.validator.prototype.elements = function () { var validator = this, rulesCache = {}; // Select all valid inputs inside the form (no submit or reset buttons) return $( this.currentForm ) .find( "input, select, textarea, [contenteditable]" ) .not( ":submit, :reset, :image, :disabled" ) .not( this.settings.ignore ) .filter( function() { var name = this.id || this.name || $( this ).attr( "name" ); // For contenteditable if ( !name && validator.settings.debug && window.console ) { console.error( "%o has no name assigned", this ); } // Set form expando on contenteditable if ( this.hasAttribute( "contenteditable" ) ) { this.form = $( this ).closest( "form" )[ 0 ]; } // Select only the first element for each name, and only those with rules specified if (name in rulesCache || !validator.objectLength( $( this ).rules() ) ) { return false; } rulesCache[ name ] = true; return true; } ); } }
相关文章推荐
- JQuery1——基础($对象,选择器,对象转换)
- JavaScript演示排序算法
- 2015-2016网页设计趋势分析 Web Design of Trends
- jQuery Ajax 跨域调用
- 移动端的长按事件
- jquery教程靠边站,一分钱不花让你免费学会jquery
- JQuery+Strusts1.x无刷新登录
- $.ajax()方法详解
- jQuery ajax - ajax() 方法
- JavaScript 各种遍历方式详解
- 数组方法汇总
- 在线用表单建立文件夹
- jQuery Html控件基本操作(日常收集整理)
- jQuery插件实现文字无缝向上滚动效果代码
- jQuery菜单插件用法实例
- JQuery 初体验(建议学习jquery)
- 基于Jquery和CSS3制作数字时钟附源码下载(CSS3篇)
- Jquery实现的table最后一行添加样式的代码
- jQuery实现向下滑出的平滑下拉菜单效果
- jQuery 练习[一] 学习jquery的准备工作