ASP.Net中实现中英文复合检索文本框
前段時間,寫一個用戶部門的管理頁面,需要對后臺獲取的用戶數(shù)據(jù)實現(xiàn)英漢檢索功能。
同時,選定一個選項之后,需要觸發(fā)事件與后臺交互,將該用戶所在的部門顯示到頁面右邊的ListBox控件中。
???
?
一、Dojo的FilteringSelect組件實現(xiàn)拼音檢索功能
在網(wǎng)上有不少相關的介紹,其中比較經(jīng)典的有"海盜亂語"的關于重寫Dojo的FilteringSelect組件實現(xiàn)拼音檢索功能的介紹(地址http://cosbor.web-144.com/?p=38、http://cosbor.web-144.com/?p=52)。由于作者的Demo后臺以及pinyin4j的jar包都是基于Java平臺的,本人花了一點時間將其實現(xiàn)在.Net平臺下,并成功的實現(xiàn)了FilteringSelect選中事件的注冊。實現(xiàn)原理請詳細參考"海盜亂語"博客中的分析,這里對.Net平臺下的實現(xiàn)思路做簡要說明,并貼出源碼供大家參考(在此對作者提供的思路表示感謝!):
首先,引入Dojo工具包,在dojo目錄下添加一個"test"文件夾,新建一個FilteringSelect.js文件,如下圖:
FilteringSelect.js文件的作用是重寫FilteringSelect組件,"海盜亂語"的博文中給出了的代碼清單,為方便起見轉貼如下:
View Code define(["dojo/_base/declare", // declare,"dojo/dom-attr", // domAttr.get"dijit/form/FilteringSelect" ], function(declare, domAttr ,FilteringSelect){return declare("test.FilteringSelect", [FilteringSelect], {displayValueAttr:null, //新增一個自定義屬性,用于指定FilteringSelect的textbox中最終顯示內容的屬性字段// summary:// 覆蓋dijit.form._AutoCompleterMixin的同名方法,使FilteringSelect支持displayValueAttr指定textbox最終顯示內容,而不是默認顯示searchAttr指定的字段內容_announceOption: function(/*Node*/ node){if(!node){return;}// pull the text value from the item attached to the DOM nodevar newValue;if(node == this.dropDown.nextButton ||node == this.dropDown.previousButton){newValue = node.innerHTML;this.item = undefined;this.value = '';}else{var item = this.dropDown.items[node.getAttribute("item")];var displayAttr = this.displayValueAttr!=null?this.displayValueAttr:this.searchAttr;//此處判斷是否配置了自定義屬性displayValueAttr newValue = (this.store._oldAPI ? // remove getValue() for 2.0 (old dojo.data API)this.store.getValue(item, displayAttr) : item[displayAttr]).toString();//將this.searchAttr替換為displayAttrthis.set('item', item, false, newValue);}// get the text that the user manually entered (cut off autocompleted text)this.focusNode.value = this.focusNode.value.substring(0, this._lastInput.length);// set up ARIA activedescendantthis.focusNode.setAttribute("aria-activedescendant", domAttr.get(node, "id"));// autocomplete the rest of the option to announce changethis._autoCompleteText(newValue);},}); });然后,新建一個WebForm頁面,放置一個FilteringSelect控件,數(shù)據(jù)源取值為頁面類繼承過來的userListstr字段,頁面前臺代碼如下:
View Code <%@ Page Title="" Language="C#" AutoEventWireup="true" CodeFile="OrgRelation.aspx.cs" Inherits="OrgRelation" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head id="Head1" runat="server"><title></title><script src="Scripts/jquery-1.4.1-vsdoc.js" type="text/javascript"></script><link href="Scripts/dojo/dijit/themes/claro/claro.css" rel="stylesheet" type="text/css" /><link href="Scripts/dojo/dojo/resources/dojo.css" rel="stylesheet" type="text/css" /><script src="Scripts/dojo/dojo/dojo.js" type="text/javascript"></script><script type="text/javascript">//參數(shù)設置 require(['test/FilteringSelect','dojo/store/Memory','dojo/domReady!'], function (FilteringSelect, Memory) {var jsonstr = '<%=userListStr%>';var json = jQuery.parseJSON(jsonstr);var obj = {data:""};obj['data'] = json;var selectStore = new Memory(obj);//創(chuàng)建FilteringSelectvar testSelect = new FilteringSelect({id: "testSelect",name: "test",value: "",store: selectStore,searchAttr: 'py', //指定輸入文本框進行用來進行檢索的字段 labelAttr: 'name', //指定下拉菜單中顯示的字段 displayValueAttr: 'name', //指定選中下拉菜單后顯示在輸入框中的字段 required: false,autoComplete: false}, "testSelect");});//注冊失去焦點事件 window.onload = function () {function selblur() {var guid = dijit.byId('testSelect').attr('value');alert(guid);window.location.href = "OrgRelation.aspx?userId=" + guid;return false;}var sel = dojo.byId("testSelect");dojo.connect(sel, "onblur", selblur);};</script></head><body><form id="Form1" method="post" runat="server"><div align="center" id="title"><strong>編輯用戶部門關系</strong></div><div style="text-align: center;width: 100%;padding-top: 100px;font-size:15px;">選擇用戶:<input id="testSelect"/></div></form></body></html>最后,在頁面加載事件中獲取用戶數(shù)據(jù),序列化之后,賦給protected類型的userListstr字段。其中這里引用到微軟提供的獲取漢字拼音的類庫ChnCharInfo.dll,代碼請單如下:
View Code 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.UI; 6 using System.Web.UI.WebControls; 7 using Microsoft.International.Converters.PinYinConverter; 8 using System.Text; 9 using System.Text.RegularExpressions; 10 using System.Web.Script.Serialization; 11 12 public partial class OrgRelation : System.Web.UI.Page 13 { 14 protected string userListStr = string.Empty; 15 16 protected void Page_Load(object sender, EventArgs e) 17 { 18 if (!IsPostBack) 19 { 20 GetUsers(); 21 } 22 } 23 24 //與前臺頁面Json對象格式對應的類 25 public class UserInfo 26 { 27 public string name { get; set; } 28 public string id { get; set; } 29 public string py { get; set; } 30 } 31 32 protected void GetUsers() 33 { 34 //獲取用戶信息,及每項記錄的拼音簡碼 35 List<User> list =new BLL.User().GetUsers(); 36 List<UserInfo> UserInfoList = new List<UserInfo>(); 37 foreach (User item in list) 38 { 39 UserInfo userInfo= new UserInfo(); 40 userInfo.id = item.UserId; 41 userInfo.name = item.User Name; 42 userInfo.py = GetPY(item.UserName); 43 UserInfoList .Add(userInfo); 44 } 45 JavaScriptSerializer jsonSerializer = new JavaScriptSerializer(); 46 //執(zhí)行序列化 并賦值 47 userListStr = jsonSerializer.Serialize(UserInfoList); 48 } 49 50 #region 拼音檢索的相關方法 51 /// <summary> 52 /// 獲得一個漢字字符的拼音的字符串集合,并處理聲調和空值 53 /// </summary> 54 /// <param name="ch">漢字字符</param> 55 /// <returns></returns> 56 public static List<string> GetPinyins(char ch) 57 { 58 List<string> list = new List<string>(); 59 ChineseChar cc = new ChineseChar(ch); //獲得包含漢字信息的對象 60 foreach (string item in cc.Pinyins) 61 { 62 if (item != null) 63 { 64 string temp = item.Substring(0, item.Length - 1); 65 if (!list.Contains(temp)) 66 { 67 list.Add(temp); 68 } 69 } 70 } 71 return list; 72 } 73 /// <summary> 74 /// 得到一個詞組的拼音的首字母字符串(多音取第一個) 75 /// </summary> 76 /// <returns></returns> 77 public static string GetPY(string str) 78 { 79 Regex reg = new Regex(@"[\u4e00-\u9fa5]"); 80 StringBuilder sb = new StringBuilder(); 81 for (int i = 0; i < str.Length; i++) 82 { 83 string ch = str[i].ToString(); 84 if (reg.IsMatch(ch)) 85 { 86 string s = GetPinyins(str[i])[0]; 87 sb.Append(s[0]); 88 } 89 else 90 { 91 sb.Append(ch); 92 } 93 } 94 return sb.ToString(); 95 } 96 #endregion 97 }這樣拼音檢索的功能就完成了。不過有兩點不盡人意的地方:1.使用拼音檢索后,不好再使用中文檢索,2.網(wǎng)上查了很久,沒有選中項改變事件介紹,代碼中只是注冊了一個失去焦點事件,在與后臺交互方面不太方便(可能是本人對dojo事件不熟,歡迎對dojo api有研究的大俠指點)。
二、JqueryUI的autocomplete插件實現(xiàn)拼音檢索功能
其實JqueryUI也提供了一個非常好用的插件--autocomplete,它與ChnCharInfo.dll類庫配合使用,不僅能實現(xiàn)同樣優(yōu)秀的檢索功能,而且能夠很好的解決上述兩個問題。不妨來看看:
需要用到的相關組件和引用的類庫:Jquery-UI 、漢字拼音轉換語言包類庫ChnCharInfo .dll和Json對象序列化類庫Newtonsoft.Json.dll,如下所示:
1.WebForm的aspx頁面實現(xiàn):
首先引入jquery-1.8.2.js、jquery-ui-1.9.0.custom.js、jquery-ui-1.9.0.custom.css,然后在頁面加載完成的事件中寫如下腳本:
1 <script type="text/javascript"> 2 $(function () { 3 $("#selCompate").autocomplete({ 4 source: "GetUser.ashx", 5 minLength: 1, 6 //以下為選中事件 7 select: function (event, ui) { 8 temp = ui.item; 9 $("#hidUserId").val(temp.id); 10 $("#hidUserName").val(temp.label); 11 $("#form2").attr("action", "./OrgRelation.aspx?contactId=" + temp.id + "&contactName=" + temp.label); 12 $("#form2").submit(); 13 } 14 }); 15 $("#selCompate").val($("#hidUserName").val()) 16 }); 17 </script>其中第4行的?source: "GetUser.ashx",是指鍵入字符后,發(fā)送異步請求的地址,GetUser.ashx負責向請求的客戶端提供滿足Json格式的用戶信息;第5行的minLength: 是輸入到幾個字符時開始發(fā)送異步請求;第7行的select: function(event, ui){}即選中事件,ui.item表示被選中的項;第8-9行的隱藏域存值,是為了頁面刷新后能重新獲取該選中項的相關信息,重新寫回頁面以備用;第10-11行以當前選中項的id和label被為參數(shù)向OrgRelation.aspx發(fā)送post請求,是實現(xiàn)將選中用戶的所在部門查詢處來,顯示到頁面右側的ListBox控件中,其服務端實現(xiàn)與本次討論的內容無關,代碼就不貼出來了。
頁面的完整代碼清單如下:
View Code <%@ Page Title="" Language="C#" AutoEventWireup="true" CodeFile="OrgRelation.aspx.cs"Inherits="OrgRelation"%><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" runat="server"><title></title><script src="Scripts/jquery-1.8.2.js" type="text/javascript"></script><script src="Scripts/jquery-ui-1.9.0.custom.js" type="text/javascript"></script><link href="css/ui-lightness/jquery-ui-1.9.0.custom.css" rel="stylesheet" type="text/css" /><script type="text/javascript">$(function () {$("#selCompate").autocomplete({source: "GetUser.ashx",minLength: 1,//以下為選中事件 select: function (event, ui) {temp = ui.item;$("#hidUserId").val(temp.id);$("#hidUserName").val(temp.label);$("#form2").attr("action", "./OrgRelation.aspx?UserId=" + temp.id + "&UserName=" + temp.label);$("#form2").submit();}});$("#selCompate").val($("#hidUserName").val())});</script> </head> <body><form id="form2" method="post" action="./OrgRelation.aspx" name="sendForm"></form><form id="Form1" method="post" runat="server" ><input type="hidden" id="hidUserId" name="hidUserId" value="<%=currentUserId%>" /><input type="hidden" id="hidUserName" name="hidUserName" value="<%=currentUserName%>"/><asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager><div id="outline"><div align="center" id="title"><strong>編輯用戶部門關系</strong></div><div id="main"><table align="center"><tr><td><div><b>選擇用戶:</b> <asp:UpdatePanel ID="UpdatePanel2" runat="server"><ContentTemplate> <input type="text" id="selCompate" style="line-height: 10px; margin-top: 0px;margin-left: 0px; height: 23px;" runat="server" /></ContentTemplate></asp:UpdatePanel><br /><b>選擇部門:</b></div><br /></td><td></td><td></td></tr><tr><td valign="top" width="41%"><div id="left"><asp:UpdatePanel ID="UpdatePanel1" runat="server"><ContentTemplate><asp:TreeView ID="TreeViewOrgData" runat="server" Font-Names="微軟雅黑" Height="385px"Font-Size="11pt" ForeColor="Black" BackColor="AliceBlue" OnTreeNodeCollapsed="TreeViewOrgData_TreeNodeCollapsed"OnTreeNodeExpanded="TreeViewOrgData_TreeNodeExpanded" ShowCheckBoxes="All"></asp:TreeView></ContentTemplate></asp:UpdatePanel></div></td><td align="center" valign="middle" width="18%"><p><asp:Button ID="btnAddOrg" runat="server" Width="85px" Text="添加部門 >>" Height="22px"BorderStyle="Solid" BorderColor="DarkGray" BackColor="GhostWhite" Font-Size="9pt"OnClick="btnAddOrg_Click"></asp:Button></p><p><asp:Button ID="btnRemoveOrg" runat="server" Width="85px" Text="<< 移除部門" Height="22px"BorderStyle="Solid" BorderColor="DarkGray" BackColor="GhostWhite" Font-Size="9pt"OnClick="btnRemoveOrg_Click"></asp:Button></p></td><td valign="top" align="center" width="41%"><div id="right"><asp:ListBox ID="LBOrg" runat="server" Width="300px" Height="350px" Rows="13" BackColor="AliceBlue"Font-Size="11pt" SelectionMode="Multiple" ></asp:ListBox></div></td></tr></table></div><br /><div align="center" id="bottom"><asp:Button ID="btnBack" runat="server" Text="·返 回·" BackColor="#f8f8ff" /> <asp:Button ID="btnSave" runat="server" Text="·保 存·" BackColor="#f8f8ff" onclick="btnSave_Click" /></div></div></form> </body> </html>?
2.Global.asax中用戶數(shù)據(jù)的準備
由于這里的用戶數(shù)據(jù)不經(jīng)常變化,考慮到搜索是需要頻繁的向服務端請求數(shù)據(jù),因此將用戶數(shù)據(jù)存入了Application中,這樣搜索時直接從Application中取,不用每次去數(shù)據(jù)庫查詢。
Application對象的賦值是在全局應用程序Global.asax的?Application_Start事件中完成的,代碼如下:
void Application_Start(object sender, EventArgs e) {Application.Lock();Application["User"] = GetUsers();Application.UnLock();}獲取用戶信息的GetUser方法中,同時完成了拼音簡碼的獲取,代碼如下:
protected List<string> GetUsers(){List<Model.User> list = new BLL.User().GetUsers();List<string> UserList = new List<string>();foreach (Model.User item in list){UserList .Add(item.Id+"|"+item.Name+"|"+GetPY(item.Name).Replace(" ","").ToLower());}return UserList ;}/// <summary>/// 獲得一個漢字字符的拼音的字符串集合,并處理聲調和空值/// </summary>/// <param name="ch">漢字字符</param>/// <returns></returns>public static List<string> GetPinyins(char ch){List<string> list = new List<string>();Microsoft.International.Converters.PinYinConverter.ChineseChar cc = new Microsoft.International.Converters.PinYinConverter.ChineseChar(ch); //獲得包含漢字信息的對象foreach (string item in cc.Pinyins){if (item != null){string temp = item.Substring(0, item.Length - 1);if (!list.Contains(temp)){list.Add(temp);}}}return list;}/// <summary>/// 得到一個詞組的拼音的首字母字符串(多音取第一個)/// </summary>/// <returns></returns>public static string GetPY(string str){Regex reg = new Regex(@"[\u4e00-\u9fa5]");StringBuilder sb = new StringBuilder();for (int i = 0; i < str.Length; i++){string ch = str[i].ToString();if (string.IsNullOrEmpty(ch)){}else if (reg.IsMatch(ch)){string s = GetPinyins(str[i])[0];sb.Append(s[0]);}else{sb.Append(ch);}}return sb.ToString();}至于Application與數(shù)據(jù)庫中數(shù)據(jù)的一致的考慮,可提供一個一般處理程序UpdateApplication.ashx負責更新Application(代碼與Global.asax中基本相同),當數(shù)據(jù)庫發(fā)生變化時,訪問UpdateApplication.ashx即可更新Application["Contact"]對象。
3.GetUser.ashx中返回符合檢索條件的數(shù)據(jù)
GetUser.ashx中響應搜索事件的服務端代碼清單如下:
1 <%@ WebHandler Language="C#" Class="GetUser" %> 2 3 using System; 4 using System.Web; 5 using BLL; 6 using System.Collections.Generic; 7 using System.Text.RegularExpressions; 8 using System.Web.Script.Serialization; 9 using Microsoft.International.Converters.PinYinConverter; 10 11 public class GetUser :JavaScriptSerializer,IHttpHandler 12 { 13 public void ProcessRequest(HttpContext context) 14 { 15 int i = 0; 16 List<string> strlist = context.Application["User"] as List<string>; 17 string inputStr = context.Request.QueryString.Get("term").ToLower(); 18 List<UserItem> userList = new List<UserItem>(); 19 20 foreach (string str in strlist) 21 { 22 string[] userArr = str.Split('|'); 23 if (i < 10) 24 { 25 Regex reg = new Regex(@"^" + inputStr); 26 if (reg.IsMatch(userArr[2]) || reg.IsMatch(userArr[1])) 27 { 28 UserItem item = new UserItem(); 29 item.id = userArr[0]; 30 item.label = userArr[1]; 31 item.value = userArr[2]; 32 userList.Add(item); 33 i++; 34 } 35 } 36 else 37 { 38 break; 39 } 40 } 41 42 context.Response.ContentType = "application/json"; 43 string output = Newtonsoft.Json.JsonConvert.SerializeObject(userList); 44 context.Response.Write(output); 45 } 46 47 public bool IsReusable 48 { 49 get 50 { 51 return false; 52 } 53 } 54 } 55 56 public class UserItem
57 { 58 public string id { get; set; } 59 public string label { get; set; } 60 public string value { get; set; } 61 }
第17行是獲取文本框中輸入的檢索字符串inputstr,這里使用正則表達式對獲取名稱以inputstr開頭的記錄(中文檢索)或者拼音簡碼以inputstr開頭的記錄(拼音檢索)。如果需要模糊檢索功能,可以修改第25行的正則表達式為:Regex reg = new Regex(inputStr);即可。如果需要更多字段的復合檢索(例如用戶手機號,郵箱地址等),也只要Application對像賦值時獲取相關的字段信息,在26行的if判斷中增加相應匹配項即可。
其中UserItem是為頁面提供Json對象的類,label是必須字段,搜索框中顯示的內容即該字段的值。得到符合條件的數(shù)據(jù)集合后,需要使用Newtonsoft.Json.JsonConvert的SerializeObject方法進行序列化,再返回給客戶端。
到此,即實現(xiàn)了本文開篇的貼圖效果。
?
轉載于:https://www.cnblogs.com/Extreme/archive/2013/02/17/Extreme_ChnCharSearch.html
總結
以上是生活随笔為你收集整理的ASP.Net中实现中英文复合检索文本框的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 点击谷歌浏览器安装包没有反应
- 下一篇: ASP.NET中的Menu控件的应用