A Simple AJAX Driven Website with jQuery + PHP

Written by Kevin Liew on 08 Jul 2009
382,074 Views • Tutorials

Introduction

AJAX is abbrieviated from Asynchrounous javascript and XML. It's not a new technology, but the implementation of a group of technologies to achieve a seamless interaction between client and server.

Typically, xhtml and css to present the information, javascript is used to handle user interactions, and a server side language to perform the users' requests (and normally return data in XML format, in this tutorial, we won't do that), and it all is happening in the background using the Javascript XMLHttpRequest. Javascript plays a main role tie all these technologies together and create the asynchronous interaction between client ans server.

AHAH (Asynchrounous HTML and HTTP) is a subset of AJAX which is another technique, Inspite of retreiving XML, AHAH is retreiving HTML content. Both of them are basically the same, the only difference is the content it returns. Generally, most people will simply call it AJAX, but technically, we should call it AHAH. In this tutorial, AHAH is used.

The Good, Bad and Solutions

The Goodies:

  • Reduce connections and bandwidth to the server, images, scripts, stylesheets only need to be downloaded once
  • Reduce loading timew. User doesnt have to load pages again and again, it all happens in a same page!
  • Increase responsiveness and end user experiences.

The Badies:

  • Browser Back button. AJAX web pages cannot connect with browser history engine. If you clicked on back button, you can't navigate those AJAX content.
  • Bookmark will not work on AJAX webpages. Due to the dynamic content, you might bookmark the homepage instead of the desired page.
  • Javascript is needed. To run AJAX based website, your browser need to have javascript enabled.

The Solutions:

AJAX is not a perfect technology, but some of the limitations can be overcame with some simple solutions. I found this very userful plugin called jquery.history.js. It solves Browser Back Button. For the bookmark problem, we can solve it by appending a hash value in the end of the url.

For the last one - javascript, we are going to ignore it. It can be done but I want to keep this tutorial simple.

And, of course, you'll need a good web server as well, if you're hunting for a web hosting company, you can click here to read reviews about the best web hosting out there! iPage Review

Requirements

You will need the following items and environment to run this script

1. HTML

I will provide two versions of HTML code. The first one is the most basic elements you will need to get it working. And the last one is the one I created with some design

Simplified versions
<ul>
	<li><a href="#page1" rel="ajax">Home</a></li> 
	<li><a href="#page2" rel="ajax">Portfolio</a></li> 
	<li><a href="#page3" rel="ajax">About</a></li>
	<li><a href="#page4" rel="ajax">Contact</a></li>
</ul>

<div class="loading"></div>

<div id="content">
<!-- Ajax Content -->
</div>
		

2. CSS

This is really really simple, just have to keep the loading and content hidden

#loading {
	background: url(images/load.gif) no-repeat;
	display:none;
}
			
#content {
	font-family:arial;
	font-size:11px;
	display:none;
}	

3. Javascript

I have added comments in every single lines of the code.

	
$(document).ready(function () {
	
	//Check if url hash value exists (for bookmark)
	$.history.init(pageload);	
	    
	//highlight the selected link
	$('a[href=' + document.location.hash + ']').addClass('selected');
	
	//Seearch for link with REL set to ajax
	$('a[rel=ajax]').click(function () {
		
		//grab the full url
		var hash = this.href;
		
		//remove the # value
		hash = hash.replace(/^.*#/, '');
		
		//for back button
	 	$.history.load(hash);	
	 	
	 	//clear the selected class and add the class class to the selected link
	 	$('a[rel=ajax]').removeClass('selected');
	 	$(this).addClass('selected');
	 	
	 	//hide the content and show the progress bar
	 	$('#content').hide();
	 	$('#loading').show();
	 	
	 	//run the ajax
		getPage();
	
		//cancel the anchor tag behaviour
		return false;
	});	
});
	

function pageload(hash) {
	//if hash value exists, run the ajax
	if (hash) getPage();    
}
		
function getPage() {
	
	//generate the parameter for the php script
	var data = 'page=' + document.location.hash.replace(/^.*#/, '');
	$.ajax({
		url: "loader.php",	
		type: "GET",		
		data: data,		
		cache: false,
		success: function (html) {	
		
			//hide the progress bar
			$('#loading').hide();	
			
			//add the content retrieved from ajax and put it in the #content div
			$('#content').html(html);
			
			//display the body with fadeIn transition
			$('#content').fadeIn('slow');		
		}		
	});
}

4. PHP

We will not go further on PHP code, this time, I'm using a basic switch to grab the content. The content for the page is being assigned to a variable called "page". And the last line, output the content.

To debug the php script, you can access it by passing data into it, for example:

http://www.someurl.com/loader.php?page=page1

It should display the content for page1. If you know about php and database, you can store the content in the database and retrieve it. Make a simple form to edit the content and BANG... you got yourself a customized content management system.

	

//Get the page parameter from the url
switch($_GET['page'])  {
	case 'page1' : $page = 'Page 1'; 
					break;
	case 'page2' : $page = 'Page 2'; 
					break;
	case 'page3' : $page = 'Page 3'; 
					break;
	case 'page4' : $page = 'Page 4'; 
					break;
}
echo $page;

Conclusion

That's it. Make sure you check out the demo and download the source code and play with it. If you have created your own, feel free to drop your link in the comment section to show off! : )

Last but not least, I need your support :) If you like this article, please help me to promote it by adding this post to your bookmark. Or you can subscribe to my RSS for more jQuery tutorial and design inspiration posts! Thanks!

Demo 1Demo 2Download
Join the discussion

Comments will be moderated and rel="nofollow" will be added to all links. You can wrap your coding with [code][/code] to make use of built-in syntax highlighter.

188 comments
Dick 10 years ago
Hello.

I have a problem with loading ajax pages with links inside content div..
For example if I have a link inside page1 case in loader.php and I want to click this link on the first page in order to switch to page2 it won't work.. Apparently this works only when links are on the basic page outside of the php content that is put into content div. Do you have a solution for that?

Kind regards
Reply
PieterA 10 years ago
I have the same problem in IE8, in FF it works fine. If i try to put < a rel> links inside the HTML loaded from loader.php, they don't work from IE, while the do from FF. If i put these same links inside the static HTML in the page doing the ajax-call to loader.php, it works in IE.

Does anyone have a clue why?
Reply
Kevin Liew Admin 10 years ago
Ok, try and change this:

$('a[rel=ajax]').click(function () {

to

$('a[rel=ajax]').bind('live', function () {

that should make a different. Also, make sure the link in the content has attribute "rel='ajax'".
Reply
Dick 10 years ago
Hey!

bind function works for a while and then after clicking arround for a minute it just stops working.. Another huge problem is that jquery animations don't work..

if you have solutions for that it would be reall cool
Reply
Flo 9 years ago
Hi there!

I had the same problem with IE. I tried to change my code to "$('a[rel=ajax]').bind('live', function () {" but it didnt work out. iam not a professional but i changed it to "$('a[rel=ajax]').live('click', function () {" and suddenly it worked fine in IE. So maybe this helps ;)

best regards
Reply
Kevin Liew Admin 9 years ago
Flo you're right! I don't know why I wrote bind('live',.... I must be dreaming back then. :p Sorry Dick!
Reply
mick 10 years ago
hi, is there a way to make the first page preload.. so as soon as the site opens, content from page 1 is loaded?
Reply
Kevin Liew Admin 9 years ago
The script is in the last part of the tutorial.
Reply
vinit pratap singh 10 years ago
Hi, Kevin i have one problem in Safari Browser, page is mismatching... when i click page1 the page 1 content load as well, but when i click on page 2 the page 1 content show again... its not everything but some time i face this type of problem. is it any way to solve this type of problem thank you.
Reply
change 10 years ago
Why do you run the getpage(); function twice? Is there an advantage to this, because it seems like it is causing loading problems. Thanks!
Reply
Kevin Liew Admin 9 years ago
Which part of code are you talking about?
Reply
Gabe 9 years ago
any advice on how change things to load entire documents instead of just html?
Reply
Kevin Liew Admin 9 years ago
hmm, that's interesting idea. If you want to refresh the entire document, why don't you just link it to the new page?
Reply
Gabe 9 years ago
i have a fair amount of scripts that i have accumulated, a header and a footer that i don't want to reload every time new content is loaded. can these scripts be altered to allow php pages? is Ian Venkus approach below accurate? thanks for all your help.
Reply
yuma 9 years ago
It seems like the demos don't always work on google chrome/safari.
It sort of works, but the new content appear correctly(ie: If I'm on the portfolio section and I click the 'about' section, and the portfolio section appears again).
It seems to work fine on Fire Fox though.
Any idea why?
Thanks
Reply
Kevin Liew Admin 9 years ago
hmm, I can't replicate your issue.
Reply
John A. 9 years ago
Do you have a way of implementing this with a form submit? I've tried several options without any luck.
Can't use the hash nor the history plugin I suppose. Have a simple search form with multiple calls (?q=search&w=theinput).

Is it possible to do it with the following:

$('#nameofform').submit(function (e) {
e.preventDeafult();
and so on...
});
Reply
Kevin Liew Admin 9 years ago
Yes, almost right. You will need to submit the form using AJAX.
http://www.queness.com/post/160/create-a-ajax-based-form-submission-with-jquery
Reply
Sanu 9 years ago
Thanks.
Reply
Petr 9 years ago
hello,
I have a problem with php debugging. I need get to URL for example " index.php?page=home ". I can get to script loader.php variable " page= ", but in URL I canĀ“t show " index.php?page= ." Simply I need remove "#" and insert "?".
My code :
$(document).ready(function () {
$.history.init(pageload);

$('a[href=' + window.location.href + ']').addClass('selected');

$('a[rel=ajax]').click(function () {
var hash = this.search;
hash = hash.replace(/^.?/, '');
// $.history.load(hash);

$('a[rel=ajax]').removeClass('selected');
$(this).addClass('selected');
$('#body').hide();
$('.loading').show();

getPage(hash);
return false;
});

});

function pageload(hash) {
if (hash) getPage(hash);
}
function getPage(hash) {
var data = hash;
$.ajax({
url: "loader.php",
type: "GET",
data: data,
cache: false,
success: function (html) {
$('.loading').hide();
$('#content').html(html);
$('#body').fadeIn('slow');
}
});
}


thanks
Reply
zetta 9 years ago
Hello, I have a problem when I want to call different page when every menu I choose which the page I call is in PHP and displayed in id="content". Example I have 3 top menu such as Home, Menu, About Us then when I click Home then the home.php is displayed, click Menu the Menu.php will displayed and click About Us the AboutUs.php will displayed.
Could you mind help me to fix this problem?
-Thanks a lots-
Reply
Erik MS 9 years ago
Very nice tutorial, but I needed to remove the hash (#) signs from the following cases to make it work, is it a typo in the tutorial?

This works:

//Get the page parameter from the url
switch($_GET['page']) {
case 'page1' : $page = 'Page 1';
break;
case 'page2' : $page = 'Page 2';
break;
case 'page3' : $page = 'Page 3';
break;
case 'page4' : $page = 'Page 4';
break;
}
echo $page;
Reply
Kevin Liew Admin 9 years ago
I think you're right. Thanks!
Reply
Erik MS 9 years ago
Whenever I retrieve another page with:

case 'page3' : $page = include ($_SERVER['DOCUMENT_ROOT'].'/nywww/myPage.php'); break;

A "1" appears to be appended to the output echo statement, any idea why?
Reply
Callum Kerr 9 years ago
Hey, I'm having a little issue. Basically, instead of having case '#page1' : $page = 'content' I'm using case '#page1' : $page = include('other.php').

It works fine, however after the content a single "1" is displayed and I can't get rid of it. I was wondering if you have any workarounds for this?

Cheers.
Reply
Kevin Liew Admin 9 years ago
Hi Callum Kerr & Erik MS,

I can't seem to replicate the problem, would you able to inspect the response return from the PHP using firebug or chrome to check if the 1 is returned by PHP itself?
Reply
Callum Kerr 9 years ago
Hey Kevin, sorry for the time I took to reply, took a break for a couple of months.

According to Firebug Lite (Chrome) the response from the server is "<b>About</b><br/>Content, lolz.1" so the 1 is being sent down ... not sure if that's what you're asking for.

This is an online version of the page, if it helps you: http://cdn.ckwebsitedesign.net/ajax/index.php

Thanks =]
Reply
Mike 9 years ago
I'm also getting the echo of '1'. Not a PHP hotshot by any stretch, by removing the 'break;' after:

switch($_GET['page']) {
case '#page1' : $page = include('content/home.php');

removes the 1 but of course loads the portfolio page as part of the home page...any progress on this? I've had no luck removing the #.
Reply
Ed 9 years ago
Regarding this problem, just remove the "echo $page", since it does nothing on php include.
The include will be pretty much the page, so the echo just returns 1 for include with sucess.
Reply