I’ve been playing around with hooking up the JQuery AutoComplete widget with an ASP.NET Web Service. This is a really neat idea that adds a lot of whizzbang to a standard Web-based form. In theory one could also use ASP.NET UpdatePanel controls with traditional ASP.NET/HTML form controls, but I really wanted to look further into the JQuery Ajax functionality since this fits together very neatly with the JQuery AutoComplete widget.
I found three really good articles on the topic that I am listing below:
- Mudassar Khan’s ASP Snippets Blog article – Implement jQuery Autocomplete using Web Service in ASP.Net
- Andy Marshall’s article on CodeProject – Introduction to using jQuery with Web Services
- Luca Congiu’s article on MSDN – Use Jquery Autocomplete With Web Service (ASMX) DataSource
From reading the articles I have been able to adapt the information these authors presented into the logic I am looking for.
The Desired Functionality
Specifically what I am looking to do is to have a Web form with a text entry area that will offer a user suggestions for text while a user is typing. The options should be selectable and should pass an id value.
Furthermore, the suggestion list will kick in after the user has entered a minimum of two characters and will match anywhere within the database name field text for matches to show. To reduce lag and the amount of data being transmitted I am capping the returned results to a maximum of 500. Furthermore I am using the JSON protocol to keep the transferred data lightweight.
Setting up the ASP.NET Web Service
This seems like an interesting task with definite advantages when putting together Web form UIs.
Since I am quite familiar with ASP.NET, setting up the Web Service was a piece of cake. I’m still relatively new at JQuery syntax so this was a bit tougher to wrap my head around, but it seemed to fall into place nicely once I looked into it a bit.
For the sake of simplicity I won’t go into details on the SQL table structure and data. Let’s just imagine a simple table called namesTable that has an Id column and a Name column.
Also, don’t forget to add the database connection information into your Web.config file. For example it’ll go a little something like this:
<configuration>
<connectionStrings>
<add name=”ConnTestDb” connectionString=”Data Source=DBServer;Initial Catalog=DBName;Persist Security Info=True;User ID=TestUser;Password=TestPwd;” providerName=”System.Data.SqlClient”/>
</connectionStrings>
So far that wasn’t too difficult. Now we can set up the ASP.NET Web Service (called TestService) as follows:
Imports System.Web Imports System.Web.Services Imports System.Web.Services.Protocols Imports System.Data Imports System.Data.SqlClient Imports System.Web.Script.Services ' To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. ' <System.Web.Script.Services.ScriptService()> _ <WebService(Namespace:="http://tempuri.org/")> _ <WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _ <Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _ <ScriptService()> _ Public Class TestService Inherits System.Web.Services.WebService <WebMethod()> _ <ScriptMethod(ResponseFormat:=ResponseFormat.Json)> _ Public Function GetTestDetails(ByVal testString As String) As String() Dim lstResponse As New List(Of String)() Dim conn As SqlConnection Dim cmd As New SqlCommand Dim dtreader As SqlDataReader conn = New SqlConnection(ConfigurationManager.ConnectionStrings("ConnTestDb").ConnectionString) conn.Open() cmd.CommandType = CommandType.Text cmd.CommandText = "SELECT TOP 500 Id,Name FROM namesTable WHERE Name LIKE '%'+@testString+'%'" cmd.Connection = conn cmd.Parameters.AddWithValue("@testString", testString) dtreader = cmd.ExecuteReader While dtreader.Read() lstResponse.Add(String.Format("{0}-x-{1}", dtreader.Item("Id"), dtreader.Item("Name"))) End While cmd.Dispose() conn.Close() conn.Dispose() Return lstResponse.ToArray() End Function End Class
As you can see this doesn’t require too many modifications from a standard ASP.NET Web Service. To allow the class to be called from a client side script we add the <ScriptService()> _ tag above our class declaration. Then when we are setting up our WebMethod that handles the database query, we add the <ScriptMethod(ResponseFormat:=ResponseFormat.Json)> _ tag that specifies JSON as our output type.
Within the actual logic of the method you can see that we are calling the database directly through inline SQL. This may not be the proper way of handling a production-level solution, but is best to be able to show the logic of the example presented. Also note that while we are concatenating the JSON to be returned that we use a separator that is unlikely to exist natively in the text (-x-). This makes sure that we don’t get instances where the name value bleeds into the id and causes errors with the program’s logic.
Setting up the ASP.NET/JQuery Web Page
I have named the ASP.NET page TestPage.aspx and made it my default startup page in Visual Studio. I am calling Google’s publicly hosted JQuery and JQuery-UI Libraries so anyone looking at this example can simply copy and paste the page into their Web site without needing to download any JQuery files.
Here is the code to handle the presentation logic:
<%@ Page Language="VB" EnableEventValidation="false" EnableViewStateMac="false" ViewStateEncryptionMode="Never" %> <!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 runat="server"> <title></title> <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/base/jquery-ui.css" type="text/css" media="all" /> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js" type="text/javascript"></script> <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js" type="text/javascript"></script> <script type="text/javascript"> $(document).ready(function () { $("#<%=txtSearch.ClientID %>").autocomplete({ source: function (request, response) { $.ajax({ url: '<%=ResolveUrl("~/TestService.asmx/GetTestDetails") %>', data: "{ 'testString': '" + request.term + "'}", dataType: "json", type: "POST", contentType: "application/json; charset=utf-8", success: function (data) { response($.map(data.d, function (item) { return { label: item.split('-x-')[1], val: item.split('-x-')[0] } })) }, error: function (response) { alert(response.responseText); }, failure: function (response) { alert(response.responseText); } }); }, select: function (e, i) { $("#<%=hfId.ClientID %>").val(i.item.val); }, minLength: 2 }); }); </script> <script language="VB" Runat="server"> Protected Sub btnSubmit_Click(sender As Object, e As System.EventArgs) Dim intValue As String = hfId.Value Dim strSearchName As String = txtSearch.Text lblSearchResults.Text = String.Format("Searching for ID: {0} & VALUE: {1} ", intValue, strSearchName) End Sub </script> </head> <body> <form id="form1" runat="server"> <asp:TextBox ID="txtSearch" runat="server"></asp:TextBox> <asp:HiddenField ID="hfId" runat="server" /> <br /> <asp:Button ID="btnSubmit" runat="server" Text="Submit" onclick="btnSubmit_Click" /> <br /><asp:Label ID="lblSearchResults" runat="server" Text=""></asp:Label> </form> </body> </html>
As you can see, the JQuery hooks up the AutoComplete widget to the txtSearch TextBox control. The site URL and names of the ASP.NET controls are output dynamcially in the JQuery code via inline ASP.NET code.
The JQuery sets up an Ajax call to our Web Service and outputs failure or error alert messages if there is a problem. The parameter name that the Web Service is expecting is also important to set and populate. This is done in the data: parameter of the Ajax call. Likewise JSON is specified in the dataType option of the Ajax call.
If there are no problems with the Ajax call then the JSON returned from the Web Service is read and the Id/value pairs are split for presentation to the user. The minLength option is set to 2 so that the autocomplete logic only kicks in when the user has entered at least two characters into the search TextBox.
Finally, the submit button on the page has been set to read the value and id information that the user has selected. Naturally in a production environment there would be validation logic that would be associated with this button. In our case, though, the submit button populates an ASP.NET label control which simply outputs the Id and name values that the user has selected.
Summary
So in the end, this functionality is quite neat to put together and works flawlessly. The Ajax functionality exposed through the JQuery library is very useful and can be nicely hooked up with JQuery UI widgets and an ASP.NET backend. In this case it allows us to create a simple but powerful UI effect that let’s users of a Web page dynamically search valid data as they enter data into Web form fields.
I plan to continue to look into this technology mix with some more articles hopefully soon to some!
1 thought on “Using a JQuery AutoComplete Widget with an ASP.NET Web Service”