Testing OOP Ajax
Source
/**
* @fileoverview Simple Object Oriented Ajax Class
*
* @version 1.1
*
* @author Shawn Parker (shawn@topfroggraphics.com)
*/
/* @usage
//-----------------------------------------------------------------------------------//
Basic usage is:
// instantiate the class
var myAjax = new oopAjax();
// run the ajax call
myAjax.doAjax( 'url/to/call.php', document.getElementById('foo') );
url/to/call.php -- should be a valid relative or full url pointing to a publically
accessible script. Doesn't have to be PHP - any language that can echo or print will do.
document.getElementById('id') -- can be this or an actual object pointer to a valid
html element in your page. If your custom script uses different methods that don't need
this object pointer then just pass a null.
//-----------------------------------------------------------------------------------//
Extended usage is:
// define a new subclass
oopToo = function()
{
// grab inheritance from oopAjax
this.inheritFrom = oopAjax;
this.inheritFrom();
// define new loaded function - refers to function defined below
this.doWhenLoaded = newDoWhenLoaded;
// a different way of defining new functionality
this.doWhileLoading = function(targetObj)
{
targetObj.innerHTML = 'Loading even more content...';
}
}
// define our new function for loading
function newDoWhenLoaded(response, targetObj)
{
targetObj.innerHTML = 'secondary function: ' + response;
}
// lets set our target outside the function call this time
var targetObj = document.getElementById('result');
// instantiate the class
myAjax = new oopToo();
myAjax.doAjax('/url/to/call.php',targetObj);
Here we make a subclass that inherits all functionality from the parent oopAjax class.
the first two lines: this.inheritFrom = oopAjax; and this.inheritFrom(); will be the
same across all subclasses.
There are 3 functions designed to be overwitten: doWhileLoading, doOnError, doWhenLoaded
doWhileLoading -- runs while request is being made
doOnError -- runs in case an error is returned by the request
doWhenLoaded -- runs on successful request to remote script
//-----------------------------------------------------------------------------------//
Embedding Code in HTML
Preferred usage is to put this in an included file, but if you're gonna write the code
directly into the page then use the tags below to do so. This is both backward compatable
to browsers that don't understand Javascript and forward compatable to XHTML & XML.
//-----------------------------------------------------------------------------------//
To be done
- xmlHTTPRequests can be done to XML docs (per the name). Routine needs to be
added to handle this purpose.
- xmlHTTPRequests can be done via POST instead of GET but is dependent upon browser
compatability. Routine needs to be added to judge compatability and switch down or
error out if POST is not available.
- Create some shared functions for adding and deleting standard items using DOM.
Adding and deleting page elements is more forward compatable, though less easy
than innerHTML.
- Add internal error handling for better handling of mis-configurations. It is
currently left to JavaScript with arguably has the worst error reporting in
the history of programming languages.
- Add a delay function to help hold off new requests for a certain amount of time,
or to easily script a recurring refresh of content.
- Find a better name? Some people thing this currently has a silly name... buttheads
//-----------------------------------------------------------------------------------//
*/
function oopAjax() {
/**
* Assign the method for successul requests
* privileged method
*
* @variable function
*/
this.doWhenLoaded = stdDoWhenLoaded;
/**
* Assign the method for errors on request
* Privileged method
*
* @variable function
*/
this.doOnError = stdDoOnError;
/**
* Assign the method for while loading process
* Privileged method
*
* @variable function
*/
this.doWhileLoading = stdDoWhileLoading;
/**
* Start the XHR object
* Private Method
*
* @return object - XHR Object
*/
var startXMLReq = function() {
// create request object pointer
var request_obj = false;
if(window.XMLHttpRequest) {
// branch for native XHR
try {
request_obj = new XMLHttpRequest();
} catch(e) {
request_obj = false;
}
} else if(window.ActiveXObject) {
// branch for IE/Windows
try {
request_obj = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
try {
request_obj = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
request_obj = false;
}
}
}
// send object back
return request_obj;
}
/**
* start our XHR object pointer
* Private variable
*
* @variable Object Pointer
*/
this.http = startXMLReq();
/**
* Perform XHR
* Privileged method
*
* @param string requestUrl - our page that we're requesting
* @param string targetObj - Object Pointer
*/
this.doAjax = function(requestUrl, targetObj) {
// if the script is processing already then abort the call
if (this.http && this.http.readyState != 4) {
this.http.abort();
}
// call script
this.http.open('GET', requestUrl, true);
// set a request type header
this.http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// to fix variable scoping, create a pointer to the class instance as a local variable
var _this = this;
// handle the response
this.http.onreadystatechange = function() { _this.handleResponse(targetObj); }
// I don't like this being here but it makes Safari behave
this.doWhileLoading(targetObj);
// send request
this.http.send(null);
}
/**
* XHR Response Handler
* Privileged method
*
* @param Object Pointer
*/
this.handleResponse = function(targetObj) {
/*
Make sure the server is done by response code to XMLHttpRequest
0 : Uninitialized - open() has not been called
1 : Loading - send() has not been called
2 : Loaded - send() has been called, headers and status are available
3 : Interactive - Downloading, responseText holds partial data
4 : Finished - all operations complete
*/
if(this.http.readyState == 4) {
// only if server response is good
if(this.http.status == 200) {
// set response var to what was returned
var response = this.http.responseText;
// change browser to reflect change
this.doWhenLoaded(response, targetObj);
} else {
// show server error here
this.doOnError(this.http.StatusText, targetObj);
}
}
}
}
/**
* Do this on successful XHR
* Public method
*
* @param string response - this is the response from the remote script
* @param Object Pointer targetObj - this is the object we want to effect
*/
function stdDoWhenLoaded(response, targetObj) {
targetObj.innerHTML = response;
}
/**
* Do this on failed XHR
* Public method
*
* @param string error - this is the error response from request process
* @param Object Pointer targetObj - this is the object we want to effect
*/
function stdDoOnError(error, targetObj) {
targetObj.innerHTML = 'Unable to load content, please contact an administrator';
}
/**
* Do this on successful XHR
* Public method
*
* @param Object Pointer targetObj - this is the object we want to effect
*/
function stdDoWhileLoading(targetObj) {
targetObj.innerHTML = 'Loading content...';
}