AJAX shopping cart

Hello. This time we’ll discus writing a simple AJAX-driven shopping cart. Again, a challenge that has many solutions, but I prefer to write my own code. Especially for these posts… Like always, we need to discus the languages used and then we can talk about the code. Also, I will provide the full source code this time. You can find it here.

Also, you can see the project here.

Since we’ll use AJAX, we’ll have to write PHP and Javascript code, and of course HTML with a bit of CSS (for the interface). The JS part of the application will send requests to a PHP script, which takes the id of the item that needs to be added, and then display the response text in a container, which is our cart. The JS function sends via XMLHttpRequest two parameters, the first being the id of the item, and the second being a add/subtract ’switch’ (1 - add, 0 - subtract).

Now for the server side part. Since we need to manipulate a series of items, the first thing that comes to mind, is an array. And furthermore, since we need to pass this item from one file to another, we can uses sessions. So, we use a session-stored array to hold out items like this:

Array(
    [item_id1] => quantity1
    [item_id2] => quantity2
    [item_id3] => quantity3
    . . .
);

This is how it looks in PHP:

<?php
session_start();
$_SESSION['items'] = array();
?>

This way we can keep all the information in one array (rather than keeping item_id’s and quantity separately, or using objects).

So, what happens when we send a request? Well, first, the server side script recieves the two parameters, the id and the ’switch’; If the id that was sent is equal to 0, then it means the user wants to empty the shopping, so we do just that, we empty the array and then we exit.

session_start();
$id = $_POST['id'];

if($id == 0)
{
	array_splice($_SESSION['items'], 0);
	exit();
}

If that’s not the case, we need to manipulate an item. We do this by checking if a key equal to the sent id hasn’t been added to the array. In this case, then we simply add an item, else if the switch is equal to 1, we increase the quantity of the item by 1, and if it’s equal to 0, we subtract by 1.

if(!array_key_exists($id, $_SESSION['items']))
	$_SESSION['items'][$id] = 1;
else
	($_POST['add']) ? $_SESSION['items'][$id]++ : $_SESSION['items'][$id]--;

The final step is sending the response text back to the client side, so we just display the result. We parse the array, and display the data in the form we want it. In this case I have used a table:

<table>
<?php
foreach($_SESSION['items'] as $key => $quantity)
{
	if($quantity <= 0)
		unset($_SESSION['items'][$key]);
	else
	{
	?>
	<tr>
		<td width="50"><div class="item<?php echo $key;?>"></div></td>
		<td width="50">x <?php echo $quantity;?></td>
		<td width="150" align="right">
			<a href="#" onclick="sendRequest(<?php echo $key;?>,1);">+</a>
			 /
			<a href="#" onclick="sendRequest(<?php echo $key;?>,0);">-</a>
		</td>
	</tr>
	<?php
	}
}
?>
</table>

Ok. Now that the text is formated nicely, we can add it to the cart, I mean, we let the client side script handle that… So that’s basically it. I won’t go into to much detail about the code, since you can find the source code here.

Feel free to experiment with it and post you version here. If you need any further info, please ask.

Posted in: AJAX

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.

Posted in: AJAX