// GLOBALS
var mybic_failed_requests = 0; // a placeholder to count the number of failed requests to the server
/**
* Constructor for MyBIC's ajax object
* This only needs to be instantiated once in your script and you'll be able to re-use the same object for all your requests
*@param string The URL of the page you're going to connect to on the server, by default mybic_server.php
*@param string The function that will be called when ajax responses come back from the server, by default mybic handles this for you
*/
function XMLHTTP(server_url, readyStateFunction)
{
this.version = '0.6.4';
this.server_url = server_url; // the SERVER page URL to connect to IE ajax_server.php
this.async = true; // whether we're in syncronous mode or async (default)
this.debug=1; // debug turned off by default, to see your request/response do ajaxObj.debug=1
this.throttle=1; // this enables throttling by default so all your requests are in the proper order
this.method = "POST"; // by default all requests are sent via POST to override just use ajaxObj.method="GET"; before your call
this.req = null; // the xmlhttprequest variable, starts off as null
this.headers = new Array(); // array of optional headers you may pass in
this.callBack = ''; // the callback function, when the ajax request is sent, this is the function that will be called
this.format = "JSON"; // by default JSON encoding is the expected format, to override: ajaxObj.format = "XML"; or ajaxObj.format="TEXT";
this.net_down_func = this.down; // the function that will be called if mybic cannot make a request to the server (server down)
this.abort_timeout = -1; // the number of seconds to wait before calling network down function, set to -1 disable feature, defaults to 5 seconds
this.failed_threshold = 3; // the number of failed requests before mybic is disabled -> prevents repeated error notifications
this.ignoreCall = 0; // set this to 1 if you have a polling object and you don't want to see debug msgs every second or activity indicators
this.readyStateFunction = (readyStateFunction) ? readyStateFunction : this.responseHandler;
/*-- SYSTEM PROPERTIES - no need to change the properites below --*/
this.debugID = 0; // used for showing expandable visual debug data
this.errors = new Array(); // array of errors generated
this.queue = new Array(); // the queue that will handle the throttling requests to keep your stuff in sync
this.queue_in_process = 0; // the current index for the throttling array
this.currentCallIgnore=0; // system uses this to see what calls to ignore from the queue
}
/**
* Method to create an XMLHTTP object
*@access private
*/
XMLHTTP.prototype.getXMLHTTP = function()
{
// moz XMLHTTPRequest object
if (window.XMLHttpRequest) {
this.req = new XMLHttpRequest();
}
// IE/Windows ActiveX version
else if (window.ActiveXObject){
this.req = new ActiveXObject("Microsoft.XMLHTTP");
} else {
if(this.debug == 1) {
this.showDebug(" FATAL ERROR: Could not create XMLHTTPRequest Object! ");
}
return false;
}
return this.req;
}
/**
* Main API method to use for AJAX requests
* example: ajaxObj.call("action=loadComments&id=1", myCallBackFunction);
*@access public
*@param string A url encoded string of data to send to the server
*@param string A callback function that the server will launch when the response is generated
*@param string Used by the response handler function to send back throttled requests, you won't need to worry about this param
*/
XMLHTTP.prototype.call = function(queryVars, userCallback, queue_request)
{
// test for too many failed requests
if(mybic_failed_requests >= this.failed_threshold) {
// call network down method with instruction to notify of mybic being disabled
this.net_down_func('disable');
return false;
} else {
var currentVars;
var callback;
this.fullUrl = '';
if(this.throttle == 1 && queue_request != 'queue') { // throttling keeps your requests in sync, so things aren't out of order
this.add2Queue(queryVars, userCallback);
}
if(this.queue_in_process == 0)
{
// get XMLHTTPRequest Object
if(!this.getXMLHTTP())
{
return false;
}
if(this.throttle == 1) {
this.queue_in_process = 1;
var currentCall = this.queue.shift(); // get the current call to make
currentVars = currentCall.queryVars;
callback = currentCall.userCallback;
this.currentCallIgnore = currentCall.ignoreCall;
} else {
currentVars = queryVars;
callback = userCallback;
var ignoreCall=0;
}
this.callBack = callback;
// set response handler, if none is set, use our default one
this.req.onreadystatechange = this.readyStateFunction;
// check for JSON encoding
if(this.format != 'JSON') {
currentVars = currentVars+'&json=false';
}
// if get is used, append the query variables to the url string
this.full_url = (this.method == "POST") ? this.server_url : this.server_url + '?'+ currentVars;
if(this.debug == 1 && this.currentCallIgnore != 1) {
try {
var matches = currentVars.match(/action=(\w+)&?/);
this.showDebug('new', 'MYBIC - CALLING: '+matches[1]);
this.showDebug("Server Page: "+this.server_url+" HTTP Method: "+this.method+" Encoding Format: "+this.format+" Query String: "+currentVars+" ");
}catch(e){}
}
// open connection
this.req.open(this.method, this.full_url, this.async);
/*
// set any optional headers
if(this.headers){
for(var i in this.headers) {
alert(i);
if(i != '') {
try {
this.req.setRequestHeader( i, this.headers[i]);
if(this.debug == 1) { this.showDebug('Setting Custom Header: '+this.headers[i]+' ');}
} catch(e) {}
}
}
}
*/
// START TIMER TO ABORT REQUEST
if(this.abort_timeout != -1) {
this.end_timer = setInterval('ajaxObj.endCall()', this.abort_timeout);
}
// send request
if(this.method == 'POST') {
this.req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
this.request = currentVars;
this.req.send(currentVars);
} else {
this.req.send(null);
}
}
}
}
/**
* Default method for parsing the response from the server. It will try to eval the obj.method_to_call property and pass the native JS object
*/
XMLHTTP.prototype.responseHandler = function()
{
if(ajaxObj.req)
{
try
{
// only if req shows "complete"
if (ajaxObj.req.readyState == 4) {
// only if "OK"
if (ajaxObj.req.status && ajaxObj.req.status == 200) {
if(ajaxObj.req.responseText.indexOf('ajax_msg_failed') != -1) {
ajaxObj.showDebug("Fatal Error: mybic_server sent back ajax_msg_failed! - MSG: "+ajaxObj.req.responseText+" ");
ajaxObj.callBack(false);
} else {
// clear out network down timer
if(this.abort_timeout != -1) {
clearInterval(ajaxObj.end_timer);
}
if(ajaxObj.format == "JSON") {
try {
var myObject = JSON.parse(ajaxObj.req.responseText);
/* security login check */
// are there any error messages
var variable = "myObject.errors";
var defined = eval('(typeof('+variable+') != "undefined");');
if (defined) {
// check if there is a login error
variable = "myObject.errors['error_num']";
defined = eval('(typeof('+variable+') != "undefined");');
if (defined) {
if (myObject.errors['error_num']==0) {
alert("For a security reason your session has timed out. \nYou will now be redirected to a login window. \n\n Thank you for your patience!");
window.location = myObject.errors['login_url'];
return;
}
}
}
// callback function we passed to the server to process the results
if(document.getElementById(ajaxObj.callBack)) {
document.getElementById(ajaxObj.callBack).innerHTML = myObject;
} else {
ajaxObj.callBack(myObject);
}
} catch(e) {
alert('an error occurred in your response function, not mybic related. Error Name: ' + e.name + ' Message:' + e.message);
if(document.getElementById(ajaxObj.callBack)) { } else {
ajaxObj.callBack(false);
}
}
} else if(ajaxObj.format == "XML") {
// send the raw xml data to the callback function
ajaxObj.callBack(ajaxObj.req.responseXML);
} else {
if(document.getElementById(ajaxObj.callBack)) {
document.getElementById(ajaxObj.callBack).innerHTML = ajaxObj.req.responseText;
} else {
ajaxObj.callBack(ajaxObj.req.responseText);
}
}
}
mybic_failed_requests = 0; // reset failed requests back to 0
} else {
// server is came back with a bad status
try{
ajaxObj.showDebug("Fatal Error: MSG: "+ajaxObj.req.responseText+" StatusText: "+ajaxObj.req.statusText+" ");
} catch(e){}
ajaxObj.endCall();
}
if(ajaxObj.debug == 1 && ajaxObj.currentCallIgnore != 1) {
// STRIP HTML
var str = ajaxObj.req.responseText.replace(/(\<)/gi, '<');
var str = str.replace(/(\>)/gi, '>');
ajaxObj.showDebug("HTTP Server Response: "+str+" ");
}
// reset the method, format, etc back to class defaults
ajaxObj.restoreDefaults();
// reset our queue and call
ajaxObj.queue_in_process = 0;
if(ajaxObj.queue.length > 0) {
ajaxObj.call('','','queue');
}
}
} catch(e) {
/*network is down*/}
}
}
/**
* This method will allow you to lazy load javascript source files for on-demand javascript processing
* Just pass in the url of the javascript file you wish to pull in and you're all set, its not ajaxified so you
* can pull in scripts from any URL you want!
*@param string The URL of the script you wish to load
*/
XMLHTTP.prototype.loadScript = function(url)
{
try{
// lets check to see if the script is already loaded, if so lets remove it and add a new one
var scripts = document.getElementsByTagName('script');
s_len = scripts.length;
for(var i=0;i");}
} catch(e) {
// server is completely down, call netdown function
clearInterval(ajaxObj.end_timer);
ajaxObj.net_down_func('disable');
}
}
/**
* Default method that will be called when mybic experiences a network down situation, or is disabled
* This method will pop up a div alerting the user of a general network error
* You should define your own method to properly fit in with your page layout
*/
XMLHTTP.prototype.down = function(status)
{
var notif_div = '
';
notif_div += ' MSGHERE
';
if(status == 'disable') {
var notif = 'A network issue has disabled network connections for this page. Please reload this page or contact the site administrator';
} else {
var notif = 'A network issue has occurred which canceled your last request';
}
// lets try and find an existing error message or use the current one in the DOM
try{
if(document.getElementById('mybic_notification')) {
document.getElementById('mybic_notification').style.display='block';
} else {
var new_div = document.createElement('div');
new_div.innerHTML = notif_div;
document.body.appendChild(new_div);
}
document.getElementById('mybic_notif_msg').innerHTML = notif;
} catch(e) {
alert('Network Unavailable: Please re-load page or contact the site administrator');
}
}
/**
* This method will let developers view debug information on the screen from not only the system calls but also let them tap into it as well
*@access public
*@param string The Message you wish to push to debugging or pass in 'break' and the UI will break a new expandable column for you
*@param string OPTIONAL: If you pass in break, also send in a string that will show what the break label should be
*@param int OPTIONAL: If you pass in break, if you pass in a 1 to the function it will allow you have your section autoexpanded
*/
XMLHTTP.prototype.showDebug = function(msg, label, expand)
{
if(ajaxObj.debug == 1) {
if(!document.getElementById('mybic_debug')) {
var errs = document.createElement('div');
errs.id = 'mybic_errs';
var deb = document.createElement('div');
deb.id = 'mybic_debug';
deb.style.border = "thick solid black";
deb.style.backgroundColor = "#eeeeee";
deb.style.padding = "10px";
deb.style.margin = '75px 10px 10px 10px';
deb.style.width = '90%';
deb.innerHTML += 'MyBic Debugger: hide/show me!';
deb.innerHTML += ' Clear';
deb.innerHTML += ' Expand All';
deb.innerHTML += ' Contract All
';
deb.appendChild(errs);
if(document.body) {
document.body.appendChild(deb);
} else {
document.lastChild.appendChild(deb);
}
}
var deb = document.getElementById('mybic_errs');
if(msg == 'new') {
ajaxObj.debugID++;
var dimg = '+';
deb.innerHTML += '
'+dimg+' label'+ajaxObj.debugID+': '+label+'
';
} else {
deb.innerHTML +='
'+msg+'
';
}
}
}
/**
* This method is used by MyBic to visually show the debug data you've passed in
*@private
*@param object The image element that triggers the show/hide functionality
*/
XMLHTTP.prototype.debug_expand = function(el)
{
var deb = document.getElementById('mybic_errs');
var deb_len = deb.childNodes.length;
if(el == 'none' || el == 'block') {
var label = "mybic_debug";
var links = deb.getElementsByTagName('a');
var links_len = links.length;
for(var q=0;q';
}
} else {
var label = el.parentNode.id;
label = label.split('_');
label = "mybic_debug"+label[1];
}
for(var i=0; i