AJAX Auto Suggestion/Auto Complete Textbox

I recently created an AJAX-based auto suggestion textbox for a work project so I thought I’d share some code.

I’ve seen examples that used combinations hacked-up select boxes and multiple DIVs. However, I think I came up with a fairly good solution using nothing more than a textbox and an empty HTML DIV.

The HTML

As usual, pay attention to IDs…

<input type="text" id="serial" name="serial" onchange="serial_onchange(this, 'serial_results', '<%=User.CompanyID%>');" style="width:150px" />
<div id="serial_results" class="results" style="width:150px" /></div>

It is also good to note that the input and div should have the same width. You can do this with inline styles.

The CSS

…and of course, you’ll want to style it in order to make it invisible on first load. This styling does have a downfall however: if your textbox is not right-aligned to the very leftmost part of the BODY then the DIV won’t appear directly under it. If this is the case, you may need to use the top and left properties to get it where you need it. I’m sure there are other ways as well.

div.results {
display: none;
position: absolute;
background-color: #ffffff;
border: 1px solid #000000;
}

The Javascript

I basically wrote the Javascript as two functions: one is a generic auto-suggestion function and the other is a wrapper specifically for this instance of the auto suggestion. In this case, it will create a suggested list of serial numbers that belong to the specified company ID in the database.

This code uses the zXml class in order to send and receive the XMLHttp requests back and forth.

(some lines of code, from this point forward, have been changed from one line to multiple lines for the sake of formatting on this website, you may need to adjust them if you’re doing any copying and pasting)

var last_type = 0;

function autosuggest(textbox, resultsdiv, backendfile, extraquerystring) {
  resultsdiv = document.getElementById(resultsdiv);

  var d = new Date();

   // if they aren't typing too fast or they haven't started typing
  if (d.getTime() - last_type > 500 || last_type == 0) {
    // start the request
    var objXML = zXmlHttp.createRequest();
      // open the ajax serials page and pass the search and company
      objXML.open("get", backendfile + "?textbox=" + textbox.id + "&resultsdiv=" + _
          resultsdiv.id + "&search=" + textbox.value + extraquerystring, true);
      objXML.onreadystatechange = function () {
        if (objXML.readyState == 4) {
          // success, so pass the result to the page

          // display the box
          resultsdiv.style.display='block';

          result = objXML.responseText;
          if (result != "-1") {
            resultsdiv.innerHTML = result;
          } else {
            // an error (-1) was passed from the page
            resultsdiv.style.display='none';
          }
        }
      }
      objXML.send(null);
    } else {
      // typing too fast, hide the box
      resultsdiv.style.display='none';
    }

    // get the new last typed time
    var d = new Date();
    last_type = d.getTime();
}

function autosuggest_select(textbox, resultsdiv, value) {
  textbox = document.getElementById(textbox);
  resultsdiv = document.getElementById(resultsdiv);

  textbox.value = value;
  resultsdiv.style.display='none';
}

function serial_onchange(textbox, resultsdiv, company) {
  autosuggest(textbox, resultsdiv, "ajax/serial_onchange.asp", "&company=" + company);
}

The autosuggest function allows you to pass a reference to a textbox, the ID of the results DIV, the back-end AJAX file to call (PHP, ASP, Python, Perl, etc), and any extra query string information that should also be passed along to the back-end file.

In the case of serial_onchange, the instance-specific wrapper of the serial number auto suggestion box, we pass along the company ID as well.

The third function, autosuggest_select can be used for generated HTML links that, when clicked, will change the value of the textbox to the value specified.

The Back-End (ASP)

This code (it’s ASP, pre-.Net, and I know it’s garbage) I would put in a file something like /ajax/serial_autosuggest.asp to try and keep naming conventions as consistent as possible.

<%
  OpenConn

  search = Request.QueryString("search")
  company = Request.QueryString("company")
  textbox = Request.QueryString("textbox")
  resultsdiv = Request.QueryString("resultsdiv")

  If Len(search) > 0 And Len(company) > 0 Then
    sql = "SELECT TOP 10 serial FROM tblAssets WHERE company_id="& company & " AND _
        serial LIKE '" & search & "%' ORDER BY serial ASC"
    Set rs = objConn.Execute(sql)

    If Not rs.EOF Then
      Response.Write "<table width=""100%"" cellpadding=""2"" cellspacing=""0"">" & vbNewLine
      While Not rs.EOF
        Response.Write "<tr><td><a href=""javascript:void(0);"" onclick=""autosuggest_select(_
            '" & textbox & "', '" & resultsdiv & "', '" & rs("serial") & "');"">" & rs("serial") & "</td></tr>" & vbNewLine
        rs.MoveNext
      Wend
      Response.Write "<tr><td align=""right""><a href=""javascript:void(0);""_
          onclick=""javascript:document.getElementById('" & resultsdiv & "').style.display='none'"">x</a></td></tr>"
      Response.Write "</table>"
    Else
      Response.Write "-1"
    End If

  Else
    Response.Write "-1"
  End If

  CloseConn
%>

All it’s doing, essentially, is using the passed “search” text to the database to try and match any number of items (in this case, limited to 10) that match what they have started typing. It fetches results and generates an HTML table of the items (and one item at the end to be able to close the results) and sends that text, via the “AJAX” to the results DIV. If any errors occur, it sends back nothing but “-1″ in order for it to gracefully know what to do (such as not display the results).

Some Comments

This sounds more complicated than it really is, but if you break down the code and look at one piece at a time it should be fairly simple to figure out and re-implement. There are some additional notes however:

  • It doesn’t decay gracefully if any database errors occur… ASP 3 doesn’t have try/catch blocks to do this nicely so I didn’t bother.
  • As mentioned above, this requires a bit more hacking to show the results DIV directly below the textbox if it isn’t positioned on the left-most part of the screen.
  • Some extra lengths could be taken to encode other important things, such as the company ID being passed, so that, for instance, someone else couldn’t see serial numbers for a different company by searching through the code and finding the ASP file.

2 Responses to “AJAX Auto Suggestion/Auto Complete Textbox”

  1. Roshni Says:

    This is a very good example. It came in very handy for me when i need a similar implementation in my project. Thanks a ton.

  2. Jaswinder Says:

    Great example. Just finished using in one of my examples.

    Thanks

Leave a Reply