2012年11月18日 星期日

Validation-Engine研究



以前在使用者輸入的TextBox我們要進行資料檢測,我都使用ASP.NETRequiredFieldValidator,但一直以來感覺他的效果不是很好,因為複雜一點的規則,基本上還是自己要去寫Javascript,再來是當使用者輸入錯誤時出現提示訊息時,出現的文字會去擠壓原本的表格,這次因為要檢測使用者輸入是否為數字,想說找一下JQuery的作法,找的過程中發現有JQuery.Valdation,突然想到之前有聽過JQuery有整套的驗證機制,找了一下看到黑暗執行緒大介紹了一套Validation-Engine,看了一下效果感覺真的很不錯,因此決定來研究一下

一開始因為不曉得怎麼使用,而且看到不同的範例用的Validation-Engine都是不同版本且差異頗大,因此花了不少時間去找這個元件能夠Run起來,走了不少冤望路,主要只要以下幾個檔案就能夠執行(有時候直接去看作者原始碼比較快)
validationEngine.jquery.css
有兩種,一種為紅色系,一種為黑色系,個人覺得紅色比較好看
jquery.validationEngine-zh_TW.js
語言檔,判斷資料正確與否的正則表達式也是寫在這裡
jquery.validationEngine.js
元件主程式

知道了如何使用後再來就是測試自己所需要的功能,測試的過程中碰到一些問題記錄如下:
原本在1.7.2的版本中提供了驗證長度的方法,但在最新的2.6.1中不支援這個方法,不太明白為什麼作者將這個方法移除,照理說這個應該非常常用
所以只能夠用自訂Function

Function的寫法可以參考以下,但我尚未測試過
方法一
1、注:調整一個漢字字符長度為2,一個英文字符長度為1 
for (var i = 0; i < val.length; i++)  
 { 
   len = len + ((val.charCodeAt(i) >= 0x4e00 && val.charCodeAt(i) <= 0x9fa5) ? 2 : 1);  
 } 
2validationEngine 字符長度問題(漢字字符,英文字符長度) 
var len = field.val().length;替換為
var len = 0; 
var val = field.val(); 
for (var i = 0; i < val.length; i++)  
{ 
len = len + ((val.charCodeAt(i) >= 0x4e00 && val.charCodeAt(i) <= 0x9fa5) ? 2 : 1);  
} 

方法二
function checkDate(oTextbox) {
var regex = new RegExp("^(?:(?:([0-9]{4}(-|\/)(?:(?:0?[1,3-9]|1[0-2])(-|\/)(?:29|30)|((?:0?[13578]|1[02])(-|\/)31)))|([0-9]{4}(-|\/)(?:0?[1-9]|1[0-2])(-|\/)(?:0?[1-9]|1\\d|2[0-8]))|(((?:(\\d\\d(?:0[48]|[2468][048]|[13579][26]))|(?:0[48]00|[2468][048]00|[13579][26]00))(-|\/)0?2(-|\/)29))))$");
if (!regex.test(oTextbox)) {
return false;
}
return true;
}
方法三Client Side and Server Side
http://www.eion.com.tw/Blogger/?Pid=1047

再來是日期輸入的驗證,元件中預設的驗證日期的正則表達式其實不太能夠真的將各種狀況擋住,我搜尋了網路上的很多方法進行測試,效果都不好,無法完全處理各種狀況,最後是用一種偷懶的方式,就是在TextBox上設定一個日期元件讓使用者日期只能用選的,但從Framework 2.0後,當我們將TextBox設定為唯讀,則程式是無法存取到該TextBox的值,因此這邊要繞個彎,在TextBox設定OnBlurreturn掉使用者企圖在輸入視窗上做任何事

最後是ajax驗證
一開始就碰到問題,因為作者網站的範例不能跑,而範例中是用php寫的我無法觀察要回傳什麼json的值給元件接,如果你直接去跑作者ajax驗證那頁會發現,那一頁傳回的是空值,所以當然無法正常運作,因此找了幾個人家做好的範例參考
單純的流氓那篇算是寫得相當清楚,不過裡面有誤解了原作者的地方,就是他請大家去改原作者的元件,因為我不太相信這個元件這麼久了會有需要去改元件才能使用的問題,因此決定查個清楚,還好在RIA之家的範例是可以跑的
這邊是以2.2版的做範例,我比對過跟2.6.1要做驗證的地方一模一樣,因此我想如果他能夠正常運作,那麼他回傳的json值也一定是正確,所以我手動的去跑他ajax驗證那頁(還好可以看到程式碼)
果然他有正常傳回值,如下:
["user",true]
這樣我們就知道自己所寫的後端驗證要傳回什麼值了,因此事實上是不需要修改原作者元件的。
註:
這邊可以有三個參數
["user",true,”請輸入123”]
第一個參數為TextBoxid名稱,第二個參數為驗證成功或失敗,第三個參數則是要給使用者看到什麼訊息

以下是ajax呼叫所需要的一些參數
"ajaxTest":{
"url":"webservice.asmx/Vaildate",
"extraData":"extraData=xxx",
"alertTextOk":"*ok",
"alertText":"*fail",
"alertTextLoad":"*正在確認,請稍等。"
說明一下extraData的作用為用get的方式去傳回後端當作參數使用

作者在js\languages裡提供了各種語系檔,連中文都有,不過可以多利用jquery.validationEngine-zh_TW.js去作搜尋人家已經做好的各式驗證
要如何動態挑選適合使用者的語系,可以參考以下
http://pramaire.pixnet.net/blog/post/45322227-jquery%E5%8F%96%E7%B6%B2%E9%A0%81url%E5%8F%83%E6%95%B8-%26-%E5%8B%95%E6%85%8B%E8%BC%89%E5%85%A5js%E6%AA%94

最後,因為之前都是使用post的方式去送參數到後端,所以一送出資料以後就出現「無法辨認要求格式,因為URL 未預期地以{0} 結束。」,查了一下發現在這邊
type: options.ajaxFormValidationMethod,
ajaxFormValidationMethod定義為使用get的方式
ajaxFormValidationMethod: 'get',
因此我手動將元件改為post是可以正常運作的,因此查了一下發現預設的get是關閉的,因此程式無法運作,所以將以下這段加入web.config就正常了
   
       
       
   
如果要關閉這兩個服務的話,則加入以下這段
 
   
   
 

這裡稍微深入的研究一下
   
       
       
   

似乎可以只讓localhost呼叫
似乎可以只讓某些服務才有作用

也有看到像下面的寫法
 
   
     
       
       
     
   
 
但這些就要再找時間仔細測試了

參考網址
謙卑式jQuery檢核-動態訊息
Validation-Engine介紹
NuGet程式包-改良ASP.NET MVC驗證訊息顯示
使用jQuery.validate.unobtrusive.js
Example of Using JQuery Validation Engine Plugin with ASP.NET Controls
Validation-Engine討論區
Validation-Engine作者網站
jQuery inline form validation Engine
jquery.validationEngine ajax驗證 不通過也提交表單
jQuery Validation Engine的表單驗證與字段ajax驗證

關鍵字
jquery 檢查數字
jquery.validate.unobtrusive.js
jquery.validate.inline
validationEngine.jquery.css
validation engine length
validation engine "asp.net" ashx
validationEngine ajax
無法辨認要求格式,因為 URL 未預期地以 結束
web.config web Services protocols

日期正則表達式
正則 "yyyy/mm/dd"
一些正則表達式的參考,只有測試過日期的部分,都不太能用
http://mengqingyu.iteye.com/blog/426454

沒有留言:

張貼留言