Some time ago, to write a user department management page, you need to implement the English-Chinese search function for the user data obtained in the background.
At the same time, after selecting an option, You Need To trigger the event to interact with the background and display the user's Department to The ListBox control on the right of the page.
I. The FilteringSelect component of Dojo implements the pinyin search function
There are a lot of related introduction on the Internet, among which the classic "pirate chaos" on the rewriting of Dojo FilteringSelect component to achieve pinyin search function introduction (address http://cosbor.web-144.com /? P = 38, http://cosbor.web-144.com /? P = 52 ). Since the Demo background of the author and the jar packages of pinyin4j are based on the Java platform, I spent a little time registering the selected FilteringSelect event on the. Net platform. For details about the implementation principle, refer to the analysis in the "pirate talk" blog. net platform, and post the source code for your reference (here, I would like to thank you for your ideas !) :
First, introduce the Dojo toolkit, add a "test" folder under the dojo directory, and create a new FilteringSelect. js file, such:
The function of the FilteringSelect. js file is to rewrite the FilteringSelect component. The code list shown in the blog post of "pirate talk" is as follows for convenience:
Copy codeThe Code is as follows: define ([
"Dojo/_ base/declare", // declare,
"Dojo/dom-attr", // domAttr. get
"Dijit/form/FilteringSelect"
], Function (declare, domAttr, FilteringSelect ){
Return declare ("test. FilteringSelect", [FilteringSelect], {
DisplayValueAttr: null, // Add a custom attribute to specify the attribute field of the final content displayed in the textbox of FilteringSelect.
// Summary:
// Overwrite the dijit. form. _ AutoCompleterMixin method of the same name, so that FilteringSelect supports displayValueAttr to specify the final display content of textbox, instead of the field content specified by searchAttr by default.
_ AnnounceOption: function (/* Node */node ){
If (! Node ){
Return;
}
// Pull the text value from the item attached to the DOM node
Var newValue;
If (node = this. dropDown. nextButton |
Node = this. dropDown. previusbutton ){
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; // check whether the custom attribute displayValueAttr is configured.
NewValue = (this. store. _ oldAPI? // Remove getValue () for 2.0 (old dojo. data API)
This. store. getValue (item, displayAttr): item [displayAttr]). toString (); // replace this. searchAttr with displayAttr
This. 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 activedescendant
This. focusNode. setAttribute ("aria-activedescendant", domAttr. get (node, "id "));
// Autocomplete the rest of the option to announce change
This. _ autoCompleteText (newValue );
},
});
});
Create a new WebForm page and place a FilteringSelect control. The data source value is the userListstr field inherited from the page class. The front-end code of the page is as follows:Copy codeThe Code is as follows: <% @ 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/resources/dojo.css" rel = "stylesheet" type = "text/css"/>
<Script src = "Scripts/dojo. js" type = "text/javascript"> </script>
<Script type = "text/javascript">
// Parameter settings
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 );
// Create FilteringSelect
Var testSelect = new FilteringSelect ({
Id: "testSelect ",
Name: "test ",
Value :"",
Store: selectStore,
SearchAttr: 'py', // specify the fields used for retrieval in the input text box
LabelAttr: 'name', // specify the fields displayed in the drop-down list
DisplayValueAttr: 'name', // specify the fields displayed in the input box after the drop-down menu is selected
Required: false,
AutoComplete: false
}, "TestSelect ");
});
// Register an event with no focus
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> edit the user department relationship </strong>
</Div>
<Div style = "text-align: center; width: 100%; padding-top: 100px; font-size: 15px;"> select a user: <input id = "testSelect"/>
</Div>
</Form>
</Body>
</Html>
Finally, get user data in the page loading event. After serialization, assign it to the userListstr field of the protected type. Here we reference the ChnCharInfo. dll class library provided by Microsoft to obtain Chinese pinyin. The Code is as follows:Copy codeThe Code is as follows: using System;
Using System. Collections. Generic;
Using System. Linq;
Using System. Web;
Using System. Web. UI;
Using System. Web. UI. WebControls;
Using Microsoft. International. Converters. PinYinConverter;
Using System. Text;
Using System. Text. RegularExpressions;
Using System. Web. Script. Serialization;
Public partial class OrgRelation: System. Web. UI. Page
{
Protected string userListStr = string. Empty;
Protected void Page_Load (object sender, EventArgs e)
{
If (! IsPostBack)
{
GetUsers ();
}
}
// Class corresponding to the Json object format on the front-end page
Public class UserInfo
{
Public string name {get; set ;}
Public string id {get; set ;}
Public string py {get; set ;}
}
Protected void GetUsers ()
{
// Obtain user information and the pinyin short code of each record
List <User> list = new BLL. User (). GetUsers ();
List <UserInfo> UserInfoList = new List <UserInfo> ();
Foreach (User item in list)
{
UserInfo userInfo = new UserInfo ();
UserInfo. id = item. UserId;
UserInfo. name = item. User Name;
UserInfo. py = GetPY (item. UserName );
UserInfoList. Add (userInfo );
}
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer ();
// Execute serialization and assign values
UserListStr = jsonSerializer. Serialize (UserInfoList );
}
# Region pinyin Retrieval Methods
/// <Summary>
/// Obtain a string set of Chinese Characters in pinyin, and combine the operators and voices to reconcile null values.
/// </Summary>
/// <Param name = "ch"> Chinese Character </param>
/// <Returns> </returns>
Public static List <string> GetPinyins (char ch)
{
List <string> list = new List <string> ();
ChineseChar cc = new ChineseChar (ch); // obtain the object containing Chinese Characters
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>
/// Obtain the first character string of the pinyin alphabet of a phrase)
/// </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 (reg. IsMatch (ch ))
{
String s = GetPinyins (str [I]) [0];
Sb. Append (s [0]);
}
Else
{
Sb. Append (ch );
}
}
Return sb. ToString ();
}
# Endregion
}
In this way, the pinyin search function is complete. However, there are two unsatisfactory points: 1. it is difficult to use Chinese for retrieval after using pinyin. 2. I checked it online for a long time. I did not select an item to change the event description. I only registered a focus loss event in the code, which is not convenient in interaction with the background (maybe I am not familiar with the dojo event, you are welcome to give some advice on the dojo api ).
Ii. Use the autocomplete plug-in of JqueryUI to implement pinyin search
In fact, JqueryUI also provides a very useful plug-in, autocomplete, which works with the ChnCharInfo. dll class library, not only can achieve the same excellent retrieval function, but also can effectively solve the above two problems. Let's take a look:
Required components and referenced class libraries: Jquery-UI, Chinese PinYin conversion Language Pack class library ChnCharInfo. dll and Json Object serialization class library Newtonsoft. Json. dll, as shown below:
1. Implementation of the aspx page of WebForm:
First, import jquery-1.8.2.js?jquery-ui-1.9.0.custom.js=jquery-ui-1.9.0.custom.css, and then write the following script in the page load completion event:
Copy codeThe Code is as follows: <script type = "text/javascript">
$ (Function (){
$ ("# SelCompate"). autocomplete ({
Source: "GetUser. ashx ",
MinLength: 1,
// The selected event is as follows:
Select: function (event, ui ){
Temp = ui. item;
$ ("# Hidcontactid"). val (temp. id );
$ ("# Hidcontactname"). val (temp. label );
$ ("# Form2"). attr ("action", "./OrgRelation. aspx? ContactId = "+ temp. id +" & contactName = "+ temp. label );
$ ("# Form2"). submit ();
}
});
$ ("# SelCompate"). val ($ ("# hidcontactname"). val ())
});
</Script>
Source: "GetUser. ashx "refers to the address of the asynchronous request sent after the characters are typed, GetUser. ashx is responsible for providing the user information in Json format to the requesting client. The minLength of row 5th is an asynchronous request that starts to be sent when several characters are entered. The select: function (event, ui) {} is the selected event, ui. item indicates the selected item. The hidden domain storage value in line 8-9 is used to re-obtain information about the selected item after the page is refreshed, and re-write it back to the page for backup; line 10-11 is directed to OrgRelation with the id and label of the selected item as parameters. aspx sends a post request to display the query location of the selected user's Department to The ListBox control on the right of the page. Its server implementation is irrelevant to the content discussed in this article, the code will not be pasted out.
The complete code list on the page is as follows:
Copy codeThe Code is as follows: <% @ 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,
// The selected event is as follows:
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> edit the user department relationship </strong>
</Div>
<Div id = "main">
<Table align = "center">
<Tr>
<Td>
<Div>
<B> select a user: </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> select a department: </B>
</Div>
<Br/>
</Td>
<Td>
</Td>
<Td>
</Td>
</Tr>
<Tr>
& Lt; td valign = "top" width = "41%" & gt;
<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 = "add Department>" 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 = "<remove Department" 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 = "· return ·" BackColor = "# f8f8ff"/>
<Asp: Button ID = "btnSave" runat = "server" Text = "· Save ·" BackColor = "# f8f8ff"
Onclick = "btnSave_Click"/>
</Div>
</Div>
</Form>
</Body>
</Html>
2. Preparation of user data in Global. asax
Because the user data here does not change frequently, because the search requires frequent data requests from the server, the user data is stored in the Application, so that the user data is directly retrieved from the Application during the search, you do not need to query the database each time.
The Application object is assigned in the Application_Start event of the Global Application Global. asax. The Code is as follows:
Copy codeThe Code is as follows: void Application_Start (object sender, EventArgs e)
{
Application. Lock ();
Application ["User"] = GetUsers ();
Application. UnLock ();
}
In the GetUser method for getting user information, get the pinyin simplified code at the same time. The Code is as follows:Copy codeThe Code is as follows: 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>
/// Obtain a string set of Chinese Characters in pinyin, and combine the operators and voices to reconcile null values.
/// </Summary>
/// <Param name = "ch"> Chinese Character </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); // obtain the object containing Chinese Characters
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>
/// Obtain the first character string of the pinyin alphabet of a phrase)
/// </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 ();
}
For the consistency between the Application and the data in the database, a general processing program UpdateApplication can be provided. ashx is responsible for updating the Application (code and Global. asax is basically the same). When the database changes, access UpdateApplication. ashx updates the Application ["Contact"] object.
3. Data that meets the search criteria is returned in GetUser. ashx.
The server code list in GetUser. ashx in response to the search event is as follows:
Copy codeThe Code is as follows: <% @ WebHandler Language = "C #" Class = "GetUser" %>
Using System;
Using System. Web;
Using BLL;
Using System. Collections. Generic;
Using System. Text. RegularExpressions;
Using System. Web. Script. Serialization;
Using Microsoft. International. Converters. PinYinConverter;
Public class GetUser: JavaScriptSerializer, IHttpHandler
{
Public void ProcessRequest (HttpContext context)
{
Int I = 0;
List <string> strlist = context. Application ["User"] as List <string>;
String inputStr = context. Request. QueryString. Get ("term"). ToLower ();
List <UserItem> userList = new List <UserItem> ();
Foreach (string str in strlist)
{
String [] userArr = str. Split ('| ');
If (I <10)
{
Regex reg = new Regex (@ "^" + inputStr );
If (reg. IsMatch (userArr [2]) | reg. IsMatch (userArr [1])
{
UserItem item = new UserItem ();
Item. id = userArr [0];
Item. label = userArr [1];
Item. value = userArr [2];
UserList. Add (item );
I ++;
}
}
Else
{
Break;
}
}
Context. Response. ContentType = "application/json ";
String output = Newtonsoft. Json. JsonConvert. SerializeObject (userList );
Context. Response. Write (output );
}
Public bool IsReusable
{
Get
{
Return false;
}
}
}
Public class UserItem
{
Public string id {get; set ;}
Public string label {get; set ;}
Public string value {get; set ;}
}
The second row is the retrieval string inputstr entered in the text box. Here, we use a regular expression to retrieve records whose names start with inputstr (Chinese search) or the records starting with inputstr (pinyin search ). If you need the fuzzy search function, you can modify the Regular Expression of row 25th to Regex reg = new Regex (inputStr. If you need compound searches for more fields (such as the user's mobile phone number and email address), you only need to obtain the relevant field information when the Application assigns a value to the image, add matching items to the if judgment of 26 rows.
Here, UserItem is the class that provides Json objects for the page, label is a required field, and the content displayed in the search box is the value of this field. After obtaining a Qualified Data Set, use the SerializeObject method of Newtonsoft. Json. JsonConvert to serialize it and return it to the client.
At this point, the effect of the texture at the beginning of this article is realized.