Friday 2 December 2011

JQuery Autocomplete in an ASP.NET page - The quick howto step by step

Today, i have the need to build quickly a lightweight web control using an 'autocomplete' style. Severals products in the market exist for this implementation :
- ultracombo from infragistics
- autocomplete for ajaxcontroltoolkit
- a jquery plugin as : autocomplete  . it will be shown in this post.

For this purpose, you need to download jquery autocomplete plugin available at http://jqueryui.com/download

1- Deselect all components
2- Select only the autocomplete plugins


3- Click on the download link on the rigth pane of the page ( not display in the screenshot).
It will package all the scripts, samples pages etc... refering this plugin.


In the visual studio, create a web application projet, add folder and files as shown in the screeshot




In this screeshot :
1- Create the folder 'script' and put all js script from the dowloaded package above.
   Those script are needed to run the autocomplete component

2- Create the folder 'style' and put all css from the download package
  Stylesheet to be used 

3- Create an aspx page named 'Json'
  The main page
4- Create an Handler1.ashx ( Generic Handler ) from Visual Studio Add item.
  An handler to handle all ajax requests, process request in server side and return the datas to clien.


In the page Json.aspx :


<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
    
    <link rel="stylesheet" href="../style/jquery.ui.all.css">
    <script type="text/javascript" src="../script/jquery-1.6.2.js"></script>
    <script type="text/javascript" src="../script/jquery.ui.core.js"></script>
    <script type="text/javascript" src="../script/jquery.ui.widget.js"></script>
    <script type="text/javascript" src="../script/jquery.ui.position.js"></script>
    <script type="text/javascript" src="../script/jquery.ui.autocomplete.js"></script>
   
    <script type="text/javascript">
        $(function() {
        $(".Form_Product").autocomplete({
                source: "Handler1.ashx",
                minLength: 2,
                select: function(event, ui) {
           
                }
            });
        });
    </script>
</head>
<body>
    <form id="Form" runat="server">  
    <div class="ui-widget">
    <label for="Item">Products : </label>
    <asp:TextBox id="Form_Product" class="Form_Product" runat="server" />       
    </div>
    <asp:HiddenField ID="Form_HiddenValue" runat="server" />   
    </form>
</body>
</html>


In the source parameter, i've define the handler.ashx to where the request is sended. 
The minLength parameter means that the request is fired once the user type 2 caracters in the input.
The select parameter is used to fire action on client side once the server response is received

The Form_Product textbox is the main input linked to the autocomplete feature.

Notice that I've defined a class named 'Form_Product' into it. 
If we look at the second line of the javascript code, i've used a jQuery selector 


Using a class selector $(".Form_Product") is more powerfull than using an Id selector $("#Form_Product") in the way that if the Textbox is embedded into a Master Page, the Id generated by asp.net is changed automatically depending on the hierachical level of the contentplaceholder. The class attribut of the Textbox will always be the same.


The div class="ui-widget" is not mandatory, I've put it for having a specific style.


The Form_HiddenValue is optional, it is used to store the content of the selected item if the page has to support a postback. I will not described that in this post.



That's all of the modification that we need to do in the aspx file.


Go to the code behin of the handle1.ashx and paste the code 


public class Handler1 : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "application/json"; //since i will use a json format as //response, it need to set the contentType to application/json.
            context.Response.ContentEncoding = System.Text.Encoding.UTF8;//will use UTF8 //encoding - optional
            Collection<Data> s = new Collection<Data>();//here I've create a class named Data - we will //see it later in this post
           // Add some value in the collection, noticed the property id and value of the object. They are //required to be set to make the auto mapping of autocomplete plugin. If omitted, the autocomplete //failed
            s.Add(new Data { id = "1", value = "987", Brand = "Apple" });
            s.Add(new Data { id = "2", value = "98765", Brand = "Windows" });
            s.Add(new Data { id = "3", value = "9876534", Brand = "Android" });   
 
// Using of the javascriptSerializer to transform the collection to json format - the input form the //textbox is retrieved by context.Request.QueryString["term"].Here I've used a Linq to filter the //hardcoded collected by the StartWith method.        
            JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
            context.Response.Write(jsonSerializer.Serialize(s.Where(v => v.value.StartsWith(context.Request.QueryString["term"])).ToList()));
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
//here is the Data class. Notice the id, value property. You can omit them in this class and use an anonymous type in the linq query but it's beyond of the scope.Also notice that the class is marked as Serializable to allow the json serialization 
    [Serializable]
    public class Data
    {
        public String id { get; set; }
        public String value { get; set; }
        public String Brand { get; set; }
    }
Now the test


Interpretation :
The autocomplete automatically maps the value property of the json string. In the screen below, the json format returned by the handler.


The textBox is filled by this value property. 


How to access the Brand property ?


In the function select body :


  <script type="text/javascript">
        $(function() {
        $(".Form_Product").autocomplete({
                source: "Handler1.ashx",
                minLength: 2,
                select: function(event, ui) {
            //HERE PUT 

                    alert(ui.item.id);
                    alert(ui.item.value);
               alert(ui.item.Brand); //Magic isn't it ???
                   
                }
            });
        });


The strength :This implementation suits very well in an mvc or mvvm implementation. the viewmodel return only the representation of the business and javascript will do the rest in the view layer.


Hope that this post was helpfull for you.

No comments:

Post a Comment