[原创]如何在FineUI中集成jQuery UI的AutoComplete组件
首先介绍下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
喜欢这篇文章?别忘了点击文章右下角的推荐按钮哦~~~~