jSearch: Simple jQuery/XML based search

Apr 27, 2010. | By: Mike Endale

A couple of weeks ago, a client brought us an interesting problem. They wanted a function to search their rather massive catalog. The only problem? Their company has a content management system (CMS) that does not allow any server side scripts execute. The data was stored in a bunch of Excel spread sheets thus requiring us to batch process it. We wrote a macro to export the file to XML and clean it – long story!

If you just want to get the files

Fork it from GitHub

The Story

Once that side of the equation is handled, the problem was to come up with a simple solution to do the search.

Lo and behold, after a few minutes of Google search, we found a script written a couple of years ago:  Simple Javascript/XML based search. It was very simple!

We re-wrote a similar script using jQuery frame work. It uses a RegExp object  to handle the match and also added the tablesorter  jQuery plugin to improve the usability. Added some validation and such and viola, it became a neat little tool. Thought we’d share…

Code

First thing first

<link rel="stylesheet" href="path/to/default.css" />
<script type="text/javascript" src="path/to/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="path/to/tablesorter.js"></script>
<script id="data" type="text/javascript" src="path/to/search.js" xmlData="path/to/data.xml"></script>

You’ll notice I’ve added an id and xmlData attributes to the search.js reference. This is the best way to pass the xml file location from the HTML file. This helps a great deal if you have multiple xml files you want to use as data source. The XML data source can be structured in any way or can be any size. You can also add attributes for more data pointers. Here is a sample XML:

<?xml version="1.0" encoding="utf-8"?>
<indices>
  <index>
    <name><![CDATA[ John ]]></name>
    <age><![CDATA[ 22 ]]></age>
    <height><![CDATA[ 5'9" ]]></height>
  </index>
  <index>
    <name><![CDATA[ Paul ]]></name>
    <age><![CDATA[ 25 ]]></age>
    <height><![CDATA[ 5'5" ]]></height>
  </index>
  <index>
    <name><![CDATA[ Paul ]]></name>
    <age><![CDATA[ 26 ]]></age>
    <height><![CDATA[ 6'0" ]]></height>
  </index>
  <index>
    <name><![CDATA[ George ]]></name>
    <age><![CDATA[ 29 ]]></age>
    <height><![CDATA[ 5'4" ]]></height>
  </index>
<indices>

And here is the Javascript code:

$(document).ready(function () {
 
  //GLOBAL VAR
  var XMLSource = $('#data').attr('xmlData');
  var keyword = '';
  var catType = '';
  var pub = '';
 
  var i = 0;
 
  $("#searchButton").click(function () {
    keyword = $("input#term").val();
    catType = $("#category option:selected").val();
 
    //Reset any message
    var errMsg = '';
    pub = '';
 
    if (keyword == '') {
      errMsg += 'Please enter a search term' + 'n';
    } else if (catType == 'none') {
      errMsg += 'Please select a category' + 'n';
    } else {
      searchThis();
    }
 
    if (errMsg != '') {
      pub += '<div class="error">' + 'n';
      pub += errMsg;
      pub += '</div>' + 'n';
    }
 
    //Show error
    $('#result').html(pub);
 
  });
 
  function searchThis() {
    $.ajax({
      type: "GET",
      url: XMLSource,
      dataType: "xml",
      success: function (xml) {
        loadPublication(xml)
      }
    });
  }
 
  function loadPublication(xmlData) {
    i = 0;
    var row;
 
    var searchExp = "";
 
    $(xmlData).find('index').each(function () {
 
      var name = $(this).find('name').text();
      var age = $(this).find('age').text();
      var height = $(this).find('height').text();
 
      //Format the keyword expression
      var exp = new RegExp(keyword, "gi");
 
      //Check if there is a category selected;
      //if not, use height column as a default search
      if (catType == 'name') {
        searchExp = name.match(exp);
      } else if (catType == 'age') {
        searchExp = age.match(exp);
      } else if (catType == 'height') {
        searchExp = height.match(exp);
      }
 
      if (searchExp != null) {
 
        //Start building the result
        if ((i % 2) == 0) {
          row = 'even';
        } else {
          row = 'odd';
        }
 
        i++;
 
        pub += '<tr class="row ' + row + '">' + 'n';
        pub += '<td valign="top" class="col1">' + name + '</td>' + 'n';
        pub += '<td valign="top" class="col2">' + age + '</td>' + 'n';
        pub += '<td valign="top" class="col3">' + height + '</td>' + 'n';
        pub += '</tr>' + 'n';
      }
    });
 
    if (i == 0) {
      pub += '<div class="error">' + 'n';
      pub += 'No Result was Found' + 'n';
      pub += '</div>' + 'n';
 
      //Populate the result
      $('#result').html(pub);
    } else {
      //Pass the result set
      showResult(pub);
    }
  }
 
  function showResult(resultSet) {
 
    //Show the result
    pub = '<div class="message">There are ' + i + ' results!</div>';
    pub += '<table id="grid" border="0">' + 'n';
    pub += '<thead><tr>' + 'n';
    pub += '<th class="col1">Name</th>' + 'n';
    pub += '<th class="col2">Age</th>' + 'n';
    pub += '<th class="col3">Height</th>' + 'n';
    pub += '</tr></thead>' + 'n';
    pub += '<tbody>' + 'n';
 
    pub += resultSet;
 
    pub += '</tbody>' + 'n';
    pub += '</table>' + 'n';
 
    //Populate
    $('#result').html(pub)
 
    $('#grid').tablesorter();
  }
});

Here is the sample HTML that will work with the code above.

<div id="controller">
  <label>Search Term:
    <input type="text" id="term">
  </label>
  <label>
    <select name="category" id="category">
      <option value="none">Please Select a Type</option>
      <option value="name">Name</option>
      <option value="age">Age</option>
      <option value="height">Height</option>
    </select>
  </label>
  <input name="Search" type="button" id="searchButton" value="Search">
</div>

Screenshot

jSearch Part I

jSearch Part II

Release mambo jumbo: You may use this script as you see it fit.

Enjoy.

Update

A few folks have asked us about an issue with IE. The code base works with IE, but in order to test it, you’ll have to upload it to a server. Please check out our demo.

jSearch on IE8

Subscribe

Subscribe to this blog via RSS.

Recent Posts

About

BLEN Corp is a small, minority, and veteran-owned information technology firm located in Washington D.C. Since 2004, we have been ahead of the curve in early adaption and implementation of cutting edge technologies including web and mobile development, service-oriented architecture, and other innovative web based solutions. Look at some of our projects.

Social Links

Our Bunker

WeWork Wonder Bread Factory
641 S St. NW
3rd Floor
Washington, DC 20001
United States.