其实我自己也就能简单用用js而已,但是呢,相对很多初学者来说多懂了点,所以斗胆孟浪一下,将一些所得记录下来,以供更多的初学者能够知道一个东西的实现过程,省去在源码里摸索的过程。
在表单程序中,在页面上需要很多的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 } 8 |
关于验证器对象我们在后面来讨论,接下来我们扩展这个类,加入validate方法
1 Field.prototype.validate=function(){ 2 //循环每一个验证器 3 for(item in this.validators){ 4 //给验证器附加验证成功和验证失败的回调事件 5 this.set_callback(this.validatorsitem); 6 //执行验证器上的Validate方法,验证是否符合规则 7 if(!this.validatorsitem.validate(this.data())){ 8 break; //一旦任意一个验证器失败就停止 9 } 10 } 11 } |
再加入一个获取字段值的方法:
1 //获取字段值的方法 2 Field.prototype.data=http://www.chinaz.com/Design/Pages/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 } |