[原创]如何在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>

关键步骤:

  1. 首先在<head>标签中引入jQuery UI的CSS库;
  2. 在</form>标签后面引入jQuery和jQuery UI两个JavaScript库;
  3. 将所有实现代码放在 onReady 函数中,这个onReady函数会在所有的FineUI组件渲染完毕后由FineUI负责点调用;
  4. 通过 <%= 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 }

需要说明的两点:

  1. 在JavaScript端声明了一个局部变量 var cache = {}; 用来缓存服务器端返回的数据,从而有效地提高性能。
  2. 通过 minLength 来限制自动补全所需的最小字符数。对于这个例子,如果只输入一个字符是不会出现自动补全下拉列表的。

最终的显示效果:

 

小结:

FineUI 经过4 年的发展,100多个版本的锤炼,目前已经相当的稳定。下一步我会尽可能多的考虑将更多的其他组件集成进来,包括前一段时间集成的 FCEditor、CKEditor以及百度的UEditor,让程序员能够把更多的精力放到业务实现上去,而不是纠结于技术细节,从而提供开发效率。

 

下载全部源代码:

这些例子最终会加入FineUI v3.2.3中(尚未发布),不过你现在就可以下载 FineUI 全部源代码,自己编译运行这些例子:http://fineui.codeplex.com/SourceControl/BrowseLatest

 

 

喜欢这篇文章?别忘了点击文章右下角的推荐按钮哦~~~~

 

 

 

 

 

 

posted @ 2012-12-21 08:10 三生石上(FineUI控件) 阅读(...) 评论(...) 编辑 收藏