In this article I will explain how to configure jQuery Autocomplete TextBox with ASP.Net Web Services to allow user select multiple word (multi word) from the Autocomplete List.
I have already wrote article on jQuery Autocomplete using ASP.Net Generic Handler
 
Database
For database I am using the Microsoft’s Northwind Database. You can download the same using the link below
 
Building the Web Service
Below is the code for the web service which will handle the jQuery Autocomplete calls and will return the matching records from the Customers table of the Northwind database.
The select query gets the Name and the ID of the customer that matches the prefix text.
The fetched records are processed and the Key Value Pair is created by appending the Id to the Name field in the following format {0}-{1} where is the {0} Name and {1} is the ID.
Since jQuery Autocomplete will allow to select multiple selections, hence we will need to take precautions that the existing searched Customers are excluded from the new search. To accomplish this functionality, I have made use of an array which stores the terms to be excluded and they are then excluded
C#
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Services;
using System.Data.SqlClient;
using System.Configuration;
using System.Web.Script.Services;
using System.Linq;
 
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class Service : System.Web.Services.WebService {
 
    public Service () {
 
        //Uncomment the following line if using designed components
        //InitializeComponent();
    }
 
    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public string[] GetCustomers(string prefix)
    {
        List<string> customers = new List<string>();
        using (SqlConnection conn = new SqlConnection())
        {
            List<string> terms = prefix.Split(',').ToList();
            terms = terms.Select(s => s.Trim()).ToList();
 
            //Extract the term to be searched from the list
            string searchTerm = terms.LastOrDefault().ToString().Trim();
 
            //Return if Search Term is empty
            if (string.IsNullOrEmpty(searchTerm))
            {
                return new string[0];
            }
 
            //Populate the terms that need to be filtered out
            List<string> excludeTerms = new List<string>();
            if (terms.Count > 1)
            {
                terms.RemoveAt(terms.Count - 1);
                excludeTerms = terms;
            }
 
            conn.ConnectionString = ConfigurationManager
                    .ConnectionStrings["constr"].ConnectionString;
            using (SqlCommand cmd = new SqlCommand())
            {
                string query = "select ContactName, CustomerId from Customers where " +
                "ContactName like @SearchText + '%'";
 
                //Filter out the existing searched items
                if (excludeTerms.Count > 0)
                {
                    query += string.Format(" and ContactName not in ({0})", string.Join(",", excludeTerms.Select(s => "'" + s + "'").ToArray()));
                }
                cmd.CommandText = query;
                cmd.Parameters.AddWithValue("@SearchText", searchTerm);
                cmd.Connection = conn;
                conn.Open();
                using (SqlDataReader sdr = cmd.ExecuteReader())
                {
                    while (sdr.Read())
                    {
                        customers.Add(string.Format("{0}-{1}", sdr["ContactName"], sdr["CustomerId"]));
                    }
                }
                conn.Close();
            }
            return customers.ToArray();
        }
    }
}
 
VB.Net
Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.Web.Script.Services
Imports System.Data.SqlClient
Imports System.Collections.Generic
Imports System.Linq
 
' To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
' <System.Web.Script.Services.ScriptService()> _
<WebService(Namespace:="http://tempuri.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
<ScriptService()> _
Public Class Service
    Inherits System.Web.Services.WebService
 
    <WebMethod()> _
    <ScriptMethod(ResponseFormat:=ResponseFormat.Json)> _
    Public Function GetCustomers(prefix As String) As String()
        Dim customers As New List(Of String)()
        Using conn As New SqlConnection()
            Dim terms As List(Of String) = prefix.Split(","c).ToList()
            terms = terms.Select(Function(s) s.Trim()).ToList()
 
            'Extract the term to be searched from the list
            Dim searchTerm As String = terms.LastOrDefault().ToString().Trim()
 
            'Return if Search Term is empty
            If String.IsNullOrEmpty(searchTerm) Then
                Return New String(-1) {}
            End If
 
            'Populate the terms that need to be filtered out
            Dim excludeTerms As New List(Of String)()
            If terms.Count > 1 Then
                terms.RemoveAt(terms.Count - 1)
                excludeTerms = terms
            End If
 
            conn.ConnectionString = ConfigurationManager.ConnectionStrings("constr").ConnectionString
            Using cmd As New SqlCommand()
                Dim query As String = "select ContactName, CustomerId from Customers where " + "ContactName like @SearchText + '%'"
 
                'Filter out the existing searched items
                If excludeTerms.Count > 0 Then
                    query += String.Format(" and ContactName not in ({0})", String.Join(",", excludeTerms.[Select](Function(s) "'" + s + "'").ToArray()))
                End If
                cmd.CommandText = query
                cmd.Parameters.AddWithValue("@SearchText", searchTerm)
                cmd.Connection = conn
                conn.Open()
                Using sdr As SqlDataReader = cmd.ExecuteReader()
                    While sdr.Read()
                        customers.Add(String.Format("{0}-{1}", sdr("ContactName"), sdr("CustomerId")))
                    End While
                End Using
                conn.Close()
            End Using
            Return customers.ToArray()
        End Using
    End Function
End Class
 
 
Client Side Implementation
Populating the AutoComplete list
In the client side implementation the data received from the server is processed in the success event handler. A loop is executed for each received item in the list of items and then an object with text part in the label property and value part in the val property is returned.
 
Configuring AutoComplete to allow Multiple Word Selections
In order to allow multiple words in jQuery Autocomplete, inside the Autocomplete Select event handler we need to restore the previously selected items inside the Autocomplete TextBox separated by comma.
 
Storing the Value part when item is selected
In the select event handler of the jQuery Autocomplete I am storing the value (Here Customer ID) in the hfCustomerId Hidden Field so that it can be fetched server side. Since we are allowing multiple word selections we will also need to store multiple Ids, hence Ids too are stored comma separated like the text part.
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"
type = "text/javascript"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"
type = "text/javascript"></script>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css"
rel = "Stylesheet" type="text/css" />
<script type="text/javascript">
    $(document).ready(function () {
        $("#<%=txtSearch.ClientID %>").autocomplete({
            source: function (request, response) {
                $.ajax({
                    url: '<%=ResolveUrl("~/Service.asmx/GetCustomers") %>',
                    data: "{ 'prefix': '" + request.term + "'}",
                    dataType: "json",
                    type: "POST",
                    contentType: "application/json; charset=utf-8",
                    success: function (data) {
                        response($.map(data.d, function (item) {
                            return {
                                label: item.split('-')[0],
                                val: item.split('-')[1]
                            }
                        }))
                    },
                    error: function (response) {
                        alert(response.responseText);
                    },
                    failure: function (response) {
                        alert(response.responseText);
                    }
                });
            },
            select: function (e, i) {
                var text = this.value.split(/,\s*/);
                text.pop();
                text.push(i.item.value);
                text.push("");
                this.value = text.join(", ");
                var value = $("[id*=hfCustomerId]").val().split(/,\s*/);
                value.pop();
                value.push(i.item.val);
                value.push("");
                $("#[id*=hfCustomerId]")[0].value = value.join(", ");
                return false;
            },
            minLength: 1
        });
 
    });
</script>
</head>
<body>
    <form id="form1" runat="server">
    <asp:TextBox ID="txtSearch" runat="server"></asp:TextBox>
    <asp:HiddenField ID="hfCustomerId" runat="server" />
    <br />
    <asp:Button ID="btnSubmit" runat="server" Text="Submit" OnClick = "Submit" />
    </form>
</body>
</html>


Configure jQuery AutoComplete select multiple words in ASP.Net
 
Fetching the Selected Item Key and Value server side
The Key (Here Customer Names) and Value (Here Customer IDs) can be fetched server side on click of submit button in the following way.
C#
protected void Submit(object sender, EventArgs e)
{
    string customerNames = Request.Form[txtSearch.UniqueID];
    string customerIds = Request.Form[hfCustomerId.UniqueID];
}
 
VB.Net
Protected Sub Submit(ByVal sender As Object, ByVal e As System.EventArgs)
   Dim customerNames As String = Request.Form(txtSearch.UniqueID)
  Dim customerIds As String = Request.Form(hfCustomerId.UniqueID)
End Sub
 
Here we get the selected names of Customers and their corresponding Ids as a string of comma separated values, we can later on split it to get individual item.
Configure jQuery AutoComplete select multiple words in ASP.Net
 
Demo
 
Downloads