其實我自己也就能簡單用用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.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();