/*
* Simple AJAX
* Written By: Tyler O'Brien (tyler@indie-dev.net)
* File Version: 2012.04.25.1
* */
/*
* Create a fallback for IE6.
* IE5 and earlier might not work.
* */
if (typeof XMLHttpRequest == 'undefined') {
var XMLHttpRequest = function() {
return new ActiveXObject('Microsoft.XMLHTTP');
}
XMLHttpRequest.prototype.isActiveX = true;
}
XMLHttpRequest.prototype.send_s = function(method, queryString) {
if (method == 'POST') this.send(queryString);
else if (this.isActiveX) this.send();
else this.send(null);
}
/*
* AjaxHandler
* This object contains boilerplate functions that help organise the code of Simple AJAX.
* These probably won't need to be used outside of the AjaxRequest constructor function.
* Note:
* These functions are also where the default values are assigned.
* */
var AjaxHandler = {
/*
* CallIfExists() returns nothing
* Input: Function, Mixed, Mixed
* Takes a callback, and up to two optional parameters.
* Depending on the number of parameters given will make one of three different calls.
* */
CallIfExists: function(callback, param1, param2) {
if (callback) {
if (param2) callback(param1, param2);
else if (param1) callback(param1);
else callback();
}
},
/*
* GetCarset() returns String
* Input: String
* Takes a passed object, assumed String.
* If NULL or UNDEFINED is passed then a default value is returned.
* Otherwise the passed value is returned back.
* */
GetCharset: function(charset) {
return (charset) ? charset : 'utf-8';
},
/*
* GetContentType() returns String
* Input: String
* See GetCharset().
* */
GetContentType: function(contentType) {
return (contentType) ? contentType : 'application/x-www-form-urlencoded';
},
/*
* GetMethod() returns String
* Input: String
* See GetCharset().
* */
GetMethod: function(method) {
return (method) ? method : 'GET';
},
/*
* GetQueryString() returns String
* Input: Object
* Takes an object of (key=>value) pairs and converts them to a query string.
* For example:
* The object {a:1,b:2,c:3} would become "a=1&b=2&c=3".
* Note that the question mark is not appended to the beginning.
* */
GetQueryString: function(data) {
var output = '';
if (data) {
var output = '';
for (var key in data) {
output = (output + key +'='+ data[key] + '&');
}
// Trim off the extra ampersand.
output = output.substring(0, output.length-1);
}
return output;
},
/*
* GetUrl() returns String
* Input: String
* See GetCharset().
* */
GetUrl: function(url) {
return (url) ? url : '/';
},
/*
* GetUrlToOpen() returns String
* Input: String, String, String
* Returns the value that will be passed to the XMLHttpRequest.open() function.
* If the method is a GET it will be the entire URL, as well as the query string.
* If the method is a POST then it will only be the query string.
* */
GetUrlToOpen: function(url, queryString, method) {
return (method == 'POST') ? url : (url + '?' + queryString);
}
};
/*
* AjaxRequest
* The base class which holds all of the objects used to make AJAX requests.
* Is implemented in the Ajax() function.
* */
function AjaxRequest(args) {
this.charset = AjaxHandler.GetCharset(args['charset']);
this.contentType = AjaxHandler.GetContentType(args['contentType']);
this.http = new XMLHttpRequest();
this.method = AjaxHandler.GetMethod(args['method']);
this.onConnect = args['onConnect'];
this.onError = args['onError'];
this.onNotFound = args['onNotFound'];
this.onProcess = args['onProcess'];
this.onRequest = args['onRequest'];
this.onSuccess = args['onSuccess'];
this.onTimeout = args['onTimeout'];
this.queryString = AjaxHandler.GetQueryString(args['data']);
this.timeBegin = 0;
this.timeDifference = 0;
this.timeEnd = 0;
this.timeout = null;
this.url = AjaxHandler.GetUrl(args['url']);
this.urlToOpen = AjaxHandler.GetUrlToOpen(this.url, this.queryString, this.method);
}
/*
* Ajax() returns nothing
* Input: Object
* The main function for Simple AJAX.
* Every time this function is called it will create a new AjaxRequest object.
*
* Example usage:
* Ajax({
* method: 'GET',
* url: '/path/to/file.html',
* onSuccess: function(response){
* console.log('Received: ' + response);
*});
* */
function Ajax(args) {
var ajaxRequest = new AjaxRequest(args);
ajaxRequest.http.open(ajaxRequest.method, ajaxRequest.urlToOpen, true);
ajaxRequest.http.setRequestHeader('Content-type', ajaxRequest.contentType+'; charset='+ajaxRequest.charset);
if (ajaxRequest.method == 'POST') {
ajaxRequest.http.setRequestHeader('Content-length', ajaxRequest.queryString.length);
ajaxRequest.http.setRequestHeader('Connection', 'close');
}
ajaxRequest.http.onreadystatechange = function(){
switch (ajaxRequest.http.readyState) {
case 1:
ajaxRequest.timeBegin = new Date().getTime();
AjaxHandler.CallIfExists(ajaxRequest.onConnect);
break;
case 2:
AjaxHandler.CallIfExists(ajaxRequest.onRequest);
break;
case 3:
AjaxHandler.CallIfExists(ajaxRequest.onProcess);
break;
case 4:
if (ajaxRequest.timeout) {
clearTimeout(ajaxRequest.timeout);
}
ajaxRequest.timeEnd = new Date().getTime();
ajaxRequest.timeDifference = (ajaxRequest.timeEnd - ajaxRequest.timeBegin);
switch (ajaxRequest.http.status) {
case 200:
AjaxHandler.CallIfExists(ajaxRequest.onSuccess, ajaxRequest.http.responseText, ajaxRequest.timeDifference);
break;
case 404:
AjaxHandler.CallIfExists(ajaxRequest.onNotFound, ajaxRequest.http.responseText, ajaxRequest.timeDifference);
default:
AjaxHandler.CallIfExists(ajaxRequest.onError, ajaxRequest.http.status, ajaxRequest.timeDifference);
break;
}
break;
}
};
/*
* Add a new timeout if one is given.
* The time is assumed to be milliseconds.
* */
if (args['timeout']) {
ajaxRequest.timeout = setTimeout(function() {
ajaxRequest.http.abort();
AjaxHandler.CallIfExists(ajaxRequest.onTimeout);
}, args['timeout']);
}
ajaxRequest.http.send_s(ajaxRequest.method, ajaxRequest.queryString);
}