in programming

jQuery Autocomplete Using XML as Data Source

Update (11/30/2012): added a new demo that only searching the beginning terms of the autocomplete source.

Update: added a new demo for autocomplete for two fields in a form.

Introduction

The following article will describe how to use an XML file as a Data Source for the jQuery Autocomplete plugin.

The jQuery Autocomplete Plugin documentation is lacking on examples, or details, on how to use an XML file as the data source. So this is my attempt to provide a simple example of how to use XML with the Autocomplete Plugin.

The plugin can take an array of strings, so we need to develop code to read the XML file into memory and parse its contents into an array of strings. Once we have an array of strings, we can assign that array to the autocomplete plugin and attach that to a text field in our form. The following will step through that process.

Demo

First things first. Here is a link to the demo.

Two fields in a form that have autocomplete functionality. Demo 2

This demo only searches the beginning terms of the source provided. Demo 3

Example Code

Below is the full code used for this article.


<!DOCTYPE html>
<html>
  <head>
    <title>jQuery Autocomplete: XML as data source</title>
    <link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.js"></script>

 <script>
 $(document).ready(function() {
 var myArr = [];

 $.ajax({
   type: "GET",
   url: "states.xml", // change to full path of file on server
   dataType: "xml",
   success: parseXml,
   complete: setupAC,
   failure: function(data) {
     alert("XML File could not be found");
   }
 });

 function parseXml(xml)
 {
   //find every query value
   $(xml).find("state").each(function()
   {
     myArr.push($(this).attr("label"));
   });
 }

 function setupAC() {
   $("input#searchBox").autocomplete({
   source: myArr,
   minLength: 1,
   select: function(event, ui) {
     $("input#searchBox").val(ui.item.value);
     $("#searchForm").submit();
   }
  });
 }
});
</script>
</head>

  <body style="font-size:62.5%;">

  <form name="search_form" id="searchForm" method="GET" action="search_results.html">
   <label for="searchBox">Keyword Search</label>
   <input type="text" id="searchBox" name="searchString" />

   <button name="searchKeyword" id="searchKeyword">Sumbit</button>
  </form>

  </body>
</html>

jQuery Library Includes

The following libraries and css are used for this example:

XML File

The XML file used for this example is very basic. It consists of a parent element labeled states and child elements labeled state for each item that can be suggested as a search option.

<?xml version="1.0" encoding="UTF-8"?>
<states>
 <state label="Alabama" value="AL" country="US" />
 <state label="Alaska" value="AK" country="US" />
 <state label="Arkansas" value="AR" country="US" />
 <state label="Arizona" value="AZ" country="US" />
 <state label="California" value="CA" country="US" />
 <state label="Colorado" value="CO" country="US" />
 <state label="Connecticut" value="CT" country="US" />
...

The Form

The following is the form used in this example:


<form name="search_form" id="searchForm" method="GET" action="search_results.html">
 <label for="searchBox">Keyword Search</label>
 <input type="text" id="searchBox" name="searchString" />

 <button name="searchKeyword" id="searchKeyword">Sumbit</button>
</form>

Important features of the form

  • The form has an id of searchForm. This will be used later to submit the form when selecting a result in the search suggestion list.
  • Text Input field has an id of searchBox. This will be used to add autocomplete functionality to this form field.

Open XML file for parsing

In order for the form to display suggested search options, the XML file needs to be opened and parsed into memory. To do this, an ajax call is needed once the HTML document is ready.

$.ajax({
 type: "GET",
 url: "states.xml", // change to full path of file on server
 dataType: "xml",
 success: parseXml,
 complete: setupAC,
 error: function() {
 alert("XML File could not be found");
 }
});

Explanation

  • If XML file is loaded succesfully, parseXML function is called. Which will, as you guessed, parse the XML file into an array of strings.
  • Once the ajax request is completed, assign the autocomplete plugin to the searchBox field via the setupAC function.
  • If the ajax call fails to find the XML file, an alert prompt will display; notifying you that the file cannot be found. This method works great for an example, but a more elegant error method should be developed for a production version.

Note: be sure to change the url variable to the full path of file on your sever.

Parse XML

The following code will parse the XML opened through the ajax call above.

function parseXml(xml)
{
  //find every query value
  $(xml).find("state").each(function()
  {
    myArr.push($(this).attr("label"));
  });
}

This function finds all elements named state and adds the label attribute of that element to the myArr variable, which is of type Array.

Once this function is complete, myArr will be populated with possible search suggestion strings.

Adding Autocomplete Functionality

In order to add autocomplete functionality, we need to add the jQuery plugin features to an input text field.

After the ajax call is complete, the setupAC function is then called which will configure the autocomplete feature.


function setupAC() {
 $("input#searchBox").autocomplete({
     source: myArr,
     minLength: 3,
     select: function(event, ui) {
       $("input#searchBox").val(ui.item.value);
       $("#searchForm").submit();
     }
 });
}

Explanation

  • source: myArr assigns the array of strings parsed from our XML file as the data source
  • A minimum of 3 characters must be entered before suggested search options will display (minLength value). This can be changed to work for your solution.
  • The select option will replace the text in the input field with the search suggestion selected item. This is needed so that the form will submit with the search term within the form properties. Otherwise, the form would submit with a blank searchBox value if a selection is made from the search suggestion dropdown.
  • Lastly, $("#searchForm").submit() submits the form.

Limitations

One major limitation I’ve found with this plugin is the option to limit the suggestion menu result set. For example, it would be great to have the option to display a maximum of 10 suggestions matching the user’s search criteria. This example doesn’t have this problem, but imagine if your data source had thousands of strings and more than 50 of them had the characters “add” somewhere in the string. The suggestion dropdown would be too long to see all those results on the screen without scrolling.

Modifications to Autocomplete Functionality

jeffrey from the comment thread asked if there is a way to modify the autocomplete function to only search the first character of the state names.

Yes, this is possible. The see this in action, please check out the link for Demo 3.

We need to modify the way the source attribute is delcared to run a regex function on the myArr list to only select terms that match the beginning terms of each item. See below on how to modify the existing setupAC function (lines 3-8):

function setupAC() {
    $("input#searchBox").autocomplete({
        source: function( request, response ) {
	        var matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( request.term ), "i" );
	        response( $.grep( myArr, function( item ){
	            return matcher.test( item );
	        }) );
	    },
	    minLength: 1,
	    select: function(event, ui) {
	        $("input#searchBox").val(ui.item.value);
	        $("#searchForm").submit();
	    }
    });
}

I can’t take all the credit for this code. I found a nice example on the jQuery UI API Documentation for the autocomplete widget website (see example 2).

Download Example

Here is a zip file containing all example files for this article. Feel free to reuse for your needs

I welcome comments or suggestions. All code is free to use as you see fit. No licensing here.

Leave a Reply

132 Comments

  1. Hi there. Someone may have already mentioned this, but you can limit the number of autocomplete results displayed with the following CSS code:

    .ui-autocomplete li:nth-child(n+11){
    display:none;
    }

    Just replace the 11 with the number of results you want, plus one!
    Hope this helps!

  2. How to get the unique result in search if my data having multiple places where names are same. i should not get 2 result in search instead should get only one

  3. Hello, Will this code work with RDF files? I changed the type and the file name but it doesn’t seem to work.

  4. Hello Ryan thank you very much for this example, this is exactly what I was looking for. I would like to know how I can search using a keyword and populated another tag suggestion string.

    For example:

    and when you type “tasty”, Pizza and Cake will appear as suggestion string.

    Could you please give me a hand?

    Thank you very much!
    Regards,
    Matias

    • I dont know why but the tags dissapeared

      food label=”tasty” value=”Pizza”
      food label=”tasty” value=”Cake”

        • JasonC thank you buddy but I was thinking it the wrong way. What I’m trying to achieve now is to have a multi value tag where I can store keywords: ie:

          food name=”pizza” key=”cheesee, italy, tomatoe”
          food name=”cake” key=”chocolate, birthday”

          but I’m failing in parsing those codes correctly so the end user can see them as individual options in the autocomplete.

          thanks a lot!

        • I solved it! I used an Oracle table with a comma separated column, then I created a PLSQL procedure to create the XML and voila!
          Thanks for your help

  5. Dear Ryan,
    I am currently using your demo 3 .
    I would like to know how I can search a word through the label.
    Example:
    when I type the word “publicly” it will appear elements that have publicly. Here is a piece of my code.

    function parseXml(xml){
    $(xml).find(“word”).each(function(){
    myArr.push($(this).attr(“label”));
    });
    }

    function setupAC(){
    $(“input#searchbox”).autocomplete({
    source: myArr,
    function(request, response){
    var match = new RegExp(“^” + $.ui.autocomplete.escapeRegex(request.term), “i”);
    response($.grep(myArr, function(item){
    return match.test(item);
    }).slice(0,15));
    },
    delay: 0,
    minLength: 1,
    select: function(event, ui){
    $(“input#searchbox”).val(ui.item.value);
    $(“#avanced_search”).submit();
    }
    });