jQuery Autocomplete and ASP.NET

djuth picture djuth · Nov 20, 2008 · Viewed 92.4k times · Source

I searched all over this site and the web for a good and simple example of autocomplete using jQuery and ASP.NET. I wanted to expose the data used by autocomplete with a webservice (and will probably do that next). In the meantime, I got this working, but it seems a little hacky...

In my page I have a text box:

<input id="txtSearch" type="text" />

I am using jQuery autocomplete, set up per their example:

<link rel="stylesheet" href="js/jquery.autocomplete.css" type="text/css" />
<script type="text/javascript" src="js/jquery.bgiframe.js"></script>
<script type="text/javascript" src="js/jquery.dimensions.pack.js"></script>
<script type="text/javascript" src="js/jquery.autocomplete.js"></script>

Here is where it starts to get hacky... I call a page instead of a webservice:

  <script type="text/javascript">
    $(document).ready(function(){
        $("#txtSearch").autocomplete('autocompletetagdata.aspx');
    });      
  </script>

In the page I stripped out ALL of the html and just have this (otherwise, various HTML bits show up in the autocomplete dropdown):

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="autocompletetagdata.aspx.cs" Inherits="autocompletetagdata" %>

And in my autocompletetagdata.aspx, I am using SubSonic to query, format and return data from the database (one data item per line):

protected void Page_Load(object sender, EventArgs e)
{
    // Note the query strings passed by jquery autocomplete:
    //QueryString: {q=a&limit=150&timestamp=1227198175320}

    LookupTagCollection tags = Select.AllColumnsFrom<LookupTag>()
        .Top(Request.QueryString["limit"])
        .Where(LookupTag.Columns.TagDescription).Like(Request.QueryString["q"] + "%")
        .OrderAsc(LookupTag.Columns.TagDescription)
        .ExecuteAsCollection<LookupTagCollection>();

    StringBuilder sb = new StringBuilder();

    foreach (LookupTag tag in tags)
    {
        sb.Append(tag.TagDescription).Append("\n");
    }

    Response.Write(sb.ToString());
}

If you don't do a LIKE query, then it returns everything that contains a match for the character(s) you type -- e.g., typing "a" will include "Ask" and "Answer" as well as "March" and "Mega." I just wanted it to do a starts with match.

Anyway, it works and it's pretty easy to set up, but is there a better way?

Answer

bdukes picture bdukes · Nov 20, 2008

I just recently implemented autocomplete, and it looks fairly similar. I'm using an ashx (Generic Handler) instead of the aspx, but it's basically the same code in the code behind.

Using the ashx, it'll look something like this:

<script type="text/javascript">
  $(document).ready(function(){
      $("#txtSearch").autocomplete('autocompletetagdata.ashx');
  });      
</script>

[WebService(Namespace = "http://www.yoursite.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class AutocompleteTagData : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        // Note the query strings passed by jquery autocomplete:
        //QueryString: {q=a&limit=150&timestamp=1227198175320}

        LookupTagCollection tags = Select.AllColumnsFrom<LookupTag>()
            .Top(context.Request.QueryString["limit"])
            .Where(LookupTag.Columns.TagDescription).Like(context.Request.QueryString["q"] + "%")
            .OrderAsc(LookupTag.Columns.TagDescription)
            .ExecuteAsCollection<LookupTagCollection>();

        foreach (LookupTag tag in tags)
        {
            context.Response.Write(tag.TagDescription + Environment.NewLine);
        }
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}