we would love to hear from you. 202.269.2066 · info@blencorp.com

 

jSearch: Simple jQuery/XML based search

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!

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

Lo 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….

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"></div>
<label>Search Term:</div>
<input type="text" id="term"></div>
</label></div>
<label></div>
<select name="category" id="category"></div>
<option value="none">Please Select a Type</option></div>
<option value="name">Name</option></div>
<option value="age">Age</option></div>
<option value="height">Height</option></div>
</select></div>
</label></div>
<input name="Search" type="button" id="searchButton" value="Search"></div>
</div></div>
<div id="result">&nbsp;</div></div>

Screenshot

Download the full code (zip, 41KB)

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

Enjoy

2 Responses to “jSearch: Simple jQuery/XML based search”

  1. Mike

    Great script – but I can’t get it to show any results in IE8? Any ideas….

    May 27th, 2010 | 8:55 am
  2. hallo,

    This great script, but work only for Mozilla, the other browser don’t work.

    Thank you…

    June 15th, 2010 | 5:54 am

Leave a Reply