首先介紹下FineUI,FineUI 是基於 ExtJS 的專業 ASP.NET 2.0 控件庫,FineUI的目標是創建 No JavaScript,No CSS,No UpdatePanel,No ViewState,No WebServices 的網站應用程序。如果你對FineUI還不熟悉的話,可以移步FineUI官方網站:http://fineui.com/
我們都知道FineUI是WebForm控件的集合,這也就意味着每次頁面回發的代價比較大,需要重新構建頁面中所有的控件並觸發必要的事件。而對於自動補全這一常見功能來說,這種回發就顯得沒有必要了,因此我們可以通過一個ashx來取自動補全的數據。下面我們會通過一些例子詳細演示如何在FineUI中集成jQuery UI的AutoComplete組件。
注:本文中的大部分例子和數據都來自jQuery UI官方網站。
示例一(內聯數據):
這個例子的數據來自JavaScript,在文本框中任意輸入一個字母,會出現一個選擇編程語言的下拉列表,可以通過鼠標或者鍵盤選擇需要的值,顯示效果:
這個例子的完整代碼如下:
1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="inline.aspx.cs" Inherits="FineUI.Examples.autocomplete.inline" %> 2 3 <!DOCTYPE html> 4 <html> 5 <head runat="server"> 6 <title></title> 7 <link href="../css/main.css" rel="stylesheet" type="text/css" /> 8 <link rel="stylesheet" href="../jqueryui/css/ui-lightness/jquery-ui-1.9.2.custom.min.css" /> 9 </head> 10 <body> 11 <form id="form1" runat="server"> 12 <x:PageManager ID="PageManager1" runat="server" /> 13 <x:SimpleForm ID="SimpleForm1" runat="server" Width="600px" BodyPadding="5px" EnableBackgroundColor="true" 14 Title="簡單表單"> 15 <Items> 16 <x:TextBox ID="TextBox1" runat="server" ShowLabel="false" EmptyText="輸入字母 a 試試"> 17 </x:TextBox> 18 </Items> 19 </x:SimpleForm> 20 </form> 21 <script src="../jqueryui/js/jquery-1.8.3.min.js" type="text/javascript"></script> 22 <script src="../jqueryui/js/jquery-ui-1.9.2.custom.min.js" type="text/javascript"></script> 23 <script type="text/javascript"> 24 25 function onReady() { 26 var textbox1ID = '<%= TextBox1.ClientID %>'; 27 28 var availableTags = [ 29 "ActionScript", 30 "AppleScript", 31 "Asp", 32 "BASIC", 33 "C", 34 "C++", 35 "Clojure", 36 "COBOL", 37 "ColdFusion", 38 "Erlang", 39 "Fortran", 40 "Groovy", 41 "Haskell", 42 "Java", 43 "JavaScript", 44 "Lisp", 45 "Perl", 46 "PHP", 47 "Python", 48 "Ruby", 49 "Scala", 50 "Scheme"]; 51 52 $('#' + textbox1ID).autocomplete({ 53 source: availableTags 54 }); 55 56 } 57 58 </script> 59 </body> 60 </html>
關鍵步驟:
- 首先在<head>標簽中引入jQuery UI的CSS庫;
- 在</form>標簽后面引入jQuery和jQuery UI兩個JavaScript庫;
- 將所有實現代碼放在 onReady 函數中,這個onReady函數會在所有的FineUI組件渲染完畢后由FineUI負責點調用;
- 通過 <%= TextBox1.ClientID %> 獲取Asp.Net 服務器控件的客戶端ID。
了解這些基本步驟后,后面的示例就輕松多了。
示例二(自動補全郵件地址):
很多郵件服務商或者郵件客戶端都會提供這個功能,當你輸入郵件前綴時會自動補全郵件后綴,顯示效果如下:
關鍵代碼如下:
1 function onReady() { 2 var textbox1ID = '<%= TextBox1.ClientID %>'; 3 4 var availableTags = [ 5 "qq.com", 6 "163.com", 7 "gmail.com", 8 "outlook.com", 9 "126.com", 10 "sina.com", 11 "yahoo.com", 12 "sohu.com", 13 "foxmail.com", 14 "live.com", 15 "mail.ustc.edu.cn"]; 16 17 18 function getFullEmails(name) { 19 var emails = []; 20 for (var i = 0, count = availableTags.length; i < count; i++) { 21 emails.push(name + "@" + availableTags[i]); 22 } 23 return emails; 24 } 25 26 $('#' + textbox1ID).autocomplete({ 27 source: function (request, response) { 28 if (request.term.indexOf('@') === -1) { 29 response(getFullEmails(request.term)); 30 } 31 } 32 }); 33 34 }
示例三(多行補全數據):
就是補全數據的每一項都顯示標題和描述,可能還有其他信息,效果如下:
當選中一項時,可以把相關數據放到對應的文本輸入框中:
關鍵代碼:
1 function onReady() { 2 var textbox1ID = '<%= TextBox1.ClientID %>'; 3 var textbox2ID = '<%= TextBox2.ClientID %>'; 4 var textbox3ID = '<%= TextBox3.ClientID %>'; 5 6 var projects = [ 7 { 8 value: "jquery", 9 label: "jQuery", 10 desc: "the write less, do more, JavaScript library" 11 }, 12 { 13 value: "jquery-ui", 14 label: "jQuery UI", 15 desc: "the official user interface library for jQuery" 16 }, 17 { 18 value: "sizzlejs", 19 label: "Sizzle JS", 20 desc: "a pure-JavaScript CSS selector engine" 21 } 22 ]; 23 24 $('#' + textbox1ID).autocomplete({ 25 minLength: 0, 26 source: projects, 27 select: function (event, ui) { 28 var $this = $(this); 29 $this.val(ui.item.label); 30 $('#' + textbox2ID).val(ui.item.value); 31 $('#' + textbox3ID).val(ui.item.desc); 32 return false; 33 } 34 }).data("autocomplete")._renderItem = function (ul, item) { 35 return $("<li>").data("item.autocomplete", item) 36 .append("<a><span class='autocomplete-item-title'>" + item.label + "</span><br/>" + item.desc + "</a>") 37 .appendTo(ul); 38 }; 39 40 }
代碼中出現了一個自動的CSS類 autocomplete-item-title,因此還需要在 <head> 標簽中加入CSS定義:
1 <style> 2 .autocomplete-item-title 3 { 4 font-weight: bold; 5 } 6 </style>
示例四(輸入逗號分隔的多個值):
這個例子稍微有點復雜,不過都是jQuery UI的調用代碼,並且代碼中我都加上了中文注釋,應該比較容易看懂:
1 function onReady() { 2 var textbox1ID = '<%= TextBox1.ClientID %>'; 3 4 var availableTags = [ 5 "ActionScript", 6 "AppleScript", 7 "Asp", 8 "BASIC", 9 "C", 10 "C++", 11 "Clojure", 12 "COBOL", 13 "ColdFusion", 14 "Erlang", 15 "Fortran", 16 "Groovy", 17 "Haskell", 18 "Java", 19 "JavaScript", 20 "Lisp", 21 "Perl", 22 "PHP", 23 "Python", 24 "Ruby", 25 "Scala", 26 "Scheme" 27 ]; 28 29 // 將字符串 val 以逗號空格作為分隔符,分隔成數組 30 function split(val) { 31 return val.split(/,\s*/); 32 } 33 34 // 取得以逗號空格為分隔符的最后一個單詞 35 // 比如,輸入為 "C++, C#, JavaScript" 則輸入出 "JavaScript" 36 function extractLast(term) { 37 return split(term).pop(); 38 } 39 40 $('#' + textbox1ID).bind("keydown", function (event) { 41 // 通過 Tab 選擇一項時,不會使當前文本框失去焦點 42 if (event.keyCode === $.ui.keyCode.TAB && 43 $(this).data("autocomplete").menu.active) { 44 event.preventDefault(); 45 } 46 }).autocomplete({ 47 minLength: 0, 48 source: function (request, response) { 49 // 將最后一個單詞作為輸入值,從列表中過濾出備選項 50 response($.ui.autocomplete.filter( 51 availableTags, extractLast(request.term))); 52 }, 53 focus: function () { 54 // 阻止某一項獲得焦點時,更新文本框的值 55 return false; 56 }, 57 select: function (event, ui) { 58 var terms = split(this.value); 59 // 移除用戶正在輸入項 60 terms.pop(); 61 // 添加用戶選擇的項 62 terms.push(ui.item.value); 63 // 添加占位符,確保字符串的最后以逗號空格結束 64 terms.push(""); 65 this.value = terms.join(", "); 66 return false; 67 } 68 }); 69 70 }
示例五(遠程服務器取數據,客戶端緩存):
上面幾個例子的自動補全數據全在JavaScript中,這個例子我們將從服務器獲取數據,准備一個ashx文件:
1 using System; 2 using System.Collections.Generic; 3 using System.Web; 4 using Newtonsoft.Json; 5 using Newtonsoft.Json.Linq; 6 7 namespace FineUI.Examples.autocomplete 8 { 9 /// <summary> 10 /// search 的摘要說明 11 /// </summary> 12 public class search : IHttpHandler 13 { 14 private static readonly string[] LANGUAGES = new string[]{ 15 "ActionScript", 16 "AppleScript", 17 "Asp", 18 "BASIC", 19 "C", 20 "C++", 21 "Clojure", 22 "COBOL", 23 "ColdFusion", 24 "Erlang", 25 "Fortran", 26 "Groovy", 27 "Haskell", 28 "Java", 29 "JavaScript", 30 "Lisp", 31 "Perl", 32 "PHP", 33 "Python", 34 "Ruby", 35 "Scala", 36 "Scheme" 37 }; 38 39 public void ProcessRequest(HttpContext context) 40 { 41 //System.Threading.Thread.Sleep(2000); 42 43 String term = context.Request.QueryString["term"]; 44 if (!String.IsNullOrEmpty(term)) 45 { 46 term = term.ToLower(); 47 48 JArray ja = new JArray(); 49 foreach (string lang in LANGUAGES) 50 { 51 if (lang.ToLower().Contains(term)) 52 { 53 ja.Add(lang); 54 } 55 } 56 57 58 context.Response.ContentType = "text/plain"; 59 context.Response.Write(ja.ToString()); 60 } 61 62 } 63 64 public bool IsReusable 65 { 66 get 67 { 68 return false; 69 } 70 } 71 } 72 }
這個 search.ashx 文件會根據傳入的 term 參數,查詢出符合條件的自動補全數據,並作為 JSON 數組的形式返回給jQuery UI的Autocomplete組件。
看下客戶端的調用代碼:
1 function onReady() { 2 var textbox1ID = '<%= TextBox1.ClientID %>'; 3 4 var cache = {}; 5 6 $('#' + textbox1ID).autocomplete({ 7 minLength: 2, 8 source: function (request, response) { 9 var term = request.term; 10 if (term in cache) { 11 response(cache[term]); 12 return; 13 } 14 15 $.getJSON("search.ashx", request, function (data, status, xhr) { 16 cache[term] = data; 17 response(data); 18 }); 19 } 20 }); 21 22 }
需要說明的兩點:
- 在JavaScript端聲明了一個局部變量 var cache = {}; 用來緩存服務器端返回的數據,從而有效地提高性能。
- 通過 minLength 來限制自動補全所需的最小字符數。對於這個例子,如果只輸入一個字符是不會出現自動補全下拉列表的。
最終的顯示效果:
小結:
FineUI 經過4 年的發展,100多個版本的錘煉,目前已經相當的穩定。下一步我會盡可能多的考慮將更多的其他組件集成進來,包括前一段時間集成的 FCEditor、CKEditor以及百度的UEditor,讓程序員能夠把更多的精力放到業務實現上去,而不是糾結於技術細節,從而提供開發效率。
下載全部源代碼:
這些例子最終會加入FineUI v3.2.3中(尚未發布),不過你現在就可以下載 FineUI 全部源代碼,自己編譯運行這些例子:http://fineui.codeplex.com/SourceControl/BrowseLatest
喜歡這篇文章?別忘了點擊文章右下角的推薦按鈕哦~~~~