Lâu lâu mới viết một bài viết về .Net, cũng vì chủ đề này rất hay nên mình sẽ chọn bài này để viết. Nói qua về cái ứng dụng này, nó sẽ giúp bạn có được một control search giống với khi ta search trên Google để bổ sung vào Project của bạn cho đẹp hơn và nhẹ hơn.
Giới thiệu về ứng dụng
Bình thường, hầu hết nhiều website thực hiện tìm kiếm theo truy vấn “like” trong database như sau
1
| select * from book where bookName like '%all keywords come from user interface%' |
Tuy nhiên, điều này sẽ rất khó khăn nếu như chúng ta làm với một hệ thống có nhiều hàng trong một database lớn. Và bài báo này cũng sẽ chỉ làm trên một bộ dữ liệu nhỏ, để nhằm mục đích mô phỏng cách hoạt động của nó trong .Net ra làm sao (xin xem thêm bài Autocomplete search với Webservice và Jquery), hy vọng các bạn có thể giúp tôi hoàn thiện nó hơn, cải tiến nó hơn.
Cách code
Trước tiên chúng ta vào SQL server để tạo một database cho bài test này nhé
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| ------------------ step 1 ----------- SET ANSI_PADDING ON GO CREATE TABLE [dbo].[book]( [bookNo] [int] IDENTITY(1,1) NOT NULL, [bookName] [varchar](500) NULL, CONSTRAINT [PK_book] PRIMARY KEY CLUSTERED ( [bookNo] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO SET ANSI_PADDING OFF GO ------------------ /step 1 ----------- |
Add tiếp thêm vài row dữ liệu nữa
1
2
3
4
5
6
7
8
9
10
11
12
| ------------------ step 2 ----------- insert into book(bookName) values( 'mathematics question bank' ) insert into book(bookName) values( 'mathematics questions' ) insert into book(bookName) values( 'physics question bank' ) insert into book(bookName) values( 'mathematics question with solutions' ) insert into book(bookName) values( 'chemistry question bank' ) insert into book(bookName) values( 'chemistry questions wit detailed solutions' ) insert into book(bookName) values( 'physics questions' ) insert into book(bookName) values( 'detaied solutions of mathematics questions' ) insert into book(bookName) values( 'example of mathematics questions' ) insert into book(bookName) values( 'detailed mathematics' ) ------------------ /step 2 ----------- |
Vào trong web.config, thêm một chuỗi kết nối
1
| <add name= "connStr" connectionString= "SERVER =.\SQLEXPRESS2008; database=testDB; user id=sa; pwd=yourPwd" /> |
Và tiếp theo là ra ngoài giao diện, tạo một cái giao diện như hình dưới đây
Để cho textbox hoạt động việc autocomplete thì chúng ta thêm đoạn mã sau
Để cho textbox hoạt động việc autocomplete thì chúng ta thêm đoạn mã sau
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
| ------------------ step 4 ----------- <asp:autocompleteextender ID= "AutocompleteextenderBook" runat= "server" TargetControlID= "TBbookName" BehaviorID= "AutoCompleteExBook" OnClientItemSelected= "aceBook_itemSelected" ServicePath= "AutoComplete.asmx" ServiceMethod= "GetBookList" MinimumPrefixLength= "3" CompletionInterval= "1" UseContextKey= "True" EnableCaching= "true" CompletionListCssClass= "autocomplete_completionListElement" CompletionListItemCssClass= "autocomplete_listItem" CompletionListHighlightedItemCssClass= "autocomplete_highlightedListItem" DelimiterCharacters= "" > <Animations> <OnShow> <Sequence> <%-- Make the completion list transparent and then show it --%> <OpacityAction Opacity= "0" /> <HideAction Visible= "true" /> <%--Cache the original size of the completion list the first time the animation is played and then set it to zero --%> <ScriptAction Script=" // Cache the size and setup the initial size var behavior = $find ( 'AutoCompleteExBook' ); if (!behavior._height) { var target = behavior.get_completionList(); behavior._height = target.offsetHeight - 2; target.style.height = '0px' ; }" /> <%-- Expand from 0px to the appropriate size while fading in --%> <Parallel Duration= ".4" > <FadeIn /> <Length PropertyKey= "height" StartValue= "0" EndValueScript= "$find('AutoCompleteExBook')._height" /> </Parallel> </Sequence> </OnShow> <OnHide> <%-- Collapse down to 0px and fade out --%> <Parallel Duration= ".4" > <FadeOut /> <Length PropertyKey= "height" StartValueScript= "$find('AutoCompleteExBook')._height" EndValue= "0" /> </Parallel> </OnHide> </Animations> </asp:autocompleteextender> ------------------ /step 4 ----------- |
Trong đó
- ServicePath=”AutoComplete.asmx”
- ServiceMethod=”GetBookList”
- OnClientItemSelected=”aceBook_itemSelected”
Autocomplete.asmx là một web service bao gồm hàm GetBookList dành cho việc kích hoạt sự kiện Onchangecủa textbox. Sau khi add xong, thì web service thì gọi ra như sau
1
| [System.Web.Script.Services.ScriptService] |
Dưới đây là hàm GetBookList
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| //------------------ step 5 ----------- [WebMethod] public string[] GetBookList(string prefixText, int count ) { // this query could be run as stored procedure string sql = " select bookNo, bookName" + " from book " + " where " + " bookName like @par1 " + " order by bookName" ; //------------- SQLandParameters sqlObj = new SQLandParameters(); sqlObj.SQL = sql; sqlObj.parameters.Add( "@par1" , prefixText + "%" ); //------------- DataTable dt = Provider.execMySQL(sqlObj); //----------------------------------- List<string> custList = new List<string>(); string custItem = string. Empty ; for (int i = 0; i < dt.Rows. Count ; i++) { custItem = AutoCompleteExtender.CreateAutoCompleteItem( dt.Rows[i][ "bookName" ].ToString(), dt.Rows[i][ "bookNo" ].ToString()); custList.Add(custItem); } //----------------------------------- return custList.ToArray(); } //------------------ /step 5 ----------- |
Ngoài ra còn một số class đơn giản cho việc tạo kết nối, truy suất tới database nữa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| ------------------ step 6 ----------- public static DataTable execMySQL(SQLandParameters sqlObj) { DataTable dt = new DataTable(); string connStr = System.Configuration.ConfigurationManager.ConnectionStrings[ "connStr" ].ToString(); SqlConnection conn = new SqlConnection(connStr); SqlDataAdapter da = new SqlDataAdapter(sqlObj.SQL, conn); foreach (KeyValuePair<string, string> item in sqlObj.parameters) { da.SelectCommand.Parameters.AddWithValue(item.Key.ToString(), item.Value.ToString()); } da.SelectCommand.CommandType = CommandType.Text; conn.Open(); da.Fill(dt); conn.Close(); return dt; } ------------------ /step 6 ----------- |
1
2
3
4
5
6
7
8
9
10
11
12
13
| //------------------ step 7 ----------- <script type= "text/javascript" > function aceBook_itemSelected(sender, e) { if (e.get_value() == null) return false; var iSearchbtn = $get ( '<%= btnSearch.ClientID %>' ); iSearchbtn.focus(); __doPostBack(iSearchbtn, 'OnClick' ); var iSearcBox = $get ( '<%= TBbookName.ClientID %>' ); iSearcBox.focus(); } </script> //------------------ /step 7 ----------- |
Vậy là xong cơ bản rồi, cuối cùng còn thêm hàm sử lý sự kiện click button Search nữa là xong nhỉ
1
2
3
4
5
6
7
8
9
| //------------------ step 8 ----------- protected void btnSearch_Click(object sender, EventArgs e) { SQLandParameters SQLobj = GoogleLikeSearchLib.GenerateSQL(TBbookName.Text.Trim(), "book" , "bookName" , "bookNo" ); dgv1.DataSource = Provider.execMySQL(SQLobj); dgv1.DataBind(); } //------------------ /step 8 ----------- |
Khi button search được click thì trong SQL câu lệnh truy vấn được generate ra như sau
1
2
3
4
5
6
7
8
9
10
| select distinct t1.bookNo, t1.bookName, max(t1.myRank) myRank from ( select b.*, 2 myRank from book b where bookName like '%mathematics%' and bookName like '%questions%' union select b.*, 1 myRank from book b where bookName like '%mathematics%' union select b.*, 1 myRank from book b where bookName like '%questions%' ) t1 group by t1.bookName, t1.bookNo order by max(t1.myRank) desc |
Kết quả nhận được trong SQL
Comments[ 0 ]
Đăng nhận xét