XML array sorting using AJAX

Back again with a new post! This time, we’ll discuss how to make a sortable table using AJAX. This can be very useful when you make a site that displays items in the form of a list(table), and the user needs to sort the table using a specific criteria by clicking on a field.

In order to proceed, I’ll just mention a few things we need to know:

1. The list of items is stored in a XML file, therefore we’ll be loading the file using PHP.

2. In order to display the array without refreshing the page, we need to use XmlHttpObject so we can send a request to the server, in order to sort the array

3. The array isn’t sorted per say, we just need to retrieve a list of indices that defines the order of the items, in this case alpha-ascending order. This saves time because the server doesn’t need to do too many operations in order to sort the table.

You can see the project in action here.

Now that we have mentioned these things, we can proceed to analyze the project in detail.

1.

The XML file holds our list of items in the form of elements. Each element has three attributes which hold the value for that specific field. Since this is just a demo, I have used generic values:

<list>
  <item field1="Value 1" field2="Value 2" field3="Value 3"/>
  <item field1="Value 2" field2="Value 4" field3="Value 1"/>
  <item field1="Value 3" field2="Value 3" field3="Value 4"/>
  <item field1="Value 4" field2="Value 1" field3="Value 2"/>
</list>

Loading a XML file in a variable is simple enough using PHP 5:

$xml = new DomDocument(’1.0′);
$xml->preserveWhiteSpace = false;
$xml->load([ XML file ]);

And getting the items is also very simple:

$items = $xml->getElementsByTagName(’item’);

2.

Now that we have discussed the XML structure and the PHP-loading part, we can talk about how to use AJAX to sort the array using a request object and displaying the result.

The easiest way to create a request object is to use a function which returns an instance of the created object so you can store it in a variable, like this:


function GetXmlHttpObject()
{
	var xmlHttpObj = null;
	try
	{
		//Firefox, Opera8.0+, Safari
		xmlHttpObj = new XMLHttpRequest();
	}
	catch (e)
	{
		//Internet Explorer
		try
    		{
    			xmlHttpObj = new ActiveXObject("Msxml2.XMLHTTP");
    		}
		catch (e)
		{
			xmlHttpObj = new ActiveXObject("Microsoft.XMLHTTP");
		}
	}
	return xmlHttpObj;
}

The next step is to write the function which sends the request, and handles the response text. First we create a request object, then we form the string we want to send to the server, using the request, and finally, we write a function to determine if the request’s state has changed and therefore, a response is available. If the server has generated a response, another function handles the text. First the function to send the request:

function sendRequest(url, crit) //the url of the PHP script and the sorting criteria
{
	xmlhttpobj = GetXmlHttpObject(); //the above mentioned function

	if (xmlhttpobj == null)
	{
		alert ("Your browser does not support AJAX!");
		return;
	}

	var string = 'crit=' + crit; //string to send using the request

	xmlhttpobj.onreadystatechange = stateChanged;
	xmlhttpobj.open("POST", url, true); //we'll get the criteria using the $_POST variable
	//request headers
	xmlhttpobj.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	xmlhttpobj.setRequestHeader("Content-length", string.length);
	xmlhttpobj.setRequestHeader("Connection", "close");

	xmlhttpobj.send(string);
}

Ok. This is the main function of our request sending script. Now, the only thing left, is to write the function which handles the server response upon the state change. This is again easy, since we only need to determine if the response has arrived. We do this by asking if the request’s ready state is 4, then we put the response text in a <div> element which has the id ‘container’:

function stateChanged()
{
    if (xmlhttpobj.readyState == 4) //global variable
        document.getElementById("container").innerHTML = xmlhttpobj.responseText;
}

3.

The final part of the application is the server-side script which handles the array sorting. Like I said in the beginning, we don’t actually need to sort the entire array, instead we just form an array of indices (corresponding to each item of the list) that defines the order in which we want to display the items, in this case, alpha-ascending order by one of the three fields. The algorithm loops through the items array and determines the index of the item with the minimal (alpha-ascending) that hasn’t been added to the index array. After one loop we get the index of the item that needs to be added at that particular moment, and after doing this for each item, we get an array that stores the indices of the items in alpha-ascending order.


function sort_xml(DOMDocument $s_xml, $att, &$array)
{
	$items = $s_xml->getElementsByTagName('item');
	$index = 0;
	$con = 0;

	for($i=0; $i<$items->length; $i++)
	{
		$con = 0;
		$min_att = 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz';
		foreach($items as $item)
		{
			if(strcmp($item->getAttribute($att), $min_att) < 0 && !added($con, $array))
			{
				$min_att = $item->getAttribute($att);
				$index = $con;
			}
			$con++;

		}
		array_push($array, $index);
	}
}

The function which determines if an index has been already added:


function added($index, $array)
{
        for($i=0; $i<sizeof($array); $i++)
                if($array[$i] == $index)
                        return true;
        return false;
}

Now that we have a way to sort the array, the only thing left is to display the results according to the index array. First, we call the sort function:


$xml = new DomDocument('1.0');
$xml->preserveWhiteSpace = false;
$xml->load([ XML file ]);
$crit = $_POST['crit'];
$index_array = array();


sort_xml($xml, $crit, $index_array);

The we simply display the sorted table, since it will be handled as a response text:

<table>
	<tr bgcolor="#006699">
		<td width="100" onclick="sendRequest('scripts/table-script.php','field1')">
			<span class="heading">Field 1</span>
		</td>
		<td width="100" onclick="sendRequest('scripts/table-script.php','field2')">
			<span class="heading">Field 2</span>
		</td>
		<td width="100" onclick="sendRequest('scripts/table-script.php','field3')">
			<span class="heading">Field 3</span>
		</td>
	</tr>
	<?php
	$items = $xml->getElementsByTagName('item');
	for($i=0; $i<sizeof($index_array); $i++)
	{
		$item = $items->item($index_array[$i]);
		?>
		<tr bgcolor="#006699">
			<td><?php echo $item->getAttribute('field1');?></td>
			<td><?php echo $item->getAttribute('field2');?></td>
			<td><?php echo $item->getAttribute('field3');?></td>
		</tr>
		<?php
	}
	?>
</table>

We add the onclick attribute for all the field columns, and that’s it. Click here for a demo of this post.

StumbleUpon It!

2 Responses to “XML array sorting using AJAX”

  1. Absolutely awesome. Just at the time I needed such a thing, I stumble onto this tutorial. Thanks!

  2. Thanks for writing this.

Leave a Reply

Security Code: