手把手教你自己写一个js表单验证框架的方法


Posted in Javascript onSeptember 14, 2010

在表单程序中,在页面上需要很多的Js代码来验证表单,每一个field是否必须填写,是否
只能是数字,是否需要ajax到远程验证,blablabla。
如果一个一个单独写势必非常的繁琐,所以我们的第一个目标就是构建一个类似DSL的东西,
用表述的语句而非控制语句来实现验证。
其次一个个单独写的话还有一个问题就是必须全部验证通过才能提交,但是单独验证会因为
这个特征而增加很多额外的控制代码,且经常会验证不全面。所以第二个目标就是能够全面
的整合整个验证的过程。
最后不能是一个无法扩展的一切写死的实现,必要的扩展性还是要的。
首先,我们需要一个能够描述对字段验证的类

function Field(params){ 
this.field_id=params.fid; //要验证的字段的ID 
this.validators=params.val; //验证器对象数组 
this.on_suc=params.suc; //当验证成功的时候执行的事件 
this.on_error=params.err; //当验证失败的时候执行的事件 
this.checked=false; //是否通过验证 
}

关于验证器对象我们在后面来讨论,接下来我们扩展这个类,加入validate方法
Field.prototype.validate=function(){ 
//循环每一个验证器 
for(item in this.validators){ 
//给验证器附加验证成功和验证失败的回调事件 
this.set_callback(this.validators[item]); 
//执行验证器上的Validate方法,验证是否符合规则 
if(!this.validators[item].validate(this.data())){ 
break; //一旦任意一个验证器失败就停止 
} 
} 
}

再加入一个获取字段值的方法:
//获取字段值的方法 
Field.prototype.data=function(){ 
return document.getElementById(this.field_id).value; 
}

设置验证器回调函数的方法set_callback如下:
Field.prototype.set_callback=function(val){ 
var self=this; //换一个名字来存储this,不然函数的闭包中会覆盖这个名字 
val.on_suc=function(){ //验证成功执行的方法 
self.checked=true; //将字段设置为验证成功 
self.on_suc(val.tips); //执行验证成功的事件 
} 
val.on_error=function(){ //验证失败的时候执行的方法 
self.checked=false; //字段设置为验证失败 
self.on_error(val.tips);//执行验证失败的事件 
} 
}

接下来我们就来看看验证器,验证器是真正执行验证过程的类,根据一般的验证过程,我们
可以将其分类成,长度验证(包括必填验证),正则表达式验证,自定义函数验证,Ajax远
程验证这几种,所以我们定义这几种验证器类,Ajax远程验证为了方便引用了jQuery,其他
部分也有用到:

//长度验证的验证器类 
function Len_val(min_l,max_l,tip){ 
this.min_v=min_l; 
this.max_v=max_l; 
this.tips=tip; 
this.on_suc=null; 
this.on_error=null; 
} 
Len_val.prototype.validate=function(fd){ 
if(fd.length<this.min_v||fd.length>this.max_v){ 
this.on_error(); 
return false; 
} 
this.on_suc(); 
return true; 
} 
//正则表达式验证器 
function Exp_val(expresion,tip){ 
this.exps=expresion; 
this.tips=tip; 
this.on_suc=null; 
this.on_error=null; 
} 
Exp_val.prototype.validate=function(fd){ 
if(!fd){ 
this.on_suc(); 
return true; 
} 
if(this.exps.test(fd)){ 
this.on_suc(); 
return true; 
}else{ 
this.on_error(); 
return false; 
} 
} 
//远程验证器 
function Remote_val(url,tip){ 
this.p_url=url; 
this.tips=tip; 
this.on_suc=null; 
this.on_error=null; 
} 
Remote_val.prototype.validate=function(fd){ 
var self=this; 
$.post(this.p_url,{f:fd}, 
function(data){ 
if(data.rs){ 
self.on_suc(); 
return; 
}else{ 
self.on_error(); 
} 
},"json" 
); 
return false; 
} 
//自定义函数验证器 
function Man_val(tip,func){ 
this.tips=tip; 
this.val_func=func; 
this.on_suc=null; 
this.on_error=null; 
} 
Man_val.prototype.validate=function(fd){ 
if(this.val_func(fd)){ 
this.on_suc(); 
}else{ 
this.on_error(); 
} 
}

最后我们用一个userform的类来做一个入口,在构造的时候传入Field对象的列表,并且将
每一个控件的onblur事件绑定到validate的包装器上
function UserForm(items){ 
this.f_item=items; //把字段验证对象数组复制给属性 
for(idx=0;idx<this.f_item.length;idx++){ //循环数组 
var fc=this.get_check(this.f_item[idx]); //获取封装后的回调事件 
$("#"+this.f_item[idx].field_id).blur(fc); //绑定到控件上 
} 
} 
//绑定验证事件的处理器,为了避开循环对闭包的影响 
UserForm.prototype.get_check=function(v){ 
return function(){ //返回包装了调用validate方法的事件 
v.validate(); 
} 
}

接下来需要定义一个方法来绑定提交按钮的onclick事件:
//绑定提交事件到元件 
UserForm.prototype.set_submit=function(bid,bind){ 
var self=this; 
$("#"+bid).click( 
function(){ 
if(self.validate()){ 
bind(); 
} 
} 
); 
}

这里提到了一个UserForm的validate方法,如下:
//验证所有的字段 
UserForm.prototype.validate=function(){ 
for(idx in this.f_item){ //循环每一个验证器 
this.f_item[idx].validate(); //再检测一遍 
if(!this.f_item[idx].checked){ 
return false; //如果错误就返回失败,阻止提交 
} 
} 
return true; //一个都没错就返回成功执行提交 
}

最后用一个例子来看看怎么用:

<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 
<title>test</title> 
<script type="text/javascript" src="jquery-1.4.2.min.js"></script> 
<script type="text/javascript" src="kernel.js"></script> 
<script type="text/javascript"> 
var form; 
$( 
function(){ 
var uf=new UserForm([new Field({ 
fid:"f1", 
val:[new Len_val(1,5,"长度错误"),new Exp_val(v_int,"不是数字")], 
suc:function(text){ 
$('t1').val(''); 
$('t1').attr('class','suc'); 
}, 
err:function(text){ 
('t1').val(text); 
$('t1').attr('class','error'); 
} 
}) 
]); 
uf.set_submit( 
"bt", 
function(form){ 
alert("表单已经提交了"); 
} 
); 
} 
); 
</script> 
<style> 
.suc { background-color:#00ff00;} 
.error { background-color:#ff0000;} 
</style> 
</head> 
<body> 
<input type="text" id="f1" name="f1"/><span id="t1"></span><br/> 
<input type="button" id="bt" value="提交"/> 
</body> 
</html>

要注意的地方就是在循环中使用闭包会茶几,必须用一个方法来代理一下,呵呵

希望对初学js但是还不知道该做点什么怎么做的朋友能有所帮助

Javascript 相关文章推荐
字符串的replace方法应用浅析
Dec 06 Javascript
JavaScript String.replace函数参数实例说明
Jun 06 Javascript
Jquery代码实现图片轮播效果(一)
Aug 12 Javascript
完美解决IE不支持Data.parse()的问题
Nov 24 Javascript
js 原型对象和原型链理解
Feb 09 Javascript
基于angular实现三级联动的生日插件
May 12 Javascript
vue与vue-i18n结合实现后台数据的多语言切换方法
Mar 08 Javascript
vue非父子组件通信问题及解决方法
Jun 11 Javascript
基于elementUI实现图片预览组件的示例代码
Mar 31 Javascript
利用Bootstrap Multiselect实现下拉框多选功能
Apr 08 Javascript
Node.js之删除文件夹(含递归删除)代码实例
Sep 09 Javascript
Node.js实现批量下载图片简单操作示例
Jan 18 Javascript
(jQuery,mootools,dojo)使用适合自己的编程别名命名
Sep 14 #Javascript
修改jquery里的dialog对话框插件为框架页(iframe) 的方法
Sep 14 #Javascript
基于jquery的划词搜索实现(备忘)
Sep 14 #Javascript
基于jquery的页面划词搜索JS
Sep 14 #Javascript
基于Jquery的实现回车键Enter切换焦点
Sep 14 #Javascript
js输出列表实现代码
Sep 12 #Javascript
JavaScript日历实现代码
Sep 12 #Javascript
You might like
在PHP的图形函数中显示汉字
2006/10/09 PHP
PHP里的中文变量说明
2011/07/23 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(四)
2014/06/23 PHP
Linux下从零开始安装配置Nginx服务器+PHP开发环境
2015/12/21 PHP
PHP实现的简单sha1加密功能示例
2017/08/27 PHP
js jquery做的图片连续滚动代码
2008/01/06 Javascript
JavaScript URL参数读取改进版
2009/01/16 Javascript
Jquery颜色选择器ColorPicker实现代码
2012/11/14 Javascript
javascript中强制执行toString()具体实现
2013/04/27 Javascript
jquery中获取id值方法小结
2013/09/22 Javascript
jquery对table中各数据的增加、保存、删除操作示例
2014/05/14 Javascript
jquery的clone方法应用于textarea和select的bug修复
2014/06/26 Javascript
45个JavaScript编程注意事项、技巧大全
2015/02/11 Javascript
jQuery实现瀑布流布局详解(PC和移动端)
2020/09/01 Javascript
浅谈js内置对象Math的属性和方法(推荐)
2016/09/19 Javascript
JavaScript简单验证表单空值及邮箱格式的方法
2017/01/20 Javascript
vue2.0结合Element实现select动态控制input禁用实例
2017/05/12 Javascript
jQuery模拟实现天猫购物车动画效果实例代码
2017/05/25 jQuery
Textarea输入字数限制实例(兼容iOS&amp;安卓)
2017/07/06 Javascript
React学习之事件绑定的几种方法对比
2017/09/24 Javascript
vue 父组件调用子组件方法及事件
2018/03/29 Javascript
vue-router实现编程式导航的代码实例
2019/01/19 Javascript
JavaScript forEach中return失效问题解决方案
2020/06/01 Javascript
在Python中处理列表之reverse()方法的使用教程
2015/05/21 Python
python简单实现计算过期时间的方法
2015/06/09 Python
python实现简易数码时钟
2021/02/19 Python
Python数据类型之Tuple元组实例详解
2019/05/08 Python
k-means 聚类算法与Python实现代码
2020/06/01 Python
澳大利亚拥有最好的家具和家居用品在线目的地:Nestz
2019/02/23 全球购物
交通事故协议书
2014/04/15 职场文书
考博专家推荐信
2014/05/10 职场文书
诚实守信演讲稿
2014/09/01 职场文书
材料物理专业求职信
2014/09/01 职场文书
个人党性分析材料
2014/12/19 职场文书
2015年爱牙日活动总结
2015/02/05 职场文书
个人催款函范文
2015/06/24 职场文书