]> NiXPA.com - Nick's Personal Area

Dynamic AJAX tabs

All the AJAX type of web site designs are pretty cool and interactive, no doubts. But what is the point of including thousands of lines of JavaScript code into your page just to output one simple interactive button, or just to check the form contents?

Well, I agree that it's all because of the ease of "copy/paste" operation, but c'mon, isn't it worth spending just one extra hour to make the site visitors happier and your code more readable?

My focus today is an extremelly simple implementation of a one-dimensional tabbed navigation system. It uses JavaScript for content fetching and user interface, and PHP as the backend... well, there's little PHP code, so it should be a matter of seconds to convert it to Perl or whatever else you like. In the end we should get something that works like ivandulava.com (by the way, check it out and buy some of that DJ's tracks ;) )

Server side code

Let's store our set of links as an array, this makes it easy to put it into a separate file to make changes easier.

$links = array(
	'link_id1' => 'title1',
	'link_id2' => 'title2',
	'link_id3' => 'title3'
);

Great, now we have a set of links that will be used to display the menu. Now let's output them somewhere, make sure you use a container (such as DIV) with an assigned style to make the links good. Sample CSS code will be listed below.

echo "<div id='mytabs'>";
foreach ($links as $key => $value) {
  //$key = "$key";
  echo "<a href='#' onClick='return loadPage(\"$key\");' id='$key'>$value</a>";
}
echo "</div>";

Here we output the links and each of them gets a unique ID which is taken from the links array we defined earlier. Each of them calls loadPage() function with the ID as a parameter.

Initial markup, some CSS

Ok, before we start changing classes and appearance of things, let's have a look of what a tabbed link's style might look like

/* Style for the container with links */
#mytabs
{
  font: bold 13px Verdana;
  padding: 0;
  margin: 0;
  text-align: right;
  height: 20;
}

/* Each link in that container... */
#mytabs a
{
  text-decoration: none;
  color: #000;
  padding: 4;
  height: 15;
  background-color: #FF4444;
}

/* some effects when the tab is hovered */
#mytabs a:hover
{
  color: #FFF;
  background-color: #FF9999;
}

/* tab that is currently active */
#mytabs a.current
{
  color: #FFF;
  background: #FF9999;
}

That's all for CSS, please make sure you change the colours before previewing it, this is just an example of a bad taste :) Lot's of possibilities of decorating the links here, depends on how your current site looks like.

Final steps

Now that we have the tab bar on our page, and clicking each link causes JavaScript functions to be called, it's time to implement those functions. Start with creating an XMLRequest object as usually:

var xmlHttp = false;
try {
	xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
	try {
		xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
	} catch (e2) {
		xmlHttp = false;
	}
}

if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {
	xmlHttp = new XMLHttpRequest();
}

function updatePage() {
	/* For simplicity's sake, I'm skipping the checking of the status
		if (xmlHttp.readyState == 4) {	etc...	*/
	document.getElementById("contents").innerHTML = xmlHttp.responseText;
}

Nothing special there, same as any other AJAX code. Note, ID of the container that will have the newly loaded page is "contents". Now let's get the hash value of the address bar - this is a cool (and only AFAIK) way of storing the state of the website. If the hash is not defined, set it to the main page ID, which is 'link_id1' in our example:

curhash = new String(parent.location.hash); curhash = curhash.replace(/\#/g, ""); if (curhash == "") { curhash = "link_id1"; parent.location.hash = curhash; }

Finally, load the required page on click and update the looks of the tab bar, comments are pretty detailed here:

function loadPage(id) {
	// get the link element that corresponds to the loaded page
	elem = document.getElementById(curhash);
	// update it's class to smth that doesn't exist,
	// so view will be reset to default
	if (elem) elem.className = "noncurrent";
	// now find the link element that is being activated
	elem = document.getElementById(id);
	// and make it look 'active'
	if (elem) elem.className = "current";
	// now save the status of the website in a variable
	curhash = id;
	// and try updating the hash part of the URL. This might fail, if it works -
	// then great - users can actually bookmark an AJAX modified site!
	parent.location.hash = curhash;
	// Now tell user that we are loading the next page,
	document.getElementById("contents").innerHTML = "patience...";
	// url to the script that returns a page based on its id
	var url = "./page.php?pid=" + id;
	xmlHttp.open("GET", url, true);
	xmlHttp.onreadystatechange = updatePage;
	xmlHttp.send(null);
	return false;
}

Well, that's it! Now you don't have to worry about the music stopping playing if your visitor clicks another link in the menu. The downside is that sometimes people disable their JavaScript in browsers, so you might want to account for that and create an alternative, "old school" type page.

Oh yeah, don't forget to call pageLoad(curhash) for the first time manually. Put it somewhere after the definition of "contents" element.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             

All rights reserved © NiXPA 2007-2009  Valid HTML 4.01 Strict