The AJAX-functionality is what makes this CMS interesting. Instead of reloading the whole page for every action we take while maintaining the database, we will simply create small chunks of code that will be loaded into the DIVs we created in the previous page. This way we get a nice overview of the whole CMS as well as minimizing the loading times. To make all this work we need to create some AJAX-functions. And that's what we're about to do in this page.
This file contains all functions that are essential to get the AJAX-functionality to work. To do this we need to create three functions. Let's get started with the first one.
The following two variables need to be global, otherwise the functions can't share them:
var xmlHttp;
var area;
Global variables will be shown in green while local variable will be shown in red in JavaScript code. (yellow-ish background)
The purpose of this function is to create the XMLHttpRequest()-object and store it into the variable xmlHttp. Today, since IE7, there is no problem on this front since all browser supports the same function. However, IE6 and earlier had different ways of creating that object, and that's when this function comes in. It checks what browser you use by testing if certain functions exists. Depending on your browser it will solve the problem differently. In the end the result should be the same: a fully functional XMLHttpRequest()-object, ready to use.
function GetXmlHttpObject() {
var xmlHttp = null;
try {
xmlHttp = new XMLHttpRequest();
} catch (e) {
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
}
return xmlHttp;
}
Enter this code into the ajax.js-file and let's get going with the next function:
This is the function that makes the output to the page. Once the readyState-property of the XMLHttpRequest()-object (stored in the xmlHttp-variable) reaches 4, which means that the page is fully loaded and complete, the function outputs the page into the DIV of choice, represented here by the area-variable.
function stateChanged() {
if (xmlHttp.readyState==4) {
document.getElementById(area).innerHTML = xmlHttp.responseText;
}
}
Finally the function that should be called whenever you click a link. This function takes three passed values which are all required to make it work. Passed-in variables will be displayed in blue color within all code samples.
function updatePage(PAGE,AREA,QUERY) {
xmlHttp = GetXmlHttpObject();
if (xmlHttp==null) { alert ("Your browser does not support AJAX!"); return; }
if (AREA != "0") {
for (var i=4; i >= AREA; i--) {
document.getElementById("flap_num" + i).style.display = "none";
document.getElementById("flap_num" + i).innerHTML = "";
}
}
area = "flap_num" + AREA;
var url = "cms/" + PAGE + ".php?sid=" + Math.random() + QUERY;
xmlHttp.onreadystatechange = stateChanged;
xmlHttp.open("GET",url,true);
xmlHttp.send(null);
document.getElementById(area).style.display = "block";
}
Let's walk through this code chunk by chunk:
function updatePage(PAGE,AREA,QUERY) {At the first row you'll notice that three values are passed into the functions. PAGE will contain the file name of the page to load into a specified DIV. AREA will contain the number of the "flap" to put that file in and QUERY will contain a string of data that will be attached to the file name as a querystring.
xmlHttp = GetXmlHttpObject();The first thing we do is to set the global xmlHttp-variable with the GetXmlHttpObject()-function (See above). Now the xmlHttp-variable will contain the XmlHttpRequest()-object, and we can start to work with it.if (xmlHttp==null) { alert ("Your browser does not support AJAX!"); return; }If you're using an ancient browser that doesn't support the XMLHttpRequest()-object there wouldn't be any point in running this script. Therefore the next paragraph tests whether or not the xmlHttp-variable contains an object or not. If it doesn't you'll get an alert message and the script will be cancelled.if (AREA != "0") {The purpose of this for-loop is to hide DIVs that are below the currently requested one. This way we get rid of old content when we change menu. Let's break this loop apart:
for (var i=4; i >= AREA; i--) {
document.getElementById("flap_num" + i).style.display = "none";
document.getElementById("flap_num" + i).innerHTML = "";
}
}
if (AREA != "0") {As you remember the "flap_num0"-DIV is dedicated to the list pages. Since we never want to hide that DIV we start by making sure that the requested DIV isn't "flap_num0". If it is there's no need to run the loop and therefore we skip it. Thus the AREA-value shouldn't be zero.for (var i=4; i >= AREA; i--) {The for-loop begins. The i-variable is a counter variable that keeps track of how many times the loop has run. Note that the beginning value is set to 4. This number is important since it coresponds to the highest "flap"-number. If you in the future need to upgrade the code with more "flaps" you must change this number accordingly. The next statement within the for-loop parenteses is the comparison statement. This code tells the loop to run as long as the i-variable holds a value that are greater or equal to the passed in value of AREA (which holds the number of the currently requested "flap". The last loop statement holds the modification of i. This code tells the loop that the i-variable should be decreased by one for each loop.
document.getElementById("flap_num" + i).style.display = "none";At the third row we hide the DIV corresponding to the current value of the i-variable. By concatenating the i-variable to the "flap_num"-string the code locates the DIV with that particular ID. (That would be "flap_num4" in the first round of the loop). The value of the CSS-property display of that DIV is changed to "none", which means that it becomes hidden.document.getElementById("flap_num" + i).innerHTML = "";The DIV is now hidden but it still holds the HTML content from before. If we where to request that same DIV with new content there's a chance that we would see the old content before the new one was properly loaded, and that's not an effect we want. Therefore we empty the DIV of all HTML before continuing on.}The two closing curly brackets at the bottom closes the loop and the if-statement.
}
area = "flap_num" + AREA;The ID of the currently requested "flap" is concatenated with the string "flap_num" and the AREA-value and stored in the global variable area.
var url = "cms/" + PAGE + ".php?sid=" + Math.random() + QUERY;The url-variable is created and assigned the name and path of the file that are to be loaded into the currently requested DIV. Notice that the .php extension is added for you, so you will never have to add that when you pass in a PAGE-value. You may add additional folder structure though, although they must be located within the "cms"-folder as the code is now. This also means that you are limited to call php-files. You can remove the file extension from here if you like, but then you have to remember to add a file extension when you call the updatePage-function. In this tutorial I will only use php-files so that's why I made it easy on myself. You should also notice that the querystring "sid" is automatically added and given a random number. This querystring value will never be accessed in the code but will instead act as a workaround to eliminate cached content. Since the value of the "sid" will never be the same twice in a row the browser will interpret this as new page content, although it might be the same page loaded again. This way the browser won't show you a cached version which means that you can be sure to see the current data in the database. Finally the string passed in with the QUERY-value will be added. We'll talk a lot more about the QUERY-value on later pages. Let's just leave it as it is for now.
xmlHttp.onreadystatechange = stateChanged;The following three lines of code is AJAX code. Here the "onreadystatechange"-property of the XMLHttpRequest()-object is accessed. Every time the "onreadystatechange"-property changes value the "stateChanged"-function will be called (see above). Once the readystate changes to 4 the XMLHttpRequest()-object will be told to receive text. (within the stateChanged-function (see above)).xmlHttp.open("GET",url,true);The next line of code opens the page stored in the url-variable
xmlHttp.send(null);The server call is terminated.document.getElementById(area).style.display = "block";The last line of code shows the newly updated DIV to the visitor.Eager to click those links we created at the previous page? In that case we need to create those code chunks that will be called by the function. Now you will only get a "Not Found on this Server"-notice. But by all means, try it out!
Next Up: Building our first code chunks