ASP.NET Autocomplete Textbox using jQuery, JSON, and AJAX

Description

– In this article, we will learn how to show icons in the textbox’s suggestions using jQueryUI Autocomplete widget and ASP.NET Web Service.

Requirement

– We need a textbox in which when a user types the name of a country, it automatically shows suggestions as soon as the user starts typing a word. Also with the suggestion, we want the country flag to appear against each country in the suggestion.

Solution:

Download Source Code in Visual Studio Here..

Step 1 – Download some sample images of flags of some countries from internet. I have already downloaded some of the images.

Step 2 – Create a table in a database that stores the path of flags along with the country names. Use the following SQL Script to achieve this.

CREATE DATABASE jQueryUIDemo
 
USE jQueryUIDemo
 
CREATE TABLE [dbo].[jQueryDemo] (
    [Id]          INT            IDENTITY (1, 1) NOT NULL,
    [CountryName] NVARCHAR (50)  NOT NULL,
    [IconPath]    NVARCHAR (MAX) NOT NULL,
    PRIMARY KEY CLUSTERED ([Id] ASC)
);
 
CREATE procedure [dbo].[spGetCountriesDetailsWithIcons]
@term nvarchar(max)
as
begin
	select * from jQueryDemo where CountryName like @term + '%'
end
 
SET IDENTITY_INSERT [dbo].[jQueryDemo] ON
INSERT INTO [dbo].[jQueryDemo] ([Id], [CountryName], [IconPath]) VALUES (1, N'Australia', N'/Icons/australia.gif')
INSERT INTO [dbo].[jQueryDemo] ([Id], [CountryName], [IconPath]) VALUES (2, N'Canada', N'/Icons/canada.gif')
INSERT INTO [dbo].[jQueryDemo] ([Id], [CountryName], [IconPath]) VALUES (3, N'China', N'/Icons/china.gif')
INSERT INTO [dbo].[jQueryDemo] ([Id], [CountryName], [IconPath]) VALUES (4, N'England', N'/Icons/england.gif')
INSERT INTO [dbo].[jQueryDemo] ([Id], [CountryName], [IconPath]) VALUES (5, N'India', N'/Icons/india.gif')
INSERT INTO [dbo].[jQueryDemo] ([Id], [CountryName], [IconPath]) VALUES (6, N'Ireland', N'/Icons/ireland.gif')
INSERT INTO [dbo].[jQueryDemo] ([Id], [CountryName], [IconPath]) VALUES (7, N'Malaysia', N'/Icons/malaysia.gif')
INSERT INTO [dbo].[jQueryDemo] ([Id], [CountryName], [IconPath]) VALUES (8, N'Mexico', N'/Icons/mexico.gif')
INSERT INTO [dbo].[jQueryDemo] ([Id], [CountryName], [IconPath]) VALUES (9, N'Nepal', N'/Icons/nepal.gif')
INSERT INTO [dbo].[jQueryDemo] ([Id], [CountryName], [IconPath]) VALUES (10, N'Pakistan', N'/Icons/pakistan.gif')
INSERT INTO [dbo].[jQueryDemo] ([Id], [CountryName], [IconPath]) VALUES (11, N'Poland', N'/Icons/poland.gif')
INSERT INTO [dbo].[jQueryDemo] ([Id], [CountryName], [IconPath]) VALUES (12, N'Portugal', N'/Icons/portugal.gif')
INSERT INTO [dbo].[jQueryDemo] ([Id], [CountryName], [IconPath]) VALUES (13, N'Russia', N'/Icons/russia.gif')
INSERT INTO [dbo].[jQueryDemo] ([Id], [CountryName], [IconPath]) VALUES (14, N'Spain', N'/Icons/spain.gif')
INSERT INTO [dbo].[jQueryDemo] ([Id], [CountryName], [IconPath]) VALUES (15, N'Sri Lanka', N'/Icons/sri_lanka.gif')
INSERT INTO [dbo].[jQueryDemo] ([Id], [CountryName], [IconPath]) VALUES (16, N'Turkey', N'/Icons/turkey.gif')
SET IDENTITY_INSERT [dbo].[jQueryDemo] OFF

Step 3 – Open Visual Studio and Create an Empty ASP.NET Web application.

1

1

Step 4 – Add a folder named “Icons” and copy all the downloaded images to it. Remember, the name of the folder should be same as that of the path that you have saved in the Database table.

Step 5 – Download jQueryUI Autocomplete Widget source files from jQueryUI official website or you can follow the steps to download from my previous article on jQueryUI Autocomplete widget. Copy this downloaded folder to the root directory of the application. We need only the reference of the following files in that downloaded folder.

1

Step 6 – Add a class file named “Countries.cs” and replace with the following code.

1

1

namespace jQueryUIAutocompleteWithIcons
{
    public class Countries
    {
        public int Id { getset; }
        public string CountryName { getset; }
        public string IconPath { getset; }
    }
}

Step 7 – Add the connection strings to connect to database in the web.config file.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
  </system.web>
  <connectionStrings>
    <add connectionString="Data Source=.; Database=jQueryUIDemo; Integrated Security=True" name="DBCS" providerName="System.Data.SqlClient"/>
  </connectionStrings>
</configuration>

Step 8 – Add an ASP.NET Web service file named “CountriesService.asmx” and replace with the following code.

1

1

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Web.Script.Serialization;
using System.Web.Services;
 
namespace jQueryUIAutocompleteWithIcons
{
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    [System.Web.Script.Services.ScriptService]
    public class CountriesService : System.Web.Services.WebService
    {
        [WebMethod]
        public void GetCountriesDetails(string term)
        {
            string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
 
            List<Countries> countries = new List<Countries>();
 
            using (SqlConnection con = new SqlConnection(CS))
            {
                SqlCommand cmd = new SqlCommand("spGetCountriesDetailsWithIcons", con);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.AddWithValue("@term", term);
                con.Open();
                SqlDataReader dr = cmd.ExecuteReader();
                while (dr.Read())
                {
                    Countries country = new Countries();
                    country.Id = Convert.ToInt32(dr["Id"]);
                    country.CountryName = dr["CountryName"].ToString();
                    country.IconPath = dr["IconPath"].ToString();
                    countries.Add(country);
                }
            }
            JavaScriptSerializer JS = new JavaScriptSerializer();
            Context.Response.Write(JS.Serialize(countries));
        }
    }
}

Press Ctrl + F5 to check that our service is working as expected or not. You will see the following Screen.

1

Click the link GetCountriesDetails which is the name of the method that we created in Service code. You will see the following.

1

When you enter some character and press invoke, it will fetch the data from database using the Stored procedure that we created in SQL.

1

Understanding the code of Web service.

  • We will use the auto implemented properties defined in Countries.cs class file.
  • In the web service we are using the simple ADO.NET connectivity to fetch data using Stored procedure.
  • The data that we get from database is stored in List object of Countries class. So, a list of countries is maintained in it.
  • At the end of code, we are using JavascriptSerializer Class’s object which will serialize all the list data into JSON format that we will use in our jQuery code to show suggestions in textbox.

Step 9 – Add a new Webform named “Demo.aspx” and add the reference of the following jQuery files to its head section.

1

Step 10 – Add the following code to HTML Source of Demo.aspx page.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Demo.aspx.cs" Inherits="jQueryUIAutocompleteWithIcons.Demo" %>
 
<!DOCTYPE html>
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <script src="jquery-ui-1.11.4.custom/external/jquery/jquery.js"></script>
    <script src="jquery-ui-1.11.4.custom/jquery-ui.js"></script>
    <link href="jquery-ui-1.11.4.custom/jquery-ui.css" rel="stylesheet" />
    <link href="jquery-ui-1.11.4.custom/jquery-ui.theme.css" rel="stylesheet" />
    <link href="jquery-ui-1.11.4.custom/jquery-ui.structure.css" rel="stylesheet" />
    <title>jQueryUI Demo</title>
    <script type="text/javascript">
        $(document).ready(function () {
            $("#countryInput").autocomplete({
                minLength: 1,
                source: function (request, response) {
                    $.ajax({
                        url: "CountriesService.asmx/GetCountriesDetails",
                        method: "post",
                        data: { term: request.term },
                        dataType: "json",
                        success: function (data) {
                            response(data);
                        },
                        error: function (err) {
                            alert(err);
                        }
                    });
                },
                focus: updateTextbox,
                select: updateTextbox
            }).autocomplete("instance")._renderItem = function (ul, item) {
                return $("<li>")
                    .append("<img class='imageClass' src=" + item.IconPath + " alt=" + item.CountryName + "/>")
                    .append('<a>' + item.CountryName + '</a>')
                    .appendTo(ul);
            };
            function updateTextbox(event, ui) {
                $(this).val(ui.item.CountryName);
                return false;
            }
        });
    </script>
    <style type="text/css">
        .imageClass {
            width16px;
            height16px;
            padding-right4px;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
        Enter Country Name :
            <input type="text" id="countryInput" />
    </form>
</body>
</html>

Step 11 – Verify that our Solution Explorer should look like the below image. I mean that all the below mentioned files/folder should be available.
SolutionExplorer
Step 12 – Now press Ctrl + F5 and you will see that our objective is completed.
1

1

Understanding the HTML and jQuery Code.

  • We have taken a textbox in the body of HTML page.
  • In jquery code, we have used some properties of AJAX and Autocomplete Widget, to understand their purposes, I have copied their definitions from jqueryui.com and jquery.com. So, please have a look at them.

Autocomplete widget properties and events:

  • minLength

Type: Integer
Default: 1
The minimum number of characters a user must type before a search is performed. Zero is useful for local data with just a few items, but a higher value should be used when a single character search could match a few thousand items.

  • source

Type: Array or String or Function( Object request, Function response( Object data ) )
Default: none; must be specified
Defines the data to use, must be specified.

  • response( event, ui )
    Type: autocompleteresponse

Triggered after a search completes, before the menu is shown. Useful for local manipulation of suggestion data, where a custom source option callback is not required. This event is always triggered when a search completes, even if the menu will not be shown because there are no results or the Autocomplete is disabled.
event
Type: Event ui
Type: Object content
Type: Array

Contains the response data and can be modified to change the results that will be shown. This data is already normalized, so if you modify the data, make sure to include both value and label properties for each item.

  • focus( event, ui )Type: autocompletefocus

Triggered when focus is moved to an item (not selecting). The default action is to replace the text field’s value with the value of the focused item, though only if the event was triggered by a keyboard interaction.
Canceling this event prevents the value from being updated, but does not prevent the menu item from being focused.

event
Type: Event ui
Type: Object item
Type: Object

The focused item.

  • _renderItem( ul, item )Returns: jQuery

Method that controls the creation of each option in the widget’s menu. The method must create a new <li> element, append it to the menu, and return it.

ul
Type: jQuery

The <ul> element that the newly created <li> element must be appended to.

item Type: Object label
Type: String

The string to display for the item.
value Type: String

The value to insert into the input when the item is selected.

  • select( event, ui )Type: autocompleteselect

Triggered when an item is selected from the menu. The default action is to replace the text field’s value with the value of the selected item.
Canceling this event prevents the value from being updated, but does not prevent the menu from closing.

event
Type: Event
ui
Type: Object
item
Type: Object
An Object with label and value properties for the selected option.

jquery AJAX properties and Events:

  • url

Type: String
A string containing the URL to which the request is sent.

  • method (default: ‘GET’)

Type: String
The HTTP method to use for the request (e.g. “POST”, “GET”, “PUT”). (version added: 1.9.0)

  • data

Type: PlainObject or String or Array

Data to be sent to the server. It is converted to a query string, if not already a string. It’s appended to the url for GET-requests. See processData option to prevent this automatic processing. Object must be Key/Value pairs. If value is an Array, jQuery serializes multiple values with same key based on the value of the traditional setting.

  • dataType (default: Intelligent Guess (xml, json, script, or html))

Type: String

The type of data that you’re expecting back from the server.

“json”: Evaluates the response as JSON and returns a JavaScript object. Cross-domain “json” requests are converted to “jsonp” unless the request includes jsonp: false in its request options. The JSON data is parsed in a strict manner; any malformed JSON is rejected and a parse error is thrown. As of jQuery 1.9, an empty response is also rejected; the server should return a response of null or {} instead.

  • success

Type: Function( Anything data, String textStatus, jqXHR jqXHR )
A function to be called if the request succeeds. The function gets passed three arguments: The data returned from the server, formatted according to the dataType parameter or the dataFilter callback function, if specified; a string describing the status; and the jqXHR (in jQuery 1.4.x, XMLHttpRequest) object. As of jQuery 1.5, the success setting can accept an array of functions. Each function will be called in turn. This is an Ajax Event.

  • error

Type: Function( jqXHR jqXHR, String textStatus, String errorThrown )

A function to be called if the request fails. The function receives three arguments: The jqXHR (in jQuery 1.4.x, XMLHttpRequest) object, a string describing the type of error that occurred and an optional exception object, if one occurred. Possible values for the second argument (besides null) are “timeout”, “error”, “abort”, and “parsererror”. When an HTTP error occurs, errorThrown receives the textual portion of the HTTP status, such as “Not Found” or “Internal Server Error.” As of jQuery 1.5, the error setting can accept an array of functions. Each function will be called in turn. Note: This handler is not called for cross-domain script and cross-domain JSONP requests. This is an Ajax Event.

Code Explanation:

  • At the very first, In ready function of jQuery, we are finding the textbox using its ID and to that we applied autocomplete function of jquery.
  • minLength tells that the minimum character to be entered by the user should be one.
  • source tells that what will be the source for autocomplete feature to work. So, we created a function that sends the user entered value to our web service which expects a parameter called “term”. All this will occur at the request end. When the service completes its works we specify the method as ‘post’ which will only work when we get the response from the web service. That’s why the function here has two parameters i.e. request and response.
  • As our web service is returning that data in JSON format, so we specify datatype as JSON.
  • The data is term that we send to the service.
  • If the data is success, then we return back data in the function and send it to response parameter of source function.
  • If the error occurs, it will show a javascript alert.
  • Focus and select will keep the focus on textbox. This is implemented to show the data in textbox even if we hover mouse cursor over. For this we created a separate function which shows the hovered/selected list item of autocomplete in the textbox.
  • Again we call autocomplete function, to that we call _renderItem method which creates a list of returned data in <li> tag format.
  • renderItem expects two parameters, ul and item. So, we returned a <li> tag using jQuery and to that we append image tag which shows the image.
  • to the above, we again append, the name of country.
  • and we add all this appended data to <ul> and returned the item.
  • We also added some style to set the width and height of image, because image can be of different sizes.
Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s