天天看點

從零開始學習jQuery (十一) 實戰表單驗證與自動完成提示插件

<a href="http://www.cnblogs.com/zhangziqiu/archive/2009/04/30/jQuery-Learn-1.html"></a>

<a href="http://www.cnblogs.com/zhangziqiu/archive/2009/04/30/jQuery-Learn-1.html">從零開始學習jQuery (一) 開天辟地入門篇</a>

<a href="http://www.cnblogs.com/zhangziqiu/archive/2009/05/03/jQuery-Learn-2.html">從零開始學習jQuery (二) 萬能的選擇器</a>

<a href="http://www.cnblogs.com/zhangziqiu/archive/2009/05/04/jQuery-Learn-3.html">從零開始學習jQuery (三) 管理jQuery包裝集</a>

<a href="http://www.cnblogs.com/zhangziqiu/archive/2009/05/05/jQuery-Learn-4.html">從零開始學習jQuery (四) 使用jQuery操作元素的屬性與樣式</a>

<a href="http://www.cnblogs.com/zhangziqiu/archive/2009/05/06/jQuery-Learn-5.html">從零開始學習jQuery (五) 事件與事件對象</a>

<a href="http://www.cnblogs.com/zhangziqiu/archive/2009/05/08/jQuery-Learn-6.html">從零開始學習jQuery (六) jQuery中的Ajax</a>

<a href="http://www.cnblogs.com/zhangziqiu/archive/2009/05/11/jQuery-Learn-7.html">從零開始學習jQuery (七) jQuery動畫-讓頁面動起來!</a>

<a href="http://www.cnblogs.com/zhangziqiu/archive/2009/05/12/jQuery-Learn-8.html">從零開始學習jQuery (八) 插播:jQuery實施方案</a>

<a href="http://www.cnblogs.com/zhangziqiu/archive/2009/05/12/jQuery-Learn-9.html">從零開始學習jQuery (九) jQuery工具函數</a>

<a href="http://www.cnblogs.com/zhangziqiu/archive/2009/05/06/jQuery-Learn-10.html">從零開始學習jQuery (十) jQueryUI常用功能實戰</a>

<a href="http://www.cnblogs.com/zhangziqiu/archive/2009/05/22/jQuery-Learn-11.html">從零開始學習jQuery (十一) 實戰表單驗證與自動完成提示插件</a>

本系列文章将帶您進入jQuery的精彩世界, 其中有很多作者具體的使用經驗和解決方案,  即使你會使用jQuery也能在閱讀中發現些許秘籍.

本文是介紹兩個最常用的jQuery插件. 分别用于表單驗證和自動完成提示(類似google suggest).

研究别人的作品真是一件花時間而且痛苦的過程. 當然也和本人英文不好有關. 總覺得控件作者寫了很多文檔但是都不夠系統, 需要深入研究很多的執行個體後才能了解作者的思路.是以學習和研究一個插件需要很高成本, 如果發現了Bug并修複需要的成本也是未知數(本次我花了較少的時間解決了自動完成提示插件的一個中文bug, 但是如果複雜的bug就不會這麼簡單了.).

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

很多jQuery的插件編碼異常優美, 看一看藝龍首頁現在的城市輸入框控件, 除了需要為輸入框手工添加很多很多屬性(onkeyup, onkeydown等等), 而且還不夠通用, 占用伺服器資源和網絡資源.但是當初也是花費了很久的時間完成的作品.

站在巨人的肩膀上, 讓我感覺寫腳本和寫設計C#程式一樣, 都有高度和深度可以挖掘. 除了使用作者開發好的功能, 還可以學習如何開發和封裝javascript控件. 看過優秀的jQuery插件作者的代碼和設計思想後, 常常自歎設計水準差距居然如此之大, 增加自認為腳本高手, 比較過後就是C#程式員和架構師之間的差距.

希望大家通過本章節介紹的兩個插件, 除了學會如何使用,  還能夠略微領悟到如何封裝和設計javascript控件.

在送出表單前常要對使用者輸入進行校驗.ASP.NET的驗證控件就是用于此目的, 可以同時進行用戶端和伺服器端驗證. 但是驗證控件并沒有被所有項目采用. 而且在MVC項目中經常使用自己的用戶端驗證架構.

在比較了若幹表單驗證插件後, 決定采用validate插件. 因為其使用簡單并且靈活.

插件首頁:

<a href="http://bassistance.de/jquery-plugins/jquery-plugin-validation/">http://bassistance.de/jquery-plugins/jquery-plugin-validation/</a>

插件文檔:

<a href="http://docs.jquery.com/Plugins/Validation">http://docs.jquery.com/Plugins/Validation</a>

配置說明:

<a href="http://docs.jquery.com/Plugins/Validation/validate#options">http://docs.jquery.com/Plugins/Validation/validate#options</a>

從零開始學習jQuery (十一) 實戰表單驗證與自動完成提示插件

我們在:

中的 List of built-in Validation methods 一節中列出了所有内置的驗證方法. 同時插件還提供了additional-methods.js 檔案, 裡面包含了更多的驗證方法, 引入後既可啟用.

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

預設的validate類庫自帶英文驗證消息:

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

在下載下傳檔案的localization檔案夾中, 包含了各國語言的基本驗證消息, 如同本執行個體一樣引入不同的語言檔案即可實作語言切換:

語言檔案的内容舉例:

現在必填項的問題提示就變成了中文.

除了全局預設的驗證消息, 也可以為某一個表單元素設定特有的驗證消息, 比如本文執行個體中, 為email元素設定了特有的驗證消息:

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

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

驗證規則将元素與驗證方法關聯起來, 因為驗證方法同時也關聯了驗證消息, 是以元素與消息也關聯了起來.

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

本執行個體的"姓名"元素使用了CSS樣式規則和元素屬性規則:

class元素屬性設定元素的CSS樣式類, 因為樣式類中添加了required類,  是以會和required()驗證函數關聯. 這種規則叫做CSS樣式規則.

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

另外還可以通過程式設計的方式進行關聯:

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

預設情況下, 當驗證函數失敗時表單不會送出.

但是可以通過添加class="cancel"的方式讓送出按鈕跳過驗證:

當表單送出時, 會觸發options中submitHandler屬性設定的函數:

此函數的簽名同上.  我們可以在這個函數中,  編寫在表單送出前需要處理的業務邏輯.

需要注意當最後以程式設計的方式送出表單時, 一定不要使用jQuery對象的submit()方法, 因為此方法會觸發表單驗證,并且再次調用submitHandler設定的函數, 會導緻遞歸調用.

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

在開發階段我們通常不希望表單被真正送出,  雖然可以通過本執行個體中重寫submitHandler函數來實作, 但是還有更好的方式, 我們可以在submitHandler函數完成正式送出的邏輯, 然後通過設定options的debug屬性, 來達到即使驗證通過也不會送出表單的目的:

有時會在一個頁面上出現多個Form, 因為validate控件是針對form對象進行包裝的, 是以我們可以控制哪些form對象需要驗證.

同時為了友善一次設定頁面上所有的應用了validate控件的form對象,  提供了 jQuery.validator.setDefaults 函數讓我們可以一次設定所有的預設值:

autocomplete插件能幫助我們實作類似于Google Suggest的效果:

從零開始學習jQuery (十一) 實戰表單驗證與自動完成提示插件

<a href="http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/">http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/</a>

<a href="http://docs.jquery.com/Plugins/Autocomplete">http://docs.jquery.com/Plugins/Autocomplete</a>

<a href="http://docs.jquery.com/Plugins/Autocomplete/autocomplete#toptions">http://docs.jquery.com/Plugins/Autocomplete/autocomplete#toptions</a>

本執行個體示範的是使用autocomplete完成對輸入城市的自動提示效果,如圖:

從零開始學習jQuery (十一) 實戰表單驗證與自動完成提示插件

執行個體代碼:

首先要準備實作自動建議的資料源. 本執行個體是通過發送Ajax請求擷取JSON對象. autocomplete()方法支援兩個參數, 第一個是data, 第二個是options.

其中data參數可以使本執行個體中的一個資料變量, 也可以是一個url. 如果是url則會每次都調用Ajax請求擷取資料.

為了效率我傾向于在資料量允許的情況下, 在頁面加載後使用Ajax擷取全部的資料, 然後使用傳遞資料變量給autocomplete元件. 如執行個體中所示. 除非資料特别巨大無法再用戶端加載,  則隻能每次都使用發送Ajax請求從伺服器端擷取部分資料. 但是這會對伺服器造成負擔.

雖然options是可選項, 但是對于我們的資料源cityList是一個多屬性對象, 是以必須設定下面幾個關鍵的配置項後才能夠使用:

對比對的每一行資料使用此函數格式化, 傳回值是顯示給使用者的資料内容.

函數簽名:

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函數中會設定程式内部搜尋時使用的資料格式,這個格式和給使用者展示的資料是不同的.

對每一行資料使用此函數格式化需要查詢的資料格式. 傳回值是給内部搜尋算法使用的. 執行個體中使用者看到的比對結果是formatItem中設定的格式, 但是程式内部其實隻搜尋城市的英文和中文名稱, 搜尋資料在formatMatch中定義:

function(row, rowNum, rowCount,)

參數說明同上

此函數是使用者選中後傳回的資料格式. 比如執行個體中隻傳回城市名給input控件:

上面3個函數無法實作這類要求: 雖然隻傳回城市名稱, 但是查詢時使用城市ID, 選中一個城市後需要将城市ID存儲在一個隐藏域中.

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

function(event, data, formatted)

參數清單:

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

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

data: 選中的資料行.

formatted:   雖然官方的解釋應該是formatResult函數傳回的值, 但是實驗結果是formatMatch傳回的值. 在本執行個體為: "Beijing  北京".

目前版本的autocomplete控件對中文搜尋存在Bug, 原因是其搜尋事件綁定在keydown事件上, 當使用中文輸入法輸入"北"字時沒有任何提示. 我對原庫做了修改, 将keydown事件修改為keyup事件, 即可完成對中文的智能提示搜尋. 另外主要需要将"matchContains"配置項設定為"true", 因為我們的搜尋格式是"Beijing 北京", 預設隻比對開頭的字元.

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

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

本文詳細介紹了表單驗證插件和自動完成插件, 目前大家可以搜尋到很多的插件應用, 或者上千的插件清單, 但是卻找不到詳細的使用文檔. 插件用起來簡單但是真正的靈活應用卻不容易, 除了要翻越英文文檔學習基本的使用, 還要花很長時間了解各個參數的作用, 如何配合使用等. 并且在上面做二次開發的難度相對較大, 插件的核心代碼多沒有注釋并且複雜,  要在其中尋找邏輯關系要花費很多時間和精力. 本文介紹的兩個插件更多的細節請參考官方文檔, 位址都在一開始為大家提供了.

後續文章我決定先進行jQuery技巧和javascript必備知識的講解,  我們很少開發自定義插件是以将開發插件篇放在最後.

本章節代碼下載下傳:

<a href="http://files.cnblogs.com/zhangziqiu/Code-jQueryStudy-11.rar">http://files.cnblogs.com/zhangziqiu/Code-jQueryStudy-11.rar</a>

繼續閱讀