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

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

其实我自己也就能简单用用js而已,但是呢,相对很多初学者来说多懂了点Know How所以斗
胆孟浪一下,将一些所得记录下来,以供更多的初学者能够知道一个东西的实现过程,省去
在源码里摸索的过程。
在表单程序中,在页面上需要很多的Js代码来验证表单,每一个field是否必须填写,是否
只能是数字,是否需要ajax到远程验证,blablabla。
如果一个一个单独写势必非常的繁琐,所以我们的第一个目标就是构建一个类似DSL的东西,
用表述的语句而非控制语句来实现验证。
其次一个个单独写的话还有一个问题就是必须全部验证通过才能提交,但是单独验证会因为
这个特征而增加很多额外的控制代码,且经常会验证不全面。所以第二个目标就是能够全面
的整合整个验证的过程。
最后不能是一个无法扩展的一切写死的实现,必要的扩展性还是要的。
首先,我们需要一个能够描述对字段验证的类
代码
1  function  Field(params){
2       this .field_id = params.fid;      // 要验证的字段的ID
3       this .validators = params.val;    // 验证器对象数组
4       this .on_suc = params.suc;        // 当验证成功的时候执行的事件
5       this .on_error = params.err;      // 当验证失败的时候执行的事件
6       this .checked = false ;            // 是否通过验证
7  }

 

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

 

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

 

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

 

接下来我们就来看看验证器,验证器是真正执行验证过程的类,根据一般的验证过程,我们
可以将其分类成,长度验证(包括必填验证),正则表达式验证,自定义函数验证,Ajax远
程验证这几种,所以我们定义这几种验证器类,Ajax远程验证为了方便引用了jQuery,其他
部分也有用到:
代码
 1 
 2  // 长度验证的验证器类
 3  function  Len_val(min_l,max_l,tip){
 4       this .min_v = min_l;
 5       this .max_v = max_l;
 6       this .tips = tip;
 7       this .on_suc = null ;
 8       this .on_error = null ;
 9  }
10  Len_val.prototype.validate = function (fd){
11       if (fd.length < this .min_v || fd.length > this .max_v){
12           this .on_error();
13           return   false ;
14      }
15       this .on_suc();
16       return   true ;
17  }
18  // 正则表达式验证器
19  function  Exp_val(expresion,tip){
20       this .exps = expresion;
21       this .tips = tip;
22       this .on_suc = null ;
23       this .on_error = null ;
24  }
25  Exp_val.prototype.validate = function (fd){
26       if ( ! fd){
27           this .on_suc();
28           return   true ;
29      }
30       if ( this .exps.test(fd)){
31           this .on_suc();
32           return   true ;
33      } else {
34           this .on_error();
35           return   false ;
36      }
37  }
38  // 远程验证器
39  function  Remote_val(url,tip){
40       this .p_url = url;
41       this .tips = tip;
42       this .on_suc = null ;
43       this .on_error = null ;
44  }
45  Remote_val.prototype.validate = function (fd){
46       var  self = this ;
47      $.post( this .p_url,{f:fd},
48           function (data){
49               if (data.rs){
50                  self.on_suc();
51                   return ;
52              } else {
53                  self.on_error();
54              }
55          }, " json "
56      );
57       return   false ;
58  }
59  // 自定义函数验证器
60  function  Man_val(tip,func){
61       this .tips = tip;
62       this .val_func = func;
63       this .on_suc = null ;
64       this .on_error = null ;
65  }
66  Man_val.prototype.validate = function (fd){
67       if ( this .val_func(fd)){
68           this .on_suc();
69      } else {
70           this .on_error();
71      }
72  }

 

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

 

接下来需要定义一个方法来绑定提交按钮的onclick事件:
代码
 1  // 绑定提交事件到元件
 2  UserForm.prototype.set_submit = function (bid,bind){
 3       var  self = this ;
 4      $( " # " + bid).click(
 5           function (){
 6               if (self.validate()){
 7                  bind();
 8              }
 9          }
10      );
11  }

 

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

 

最后用一个例子来看看怎么用:
代码
 1  < html >
 2  < head >
 3  < meta  http-equiv ="Content-Type"  content ="text/html; charset=utf-8" />
 4  < title > test </ title >
 5  < script  type ="text/javascript"  src ="jquery-1.4.2.min.js" ></ script >
 6  < script  type ="text/javascript"  src ="kernel.js" ></ script >
 7  < script  type ="text/javascript" >
 8  var  form;
 9  $(
10  function (){
11       var  uf = new  UserForm([ new  Field({
12              fid: " f1 " ,
13              val:[ new  Len_val( 1 , 5 , " 长度错误 " ), new  Exp_val(v_int, " 不是数字 " )],
14              suc: function (text){
15                  $( ' t1 ' ).val( '' );
16                  $( ' t1 ' ).attr( ' class ' , ' suc ' );
17              },
18              err: function (text){
19                  ( ' t1 ' ).val(text);
20                  $( ' t1 ' ).attr( ' class ' , ' error ' );
21              }
22          })
23      ]);
24      uf.set_submit(
25           " bt " ,
26           function (form){
27              alert( " 表单已经提交了 " );
28          }
29      );
30  }
31  );
32  </ script >
33  < style >
34  .suc  {  background-color : #00ff00 ; }
35  .error  {  background-color : #ff0000 ; }
36  </ style >
37  </ head >
38  < body >
39  < input  type ="text"  id ="f1"  name ="f1" />< span  id ="t1" ></ span >< br />
40  < input  type ="button"  id ="bt"  value ="提交" />
41  </ body >
42  </ html >

JSValidation是强大灵活的客户端验证框架。在应用服务器或者开发框架不提供验证的情况下,例如,普通的JSP, ASP, PHP等开发,以及一些不提供验证支持的开发框架,如Tapestry, Velocity等,JSValidation提供了一种灵活的解决方案。与其他验证方式相比,它最大的优点在于独立与易于集成。纯JavaScript结构,可以很容易的集成到现有的应用中而不论现有的应用是基于什么语言。将所有的表单验证集中管理,使得维护应用更加容易。简便的XML配置,易于扩充的验证方式(目前支持13种验证,囊括了大部分常用表单验证),使得JSValidation成为验证框架的首选。 <br>1. JSValidation是什么?<br>如首页所说,JSValidation是客户端表单验证框架,用在BS系统中,或者简单的网页系统中。表单验证在这些开发中很常见:新用户注册,需要校验某些字段;用户登陆,需要校验;等等。在这之前,页面开发者(JavaScript开发者)需要编大量的JavaScript来与表单对象交互,并进行校验。常见的校验如不能为空,必须满足长度要求,必须为数字,必须为Email等等。根据一般的经验,如果表单中需要校验的域个数超过10个,开发过程就显得枯燥无味——多段重复的代码不断重复,如果要求跨浏览器,更多的考虑因素使人头疼不已。往往这个页面的验证还不能用于那个验证……虽然逻辑基本相同;但是在大多数情况下,出于种种原因,开发者宁愿(或者没办法)重新编一个页面的JavaScript代码。<br><br>JSValidation致力于改善这一过程。它将常见的校验(目前支持13种)封装起来,并创造性的采用xml来存贮表单验证信息,使得表单的验证成为整个项目中最不重要的环节,开发者只需要定义几个xml标记,就可以创建出复杂的验证策略,而不用编一行JavaScript代码。由于采用xml集中管理表单验证,使得表单验证在整个系统中的耦合度大大降低,并且易维护性大大提高。开发者更多的精力可以投入到业务相关的代码中。<br><br>恰恰相反,JSValidation内部结构虽然不太简单(对用户而言),但是调用方式却极其简单,配置好环境后,只需要在需要验证的表单的HTML标记中加上onsubmit="return doValidate('formId')"即可。这并没有改变开发者的习惯。<br><br>更为明显的优势是,JSValidation具备跨浏览器的能力。在目前的测试环境下,支持IE5及以上版本,Mozilla系列和支持DOM2模型的其他浏览器。你不用再考虑在多浏览器下如何兼容,JSValidation帮你做到了这些。<br><br>2. JSValidation能做什么,不能做什么?<br>如上所述,JSValidation能够校验表单。在系统复杂,表单复杂的场景下,JSValidation的优势更加突出。JSValidation目前能够完成客户端的13种验证如下:<br><br>取值非空 <br>必须为整数 <br>必须为双精度数 <br>必须为普通英文字符(字母,数字,下划线) <br>必须为中文字符 <br>最小长度 <br>最大长度 <br>是否为Email格式 <br>是否为日期格式(yyyy-mm-dd) <br>自定义的正则表达式 <br>整数范围(大于某数小于某数) <br>双精度数范围 <br>必须与某个域的值相同 <br>所有这些验证都在客户端完成。如果还有在此之外的验证需求,请告诉我们,我们会跟据需求程度开发出新的验证模型。<br><br>JSValidation不能做的:<br><br>跨页面的验证。例如,A页面输入值,必须满足B页面中某一个值的条件,或者更多的页面。这个需求需要用户的反馈。如果在现实开发中这种需求很普遍,我们会考虑开发。目前的替代方式是,将A页面需要验证的值POST到B页面的一个Hidden Field,然后再使用已有的验证方式。 <br>与服务器交互验证。最常见的是输入用户名密码后登录。限于它的表示范围,JSValidation不能完成这个工作。 <br>其他没有提到的,很希望你能告诉我们。 <br><br>请大家帮忙顶,这么好的东东不能叫他沉了啊<br>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值