Create Autocomplete Using Ajax and jQuery

  • Web Methods in ASP.NET
  • JavaScript
  • jQuery
  • Ajax using jQuery
  • HTML

Here I have implemented Auto Complete using jQuery Ajax and Web Methods.

For a better understanding I have divided the article into the following 5 parts:
  1. HTML
  2. Web Method
  3. Ajax (Sync)
  4. Rendering HTML with Data
  5. Hi-lighting the typed text

First  we start with the HTML. Here I am using a TextBox as my input. That is obvious, but with an attribute autocomplete="off". When the autocomplete is on, the browser automatically completes values based on values that the user has entered before which is undesirable in this case, hence we switch it off.
Now to display the data to be Auto-Completed I have used the HTML tag <ul> as in the following:
  1. <div>  
  2.      <asp:TextBox runat="server" ClientIDMode="Static"   ID="txtCustomer" list="CustomerList" Style="height: 25px; width: 264px;" autocomplete="off" />  
  3.         <ul class="autocomplete autocomplete1" id="ddlItem">  
  4.         </ul>  
  5. </div> 
2  Web Methods

Here I have made a Web Method called GetData(). By declaring the function as a WebMethod we are exposing the Server-Side function such that the method can be called from a remote web client.
A The scope of method should be Public
B The methods should be declared static

(Or else you won't be able to call the method )
  1. [WebMethod]  
  2.     public static string GetData()//method that is called in the Ajax returns JSON String
  3.     {  
  4.         DataTable dt = new DataTable();  
  5.         dt.Columns.Add("Name");  
  6.         dt.Rows.Add("Ajith");  
  7.         dt.Rows.Add("Arun");  
  8.         dt.Rows.Add("Suraj");  
  9.         dt.Rows.Add("Pankaj");  
  10.         dt.Rows.Add("Yogesh");  
  11.         return ConvertDataTabletoString(dt);  
  12.     }  
  14.     public static string ConvertDataTabletoString(DataTable dt) //Function Used to convert DataTable to Json String  
  15.     {  
  16.         System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();  
  17.         List<Dictionary<stringobject>> rows = new List<Dictionary<stringobject>>();  
  18.         Dictionary<stringobject> row;  
  19.         foreach (DataRow dr in dt.Rows)  
  20.         {  
  21.             row = new Dictionary<stringobject>();  
  22.             foreach (DataColumn col in dt.Columns)  
  23.             {  
  24.                 row.Add(col.ColumnName, dr[col]);  
  25.             }  
  26.             rows.Add(row);  
  27.         }  
  28.         return serializer.Serialize(rows);  
  30.     } 

Here I am making a Synchronous Ajax call to a web method created above. Here I emphasize that I am making a Synchronous Ajax because, setting async to false means that the statement we are calling must complete before the next statement in your function can be called. If you set async: true then that statement will begin it's execution and the next statement will be called regardless of whether the async statement has been completed. The browser freezes until the time the Ajax call is completed.
  1. $.ajax({    
  2.           type: "POST",//Post Method    
  3.           url: 'Default.aspx/GetData',//URL    
  4.           data: '{}',    
  5.           async: false,//synchronous Call     
  6.           contentType: "application/json; charset=utf-8",   
  7.           dataType: "json",    
  8.           success: function (response) {  //callback function on Success  
  9.               BindCustomerData(response.d);    
  10.           },    
  11.           failure: function (response) {    
  12.               alert(response.d);  //alerts on failure  
  13.           }    
  14.       });   
4 Rendering HTML with Data

On Success the Ajax calls a Call Back function BindCustomerData that fills the <ul> with data in the form of <li>.
Now that we have loaded the data from the web method on the form to the <ul> in its HTML, all we need to do is to hide all the unmatching data and show the matching data.
How I have implemented it you can find it in the code given below.
5 Hi-lighting the typed text

By now the auto-complete had almost started working. But still, I found something missing. I wacked my head for nearly 2 days and got nothing, then a colleague of mine gave me the idea of Hi-lighting the text being typed in the TextBox and he suggested me to use a jQuery plugin jQuery.highlight.js that he used to Hi-light matching text in a GridView.
Now using this JavaScript hi-lighting the text is as simple as the syntax given below.
  1. $(this).unhighlight();//To unhighlight  
  2. $(this).highlight($('#txtCustomer').val());//To highlight the text that is being typed  
Complete Code
  1. $(document).ready(function (jQuery) {  
  2.             $.ajax({  
  3.                 type: "POST",//Post Method  
  4.                 url: 'Default.aspx/GetData',//URL  
  5.                 data: '{}',  
  6.                 async: false,//synchronous Call   
  7.                 contentType: "application/json; charset=utf-8",  
  8.                 dataType: "json",  
  9.                 success: function (response) {  
  10.                     BindCustomerData(response.d);  
  11.                 },  
  12.                 failure: function (response) {  
  13.                     alert(response.d);  
  14.                 }  
  15.             });  
  17.             $('#txtCustomer').keyup(function () {  
  18.                 if ($(this).val() == '') {  
  19.                     $("#ddlItem > li").hide(); // Hides all <li> if the input text is blank    
  20.                     BindCustomerData();  
  21.                 }  
  22.                 else {  
  23.                     var filter = $(this).val();  //gets value of the textbox in var filter  
  24.                     //now using .each() we search for text in <li> matching text in var filter  
  25.                     $("#ddlItem li").each(function () {  
  26.                         //the .search() is a javascript function which returns the postion where the match is found  
  27.                         //the new RegExp(filter, "i") is a Regular Expression Filter which helps in filtering text on the  
  28.                         //bases of the match found in var filter and the <li>  
  29.                         //The "i" in RegExp(filter, "i") denotes that the filter is case-insensitve (won't check the case of text)  

  30.                         //you could also use "gi" which perform a global match (find all matches rather than stopping after the first match)   
  31.                         //So if the search find a match it will return value greater than -1  
  32.                         if ($(this).text().search(new RegExp(filter, "gi")) < 0) {  
  33.                             $(this).hide();//Hides the <li>  
  34.                         } else {  
  35.                             $(this).show();//Shows the <li>  
  36.                             $(this).unhighlight();//Initally unhighlight   
  37.                             $(this).highlight($('#txtCustomer').val());//To highlight the text that is being typed   
  38.                         }  
  39.                     });  
  40.                 }  
  41.             });  
  42.         });  
  44.         function BindCustomerData(data) {  
  45.             var ddl = $('#ddlItem').get(0);//Get HTML Element <ul> with ID ddlItem  
  46.             data = JSON.parse(data);  //parse Data string into Json  
  47.             ddl.innerHTML = ""//Removes all <li> in <ul>  
  48.             var opt = "";  
  49.             for (var i = 0; i < data.length; i++) {  
  50.                 opt += "<li onclick='javascript:SelectEvent(\"" + data[i].Name + "\");' >" + data[i].Name + "</li>";  //Create <li> to be added in <ul>  
  51.             }  
  52.             ddl.innerHTML = opt;  
  53.         }  
  55.         //this function is invoked when a particular <li> is clicked  
  56.         function SelectEvent(name) {   
  57.             //the function accepts the value to be add to the textbox in its parameter  
  58.             $('#txtCustomer').val(name);  
  59.             $("#ddlItem > li").hide();//once the value of the textbox is changed all <li>'s are hidden  
  60.         } 
So here we have finished making an Autocomplete TextBox.
Please do not forget to provide your valuable suggestions and feel free to ask queries.
That's all for this article, will see you in some other article. Until then,
Keep Learning...