jQuery實戰開發表單驗證與自動完成提示插件

本文是介紹兩個最經常使用的jQuery插件. 分別用於表單驗證和自動完成提示(相似google suggest).javascript

研究別人的做品真是一件花時間並且痛苦的過程. 固然也和本人英文很差有關. 總以爲控件做者寫了不少文檔可是都不夠系統, 須要深刻研究不少的實例後才能瞭解做者的思路.因此學習和研究一個插件須要很高成本, 若是發現了Bug並修復須要的成本也是未知數(本次我花了較少的時間解決了自動完成提示插件的一箇中文bug, 可是若是複雜的bug就不會這麼簡單了.).css

對於簡單應用我首先推薦上文中的jQuery UI. 可是jQuery UI解決的問題有限. 使用jQuery插件是咱們最後的一個好辦法---還算是好辦法, 起碼比本身開發要好吧?html

不少jQuery的插件編碼異常優美, 看一看藝龍首頁如今的城市輸入框控件, 除了須要爲輸入框手工添加不少不少屬性(onkeyup, onkeydown等等), 並且還不夠通用, 佔用服務器資源和網絡資源.可是當初也是花費了好久的時間完成的做品.java

站在巨人的肩膀上, 讓我感受寫腳本和寫設計C#程序同樣, 都有高度和深度能夠挖掘. 除了使用做者開發好的功能, 還能夠學習如何開發和封裝javascript控件. 看過優秀的jQuery插件做者的代碼和設計思想後, 經常自嘆設計水平差距竟然如此之大, 增長自認爲腳本高手, 比較事後就是C#程序員和架構師之間的差距.jquery

但願你們經過本章節介紹的兩個插件, 除了學會如何使用, 還可以略微領悟到如何封裝和設計javascript控件.程序員

一.表單驗證插件 validate算法

在提交表單前常要對用戶輸入進行校驗.ASP.NET的驗證控件就是用於此目的, 能夠同時進行客戶端和服務器端驗證. 可是驗證控件並無被全部項目採用. 並且在MVC項目中常用本身的客戶端驗證框架.編程

在比較了若干表單驗證插件後, 決定採用validate插件. 由於其使用簡單而且靈活.緩存

插件首頁:服務器

http://bassistance.de/jquery-plugins/jquery-plugin-validation/

插件文檔:

http://docs.jquery.com/Plugins/Validation

配置說明:

http://docs.jquery.com/Plugins/Validation/validate#options

1.應用實例

實例效果:

image

實例代碼:

 
  1. <%@ Page Language="C#" %>  
  2.  
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  4. <html xmlns="http://www.w3.org/1999/xhtml">  
  5. <head id="Head1" runat="server">  
  6.     <title>jQuery PlugIn - 表單驗證插件實例 Validate </title>  
  7.     <!--black-tie,blitzer,blitzer,dot-luv,excite-bike,hot-sneaks,humanity,mint-choc,redmond,smoothness,south-street,start,swanky-purse,trontastic,ui-darkness,ui-lightness,vader-->  
  8.     <link rel="stylesheet" type="text/css" href="<%=WebConfig.ResourceServer +"/JsLib/jquery/themes/redmond/style.css"%>" />  
  9.     <script type="text/javascript" src="<% =WebConfig.ResourceServer %>/JsLib/jquery/jquery-min-lastest.js"></script>  
  10.     <script type="text/javascript" src="<% =WebConfig.ResourceServer %>/JsLib/jquery/ui/jquery-ui-all-min-lastest.js"></script>  
  11.     <script type="text/javascript" src="<% =WebConfig.ResourceServer %>/JsLib/jquery/plugin/jquery.validate/jquery.validate.min.js"></script>  
  12.     <script type="text/javascript" src="<% =WebConfig.ResourceServer %>/JsLib/jquery/plugin/jquery.validate/localization/messages_cn.js"></script>  
  13.           
  14.     <% if (false)  
  15.        {%><script src="~/js/jquery-vsdoc-lastest.js" type="text/javascript"></script>  
  16.     <% }%>  
  17.     <script type="text/javascript">  
  18.         /*========== 必須放在頭部加載的語句塊. 儘可能避免使用 ==========*/ 
  19.     </script>  
  20.     <style type="text/css">  
  21.         body  
  22.         {  
  23.             font-size:12px;  
  24.         }  
  25.         /* form中顯示文字的label */ 
  26.         .slabel  
  27.         {  
  28.             width:100px;  
  29.             display: -moz-inline-box;  
  30.             line-height: 1.8;  
  31.             display: inline-block;  
  32.             text-align:right;  
  33.         }  
  34.         /* 出錯樣式 */ 
  35.         input.error, textarea.error  
  36.         {  
  37.             border: solid 1px #CD0A0A;  
  38.         }  
  39.         label.error  
  40.         {  
  41.             color:#CD0A0A;  
  42.             margin-left:5px;  
  43.         }  
  44.         /* 深紅色文字 */ 
  45.         .textred  
  46.         {  
  47.             color:#CD0A0A;  
  48.         }  
  49.     </style>  
  50. </head>  
  51. <body>  
  52.     <form id="commentForm" method="get" action="">  
  53.     <fieldset style="width:500px;"><legend>表單驗證</legend>  
  54.         <p><label for="cname" class="slabel"><em class="textred">*</em> 姓名:</label>  
  55.             <input id="cname" name="name" size="25" class="required" minlength="2" />  
  56.         </p>  
  57.         <p><label for="cemail" class="slabel"><em class="textred">*</em> E-Mail:</label>  
  58.             <input id="cemail" name="email" size="25"/>  
  59.         </p>  
  60.         <p><label for="curl" class="slabel">網址:</label>              
  61.             <input id="curl" name="url" size="25" class="url" value="" />  
  62.         </p>  
  63.         <p><label for="ccomment" class="slabel"><em class="textred">*</em> 內容:</label>  
  64.             <textarea rows="2" id="ccomment" name="comment" cols="20" class="required" style="height:80px;"></textarea>  
  65.         </p>  
  66.         <p style="text-align:center;">  
  67.             <input class="submit" type="submit" value="提交" />  
  68.         </p>  
  69.     </fieldset>  
  70.     </form>  
  71.     <script type="text/javascript">  
  72.        /*==========用戶自定義方法==========*/ 
  73.  
  74.  
  75.        /*==========事件綁定==========*/ 
  76.        $(function()  
  77.        {  
  78.  
  79.        });  
  80.  
  81.        /*==========加載時執行的語句==========*/ 
  82.        $(function()  
  83.        {  
  84.            $("#commentForm").validate(  
  85.            {  
  86.                errorClass: "error",  
  87.                submitHandler: function(form)  
  88.                {  
  89.                    //若是想提交表單, 須要使用form.submit()而不要使用$(form).submit()  
  90.                    alert("submitted!");  
  91.                },  
  92.                rules: {  
  93.                    //爲name爲email的控件添加兩個驗證方法:required()和email()  
  94.                    email: { required: true, email: true }  
  95.                },  
  96.                messages: {  
  97.                    //爲name爲email的控件的required()和email()驗證方法設置驗證失敗的消息內容  
  98.                    email: {required:"須要輸入電子郵箱", email:"電子郵箱格式不正確"}  
  99.                }  
  100.  
  101.            });  
  102.        });          
  103.     </script>  
  104. </body>  
  105. </html> 

2. 實例講解

(1) 驗證方法

驗證方法是驗證某一個控件是否知足某些規則的方法, 返回一個boolean值. 好比email( ) 方法驗證內容是否符合email格式, 符合則返回true. 下面是類庫中email方法的源代碼:

 
  1. // http://docs.jquery.com/Plugins/Validation/Methods/email  
  2. email: function(value, element) {  
  3.     // contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/  
  4.     return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|
  5. [\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|
  6. [\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?
  7. (([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|
  8. [\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|
  9. (\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?
  10. (\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|
  11. (([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|
  12. \d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|
  13. [\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|
  14. [\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value);  
  15. }, 

咱們在:http://docs.jquery.com/Plugins/Validation中的 List of built-in Validation methods 一節中列出了全部內置的驗證方法. 同時插件還提供了additional-methods.js 文件, 裏面包含了更多的驗證方法, 引入後既可啓用.

(2) 驗證消息

驗證消息就是驗證方法失敗後顯示的文字內容. 驗證消息必定關聯在某一個驗證方法上, 而且全局的驗證消息保存在jQuery.validator.messages 屬性中.

默認的validate類庫自帶英文驗證消息:

 
  1. messages: {  
  2.     required: "This field is required.",      
  3.     //...      
  4. }); 

上面說明當required驗證方法驗證失敗是, 顯示"This field is required."這條消息.

在下載文件的localization文件夾中, 包含了各國語言的基本驗證消息, 如同本實例同樣引入不一樣的語言文件便可實現語言切換:

 
  1. <script type="text/javascript" src="<% =WebConfig.ResourceServer %>/JsLib/jquery/plugin/jquery.validate/localization/messages_cn.js"></script> 

語言文件的內容舉例:

 
  1. jQuery.extend(jQuery.validator.messages, {  
  2.         required: "必選字段",  
  3.         //...  
  4. }); 

如今必填項的問題提示就變成了中文.

除了全局默認的驗證消息, 也能夠爲某一個表單元素設置特有的驗證消息, 好比本文實例中, 爲email元素設置了特有的驗證消息:

 
  1. messages: {  
  2.    //爲name爲email的控件的required()和email()驗證方法設置驗證失敗的消息內容  
  3.    email: {required:"須要輸入電子郵箱", email:"電子郵箱格式不正確"}  

options的messages屬性能夠針對某一個表單元素設置驗證消息, 第一個email表示email元素, 值是一個集合, required就表示required驗證函數, 第二個email表示是email驗證函數.

(3)驗證規則

驗證規則就是這樣的語意語句: 在元素A上, 使用 驗證方法A 和 驗證方法B 進行驗證.

驗證規則將元素與驗證方法關聯起來, 由於驗證方法同時也關聯了驗證消息, 因此元素與消息也關聯了起來.

爲一個元素添加驗證規則有多種方式.

本實例的"姓名"元素使用了CSS樣式規則和元素屬性規則:

 
  1. <input id="cname" name="name" size="25" class="required" minlength="2" /> 

class元素屬性設置元素的CSS樣式類, 由於樣式類中添加了required類, 因此會和required()驗證函數關聯. 這種規則叫作CSS樣式規則.

minlength元素屬性也會自動和minlength()驗證函數關聯, 這種規則叫作元素屬性規則.

另外還能夠經過編程的方式進行關聯:

 
  1. rules: {  
  2.    //爲name爲email的控件添加兩個驗證方法:required()和email()  
  3.    email: { required: true, email: true }  
  4. }, 

上面的語句表名爲email表單對象添加了required()和email()驗證函數.

(4) 表單提交

默認狀況下, 當驗證函數失敗時表單不會提交.

可是能夠經過添加class="cancel"的方式讓提交按鈕跳過驗證:

 
  1. <input type="submit" class="cancel" name="cancel" value="Cancel" /> 

當表單提交時, 會觸發options中submitHandler屬性設置的函數:

 
  1. submitHandler: function(form)  
  2. {  
  3.    //若是想提交表單, 須要使用form.submit()而不要使用$(form).submit()  
  4.    alert("submitted!");  
  5. }, 

此函數的簽名同上. 咱們能夠在這個函數中, 編寫在表單提交前須要處理的業務邏輯.

須要注意當最後以編程的方式提交表單時, 必定不要使用jQuery對象的submit()方法, 由於此方法會觸發表單驗證,而且再次調用submitHandler設置的函數, 會致使遞歸調用.

此函數的參數form就是表單對象, 用途就是不進行驗證提交表單:form.submit()

(5) DEBUG模式

在開發階段咱們一般不但願表單被真正提交, 雖然能夠經過本實例中重寫submitHandler函數來實現, 可是還有更好的方式, 咱們能夠在submitHandler函數完成正式提交的邏輯, 而後經過設置options的debug屬性, 來達到即便驗證經過也不會提交表單的目的:

 
  1. $(".selector").validate({  
  2.    debug: true 
  3. }) 

(6) 多表單驗證

有時會在一個頁面上出現多個Form, 由於validate控件是針對form對象進行包裝的, 因此咱們能夠控制哪些form對象須要驗證.

同時爲了方便一次設置頁面上全部的應用了validate控件的form對象, 提供了 jQuery.validator.setDefaults 函數讓咱們能夠一次設置全部的默認值:

 
  1. jQuery.validator.setDefaults({   
  2.     debug: true   
  3. }); 

二.自動完成插件 autocomplete

autocomplete插件能幫助咱們實現相似於Google Suggest的效果:

image

插件首頁:

http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/

插件文檔:

http://docs.jquery.com/Plugins/Autocomplete

配置說明:

http://docs.jquery.com/Plugins/Autocomplete/autocomplete#toptions

1.應用實例

本實例演示的是使用autocomplete完成對輸入城市的自動提示效果,如圖:

image

實例代碼:

 
  1. <%@ Page Language="C#" %>  
  2.  
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  4. <html xmlns="http://www.w3.org/1999/xhtml">  
  5. <head id="Head1" runat="server">  
  6.     <title>jQuery PlugIn - 自動完成插件實例 AutoComplete </title>  
  7.     <!--black-tie,blitzer,blitzer,dot-luv,excite-bike,hot-sneaks,humanity,mint-choc,redmond,smoothness,south-street,start,swanky-purse,trontastic,ui-darkness,ui-lightness,vader-->  
  8.     <link rel="stylesheet" type="text/css" href="<%=WebConfig.ResourceServer +"/JsLib/jquery/themes/redmond/style.css"%>" />  
  9.     <link rel="stylesheet" type="text/css" href="<%=WebConfig.ResourceServer +"/JsLib/jquery/plugin/jquery.autocomplete/jquery.autocomplete.css"%>" />  
  10.     <script type="text/javascript" src="<% =WebConfig.ResourceServer %>/JsLib/jquery/jquery-min-lastest.js"></script>  
  11.     <script type="text/javascript" src="<% =WebConfig.ResourceServer %>/JsLib/jquery/ui/jquery-ui-all-min-lastest.js"></script>  
  12.     <script type="text/javascript" src="<% =WebConfig.ResourceServer %>/JsLib/jquery/plugin/jquery.autocomplete/jquery.autocomplete.min.js"></script>  
  13.     <% if (false)  
  14.        {%><script src="~/js/jquery-vsdoc-lastest.js" type="text/javascript"></script>  
  15.     <% }%>  
  16.     <script type="text/javascript">  
  17.         /*========== 必須放在頭部加載的語句塊. 儘可能避免使用 ==========*/ 
  18.     </script>  
  19.     <style type="text/css">  
  20.         body  
  21.         {  
  22.             font-size: 12px;  
  23.         }  
  24.           
  25.         .formLabel{float: left; width: 150px; text-align:right;}  
  26.         .formInput{float: left;}  
  27.     </style>  
  28. </head>  
  29. <body>  
  30.     <!-- Demo. 應用AutoComplete插件 -->  
  31.     <div class="ui-widget ui-widget-content ui-corner-all" style="width: 700px; padding: 5px;">  
  32.         <h3>  
  33.             Demo. 應用AutoComplete插件 </h3>  
  34.         <br style="clear: both" />  
  35.         <div class="formLabel">  
  36.             <label for="inputCityName">請輸入城市拼音和漢字:</label>  
  37.         </div>  
  38.         <div class="formInput">  
  39.             <input id="inputCityName" name="inputCityName" type="text" />  
  40.         </div>  
  41.         <br style="clear:both" />  
  42.         <br style="clear: both" />  
  43.         <div class="formLabel">  
  44.             <label for="inputCityName">城市ID:</label></div>  
  45.         <div class="formInput">  
  46.             <input id="inputCityId" name="inputCityId" type="text" /></div>  
  47.         <br style="clear: both" />  
  48.         <br style="clear: both" />  
  49.     </div>  
  50.     <script type="text/javascript">  
  51.         /*==========用戶自定義方法==========*/ 
  52.         //城市數據  
  53.         var cityList;  
  54.         //autocomplete選項  
  55.         var options = {  
  56.             minChars: 1,  
  57.             max: 500,  
  58.             width: 250,  
  59.             matchContains: true,  
  60.             formatItem: function(row, i, max)  
  61.             {  
  62.                 return i + "/" + max + ": \"" + row.CityNameEn + "\" [" + row.CityName + "]";  
  63.             },  
  64.             formatMatch: function(row, i, max)  
  65.             {  
  66.                 return row.CityNameEn + " " + row.CityName;  
  67.             },  
  68.             formatResult: function(row)  
  69.             {  
  70.                 return row.CityName;  
  71.             }              
  72.         };  
  73.         //autocomplete初始化函數  
  74.         function initAutoComplete(data)  
  75.         {  
  76.             cityList = data;  
  77.             $("#inputCityName").autocomplete(cityList, options);  
  78.             $("#inputCityName").result(function(event, data, formatted)  
  79.             {  
  80.                 $("#inputCityId").val(data.ElongCityId);  
  81.             });                      
  82.         }  
  83.  
  84.  
  85.         /*==========事件綁定==========*/ 
  86.         $(function()  
  87.         {  
  88.         });  
  89.  
  90.         /*==========加載時執行的語句==========*/ 
  91.         $(function()  
  92.         {  
  93.             //加載城市數據, 並在回調函數中用返回的數據初始化autocomplete  
  94.             $.getJSON("cityinfo.htm"null, initAutoComplete)    
  95.         });          
  96.     </script>  
  97. </body>  
  98. </html>  
  99.    

2. 實例講解

(1)準備數據源

首先要準備實現自動建議的數據源. 本實例是經過發送Ajax請求獲取JSON對象. autocomplete()方法支持兩個參數, 第一個是data, 第二個是options.

其中data參數可使本實例中的一個數據變量, 也能夠是一個url. 若是是url則會每次都調用Ajax請求獲取數據.

爲了效率我傾向於在數據量容許的狀況下, 在頁面加載後使用Ajax獲取所有的數據, 而後使用傳遞數據變量給autocomplete組件. 如實例中所示. 除非數據特別巨大沒法再客戶端加載, 則只能每次都使用發送Ajax請求從服務器端獲取部分數據. 可是這會對服務器形成負擔.

(2) 設置關鍵函數

雖然options是可選項, 可是對於咱們的數據源cityList是一個多屬性對象, 因此必須設置下面幾個關鍵的配置項後纔可以使用:

formatItem

對匹配的每一行數據使用此函數格式化, 返回值是顯示給用戶的數據內容.

函數簽名:

function(row, rowNum, rowCount, searchItem)

參數說明:

row: 當前行. the results row,

rowNum: 當前行號,從1開始.(注意不是索引,索引從0開始) the position of the row in the list of results (starting at 1),

rowCount: 總的行號 the number of items in the list of results

searchItem: 查詢使用的數據, 即formatMatch函數返回的數據格式的內容. 咱們在formatMatch函數中會設置程序內部搜索時使用的數據格式,這個格式和給用戶展現的數據是不一樣的.

formatMatch

對每一行數據使用此函數格式化須要查詢的數據格式. 返回值是給內部搜索算法使用的. 實例中用戶看到的匹配結果是formatItem中設置的格式, 可是程序內部其實只搜索城市的英文和中文名稱, 搜索數據在formatMatch中定義:

return row.CityNameEn + " " + row.CityName;

函數簽名:

function(row, rowNum, rowCount,)

參數說明同上

formatResult

此函數是用戶選中後返回的數據格式. 好比實例中只返回城市名給input控件:

return row.CityName;

函數簽名:

function(row, rowNum, rowCount,)

參數說明同上

(3) 爲控件添加Result事件函數

上面3個函數沒法實現這類要求: 雖然只返回城市名稱, 可是查詢時使用城市ID, 選中一個城市後須要將城市ID存儲在一個隱藏域中.

因此autocomplete控件提供了result事件函數, 此事件會在用戶選中某一項後觸發:

 
  1. $("#inputCityName").result(function(event, data, formatted)  
  2. {  
  3.     $("#inputCityId").val(data.ElongCityId);  
  4. });  

函數簽名:

function(event, data, formatted)

參數列表:

Result事件會爲綁定的事件處理函數傳遞三個參數:

event: 事件對象. event.type爲result.

data: 選中的數據行.

formatted: 雖然官方的解釋應該是formatResult函數返回的值, 可是實驗結果是formatMatch返回的值. 在本實例爲: "Beijing 北京".

(4) 匹配中文

當前版本的autocomplete控件對中文搜索存在Bug, 緣由是其搜索事件綁定在keydown事件上, 當使用中文輸入法輸入"北"字時沒有任何提示. 我對原庫作了修改, 將keydown事件修改成keyup事件, 便可完成對中文的智能提示搜索. 另外主要須要將"matchContains"配置項設置爲"true", 由於咱們的搜索格式是"Beijing 北京", 默認只匹配開頭的字符.

(5) 更多配置項

關於更多的配置項, 請參考官方文檔:

http://docs.jquery.com/Plugins/Autocomplete/autocomplete#toptions

(6) 更多事件

除了上面介紹的autocomplete()和result()函數, 還有以下函數:

search( ) : 激活search事件

flushCache( ) : 清空緩存

setOptions( options ) : 設置配置項

三.總結

本文詳細介紹了表單驗證插件和自動完成插件, 目前你們能夠搜索到不少的插件應用, 或者上千的插件列表, 可是卻找不到詳細的使用文檔. 插件用起來簡單可是真正的靈活應用卻不容易, 除了要翻越英文文檔學習基本的使用, 還要花很長時間瞭解各個參數的做用, 如何配合使用等. 而且在上面作二次開發的難度相對較大, 插件的核心代碼多沒有註釋而且複雜, 要在其中尋找邏輯關係要花費不少時間和精力.

相關文章
相關標籤/搜索