AutoComplete Textbox in MVC3 Razor using jQuery and jSon



  1. In this article we will see how to implement autocomplete functionality in MVC3 Razor.
  2. We will use jQuery, ajax and jSon to achieve this implementation.
  3. We are using hard coded array of value which will be queried based on user's input in the textbox.
  4. We will use keyup event of jQuery to capture user's typed character or string.
  5. This string is searched in the array result and then the result is shown as autocomplete list.
Following are the steps :

Controller :

[HttpPost]
        public ActionResult RemoteData(string query)
        {
            List listData = null;
            //checking the query parameter sent from view. If it is null we will return null else we will return list based on query.
            if (!string.IsNullOrEmpty(query))
            {
                //Created an array of players. We can fetch this from database as well.
                string[] arrayData = new string[] { "Fabregas", "Messi", "Ronaldo", "Ronaldinho", "Goetze", "Cazorla", "Henry", "Luiz", "Reus", "Neur", "Podolski" };
                
                //Using Linq to query the result from an array matching letter entered in textbox.
                listData = arrayData.Where(q => q.ToLower().Contains(query.ToLower())).ToList();
            }

            //Returning the matched list as json data.
            return Json(new { Data = listData });
        }

The above method returns the list of result. The input entered in textbox is sent as parameter to this method using ajax post. In this method we have created an array of players. This array is searched for result based on user's input. We have used linq to query the result. The result is captured in the list and list is returned as jSon result. We can also use database instead of array for data source.


View :



@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Index</h2>

<style>
    #targetUL
    {
     width: 110px;
        border: 1px solid silver;
        margin-top: 2px;
        list-style: none;
    }
    #targetUL li
    {
        margin-left: -40px;
        border-bottom: 1px solid silver;
        height: 26px;
        padding-left: 5px;
        padding-top : 8px;
        cursor:pointer;
    }
 </style>

<div id="targetDiv">
<input type="text" id="target" />
</div>


<script type="text/javascript">
    $(document).ready(function () {

        //We have used keyup event to track the user enter value in the textbox.
        $("#target").keyup(function () {
            //Fetching the textbox value.
            var query = $(this).val();
            //Calling GetItems method.
            getItems(query);
        });

        function getItems(query) {

            //Here we are using ajax get method to fetch data from the list based on the user entered value in the textbox.
            //We are sending query i.e textbox as data.
            $.ajax({
                url: '@Url.Action( "RemoteData", "AutoComplete")',
                data: { "query": query },
                type: 'POST',
                dataType: 'json',
                success: function (response) {
                    if (response.Data != null) {
                        if ($("#targetUL") != undefined) {
                            //If the UL element is not null or undefined we are clearing it, so that the result is appended in new UL every next time.
                            $("#targetUL").remove();
                        }
                        //assigning json response data to local variable. It is basically list of values.
                        data = response.Data;
                        //appending an UL element to show the values.
                        $("#targetDiv").append($("<ul id='targetUL'></ul>"));
                        //Removing previously added li elements to the list.
                        $("#targetUL").find("li").remove();
                        //We are iterating over the list returned by the json and for each element we are creating a li element and appending the li element to ul element.
                        $.each(data, function (i, value) {
                            //On click of li element we are calling a method.
                            $("#targetUL").append($("<li class='targetLI' onclick='javascript:appendTextToTextBox(this)'>" + value + "</li>"));

                        });
                    }
                    else {
                        //If data is null the we are removing the li and ul elements.
                        $("#targetUL").find("li").remove();
                        $("#targetUL").remove();
                    }
                },
                error: function (xhr, status, error) {
                }
            });
        }
    });

    //This method appends the text oc clicked li element to textbox.
    function appendTextToTextBox(e) {
        //Getting the text of selected li element.
        var textToappend = e.innerText;
        //setting the value attribute of textbox with selected li element.
        $("#target").val(textToappend);
        //Removing the ul element once selected element is set to textbox.
        $("#targetUL").remove();
    }
 </script>

In the view we have defined script section. We have used keyup jQuery event to capture the user's entered value as soon as user enter something in the textbox. The textbox value is then posted to action method in the controller to query the user's input and to get the result. In order to show the result, we have appended an ul element to the div and each returned result is then appended in the ul as li element. We have used CSS to give it a proper look. This code works look wise best in chrome.

UI :




AutoComplete with scrollbar :

We can introduce scroll bar to handle long list of result. We need to set maximum height for the UL element and use the overflow property to show the scrollbar. 




#targetUL
    {
     width: 110px;
        border: 1px solid silver;
        margin-top: 2px;
        list-style: none;
        max-height:300px;
        overflow:auto;
    }

We have set the maximum height and set the overflow property to auto. When the height of the list increases the specified maximum height, scrollbar is used to show the extended result.

Screenshot :




Thus we have applied scrollbar to the autocomplete list.
Thus we have created our own custom autocomplete textbox which functions similar to jQuery Autocomplete.

9 comments:

  1. Nice work :) cheer

    ReplyDelete
  2. Good and fantastic...Please do it continue i think this will help fresher very much..Thanks

    ReplyDelete
  3. very good work!! appreciate your efforts

    ReplyDelete
  4. I would suggest the following improvement:
    FROM: if (response.Data != null) {
    TO: if (response.Data != null && !$.isEmptyObject(response.Data)) {

    This way if the user clears out the text to search by, a leftover targetUL is not accidently remaining in the div.

    ReplyDelete
  5. Thanks Luke for your suggestion.

    ReplyDelete
  6. Hi,
    I tried adding a model and it returns model name instead of data

    ReplyDelete