How to use Ajax auto complete in asp.net

3

In this time CMSN Software has decided to provide a little bit of advance tutorial. "How to use Ajax auto complete in asp.net" simply shows you how to implement auto complete text box in ASP.Net. Technically we are passing value to server side using simple Ajax request and then search inside a xml file using Linq to xml. Then format and display the response as a auto complete suggestions. As usual in this tutorial also CMSN Software shows how to use multiple technologies to accomplish same task.

In this tutorial you can get a clear idea about how to use
  • JavaScript
  • ASP.NET Ajax
  • jQuery
to implement auto complete text box in asp.net.
This sample shows you how to implement auto complete using JavaScript in ASP.Net.
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="HowToUseAjaxAutoComplete.aspx.cs"
    Inherits="JavaScriptSample.HowToUseAjaxAutoComplete" %>
 
<!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>How to use Ajax auto complete in asp.net || JavaScript Sample</title>
    <link href="Style/AutoComplete.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript">
 
        function fillWebsiteDetails(text, url) {
            /// <summary>
            /// fill website details when click on suggestions.
            /// </summary>
            document.getElementById('websiteUrl').innerHTML = url;
            document.getElementById('suggestions').style.display = 'none';
            document.getElementById('autoCompleteBox').value = text;
        }
        function getSuggestions(webSiteTitle) {
            /// <summary>
            /// Call suggestion web method via Ajax request
            /// </summary>
            if (window.XMLHttpRequest) {
                // for IE7+, Firefox, Chrome, Opera, Safari
                this.xmlhttp = new XMLHttpRequest();
            }
            else {
                // for IE6, IE5
                try {
                    this.xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
                } catch (e1) {
                    try {
                        // older version of Msxml
                        this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
                    } catch (e2) {
                        this.xmlhttp = null;
                    }
                }
            }
            xmlhttp.onreadystatechange = function () {
                /// <summary>
                /// Display suggestions when success
                /// </summary>
                if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                    // success Status                   
                    var xmlDoc = xmlhttp.responseXML;
                    document.getElementById('autoSuggestionsList').innerHTML = '';
                    var website = xmlDoc.getElementsByTagName("Websites");
                    if (website.length > 0) {
                        for (var i = 0; i < website.length; i++) {
                            document.getElementById('autoSuggestionsList').innerHTML +=
                            '<li onclick=fillWebsiteDetails(this.innerHTML,"' +
                            website[i].getElementsByTagName("NavigationLink")[0].childNodes[0].nodeValue + '");>'
                            + website[i].getElementsByTagName("Title")[0].childNodes[0].nodeValue + '</li>';
                        }
                        document.getElementById('suggestions').style.display = 'block';
                    }
                }
            }
            this.xmlhttp.open("GET""WebsiteList.asmx/WebsiteDetails?websiteTitle=" + webSiteTitle, true);
            this.xmlhttp.send();
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <input id="autoCompleteBox" type="text" onkeyup="getSuggestions(this.value);" />
        <div class="suggestionsBox" id="suggestions" style="display: none;">
            <ul id="autoSuggestionsList" class="suggestionList">
            </ul>
        </div>
        <div id="websiteUrl">
        </div>
    </div>
    </form>
</body>
</html>

In the previous tutorial of CMSN Software Tutorials ("How to call CSharp function in Ajax") JavaScript section We explained the basic steps of calling CSharp methods via Ajax request. The main difference here is we are passing parameter to the CSharp method. To accomplished that we send parameter as query string using open("GET", url, async) method of the XMLHttpRequest object. Then format the response from WebServise and display as suggestion. The response for this request is simple xml so we can parse that xml and get whatever details we want.

This sample shows you how to implement auto complete using in ASP.Net Ajax
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="HowToUseAjaxAutoComplete.aspx.cs"
    Inherits="MicrosoftAjaxSample.HowToUseAjaxAutoComplete" %>
 
<!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>How to use Ajax auto complete in asp.net | Microsoft Ajax Sample</title>
    <link href="Style/AutoComplete.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript">
        function fillWebsiteDetails(text, url) {
            /// <summary>
            /// fill website details when click on suggestions.
            /// </summary>
            document.getElementById('websiteUrl').innerHTML = url;
            document.getElementById('suggestions').style.display = 'none';
            document.getElementById('autoCompleteBox').value = text;
        }
 
        function getSuggestions(webSiteTitle) {
            /// <summary>
            /// get suggestions based on the entered text
            /// </summary>
            MicrosoftAjaxSample.WebsiteList.WebsiteDetails(webSiteTitle, OnComplete, OnFailer);
        }
 
        function OnComplete(result) {
            /// <summary>
            /// Display suggestions when success
            /// </summary>
            document.getElementById('autoSuggestionsList').innerHTML = '';
            var website = (typeof result) == 'string' ? eval('(' + result + ')') : result;
            if (website.length > 0) {
                for (var i = 0; i < website.length; i++) {
                    document.getElementById('autoSuggestionsList').innerHTML +=
                    '<li onclick=fillWebsiteDetails(this.innerHTML,"' + website[i].NavigationLink + '");>'
                    + website[i].Title + '</li>';
                }
                document.getElementById('suggestions').style.display = 'block';
            }
        }
 
        function OnFailer(result) {
            /// <summary>
            /// show error message when there is an error
            /// </summary>
            alert("Error: " + result.get_message());
        }
        
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="WebsiteDetailsScriptManager" runat="server">
        <Services>
            <asp:ServiceReference Path="~/WebsiteList.asmx" />
        </Services>
    </asp:ScriptManager>
    <div>
        <input id="autoCompleteBox" type="text" onkeyup="getSuggestions(this.value);" />
        <div class="suggestionsBox" id="suggestions" style="display: none;">
            <ul id="autoSuggestionsList" class="suggestionList">
            </ul>
        </div>
        <div id="websiteUrl">
        </div>
    </div>
    </form>
</body>
</html>

In the previous tutorial of CMSN Software Tutorials ("How to call CSharp function in Ajax") Asp.Net section we explained basic steps of calling CSharp methods using Script Manager. Nothing difference here other than passing the parameter to WebService method. Then format the response and display as suggestion. Response of this section is same as the CSharp typed list so we can access it same as in CSharp.

This sample shows you how to implement auto complete using jQuery in ASP.Net.
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="HowToUseAjaxAutoComplete.aspx.cs"
    Inherits="JquerySample.HowToUseAjaxAutoComplete" %>
 
<!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>How to use Ajax auto complete in asp.net | jQuery Sample</title>
    <link href="Style/AutoComplete.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
    <script type="text/javascript">
 
        $("#autoCompleteBox").live('keyup'function (event) {
            /// <summary>
            ///  call to web service and display suggestions.
            /// </summary>
            if ($(this).val().length == 0) {
                // Hide the suggestion box if text is empty.
                $('#suggestions').hide();
            } else {
                //get suggestions. 
                getWebsiteDetails("WebsiteList.asmx/WebsiteDetails",
                                    "{'websiteTitle':'" + $("#autoCompleteBox").val() + "'}",
                                    onRequestSuccess,
                                    onRequestFail);
            }
        });
 
        $('#autoCompleteBox').live('keydown'function (event) {
            /// <summary>
            ///  this is used to prevent the post back when hit enter button.
            /// </summary>
            if (event.keyCode == '13') {
                event.preventDefault();
            }
        });
 
        function getWebsiteDetails(url, data, successEvent, failerEvent) {
            $.ajax({
                /// <summary>
                ///  Perform an asynchronous HTTP (Ajax) request to get web site details
                /// </summary>
                type: "POST",
                url: url,
                data: data,
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: successEvent,
                failure: failerEvent
            });
        }
        function onRequestSuccess(response) {
            /// <summary>
            /// Display server time when success
            /// </summary>
            $('#autoSuggestionsList').empty();
            var website = (typeof response.d) == 'string' ? eval('(' + response.d + ')') : response.d;
 
            if (website.length > 0) {
                for (var i = 0; i < website.length; i++) {
                    $('#autoSuggestionsList').append($('<li/>').data('Uri', website[i].NavigationLink).click(function () {
                        $("#websiteUrl").text($(this).data('Uri'));
                        $('#suggestions').hide();
                        $("#autoCompleteBox").val($(this).text());
                    }).html(website[i].Title));
                }
                $('#suggestions').show();
            }
        }
        function onRequestFail(msg) {
            /// <summary>
            /// show error message when there is an error
            /// </summary>
           alert(msg.d);
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <input id="autoCompleteBox" type="text" />
        <div class="suggestionsBox" id="suggestions" style="display: none;">
            <ul class="suggestionList" id="autoSuggestionsList">
            </ul>
        </div>
        <div id="websiteUrl">
        </div>
    </div>
    </form>
</body>
</html>

In the previous tutorial of CMSN Software Tutorials ("How to call CSharp function in Ajax") jQuery section We explained the basic steps of calling CShaAjax request. CMSN Software use same technique here and pass a parameter as data. Then format the response and display it as suggestion. Response of this section is same as the CSharp typed list so we can access it same as in CSharp.

We have used following sample web service file to get suggestions via Ajax request.
//-----------------------------------------------------------------------
// <copyright file="WebsiteList.asmx.cs" company="CMSN Software">
//    Copyright © 2011  CMSN Software
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see http://www.gnu.org/licenses.
// </copyright>
//-----------------------------------------------------------------------
 
[module: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming""CA1704:IdentifiersShouldBeSpelledCorrectly", Scope = "namespace", Target = "JquerySample", MessageId = "Jquery", Justification = "jQuery is the correct naming")]
namespace JquerySample
{
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using System.Web;
    using System.Web.Services;
    using System.Xml.Linq;
    using System.Xml.Serialization;
 
    /// <summary>
    /// web service for get websites details.
    /// </summary>
    [WebService(Namespace = "http://cmsnsoftware.blogspot.com/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    [System.Web.Script.Services.ScriptService]
    public class WebsiteList : System.Web.Services.WebService
    {
        /// <summary>
        /// URL of the xml file
        /// </summary>
        private const string WebsiteDetailsXml = "WebsiteDetails.xml";
 
        /// <summary>
        /// Xml node for Websites
        /// </summary>
        private const string WebsitesNode = "Websites";
 
        /// <summary>
        /// Xml node for Website
        /// </summary>
        private const string WebsiteNode = "Website";
 
        /// <summary>
        /// Xml node for Website title
        /// </summary>
        private const string TitleNode = "Title";
 
        /// <summary>
        /// Xml node for Website URL
        /// </summary>
        private const string UriNode = "Uri";
 
        /// <summary>
        /// Get Web sites details from XML file.
        /// </summary>
        /// <param name="websiteTitle">The web site title.</param>
        /// <returns>list of matching web sites</returns>
        [WebMethod]
        public List<Websites> WebsiteDetails(string websiteTitle)
        {
            List<Websites> websitesList = new List<Websites>();
            Websites websiteList = new Websites();
 
            XDocument websitesXml = XDocument.Load(Server.MapPath(WebsiteDetailsXml));
            var websites = from website in websitesXml.Descendants(WebsitesNode).Elements(WebsiteNode)
                           where (website.Element(TitleNode).Value.ToUpperInvariant().Contains(websiteTitle.ToUpperInvariant())
                           || website.Element(UriNode).Value.ToUpperInvariant().Contains(websiteTitle.ToUpperInvariant()))
                           select new
                           {
                               title = website.Element(TitleNode).Value,
                               url = website.Element(UriNode).Value
                           };
 
            foreach (var website in websites)
            {
                websiteList.Title = website.title;
                websiteList.NavigationLink = website.url;
                websitesList.Add(websiteList);
            }
 
            return websitesList;
        }
    }
}

In this WebService file CMSN Software decided to explain bit advance technique to return data to client side. In the previous tutorial of CMSN Software Tutorials ("How to call CSharp function in Ajax") WebService we just return the server time as a string but in here CMSN Software shows you how to return advance data types and access it in client side. We used custom type list to return website details. The type "Websites" is a structure and it has properties to return "Title" and "NavigationLink" of the website.

Download tutorial

3 comments:

Duke -
what if a list of suggestion has > 100 records? It will take so long to load all records when a user enters data. How do we load > 100 records in a server cache? Thanks
Chamika -
Duke,
you can just change the linq query in web-service to get top 10 or whatever value you want. it will solve your problem. and no point to cache the result because we are searching on each letter input(lot of search criteria). for better performance you can simply cache the xml file.

Post a Comment