
<!--

/*************************************************************************
*
* Live AJAX Search Features for UKSeries
*
*  v1.0.0: 25th November 2009
*
***************************************************************************/



/*************************************************************************
*  History:
*
*
***************************************************************************/




/*************************************************************************
*
*  Script Notes
*  ------------
*
*
*  INPUTS:
*
*   • The inputs mostly control what gets sent to the AJAX server script as a POST'd string and
*     thus hopefully determine the data that returns.
*
*     • The name of the object below can be anything we like and if calling multiple times on a page
*       it'd be a good idea to create multiple names. We just use 'uks_live_entry_search_inputs' as
*       an example of the object name. See the "how to call" section for more details.
*
*     • The only one that's a little different is the .callbackfunc one which is the name of the function
*       we call at the end of the whole AJAX process. Effectively sends back details from AJAX so we know
*       if the lookup worked and what data it returned. More details are in the OUTPUTS section below.
*
*
*
*   Create Object:
*
*     # Add this before any of the following (see "how to call" section for details)
*     var uks_live_entry_search_inputs = new Object();
*
*
*   Required Inputs:
*
*    • uks_live_entry_search_inputs.eqs  [OR]
*
*    • uks_live_entry_search_inputs.tid  [OR]
*
*    • uks_live_entry_search_inputs.clt
*    • uks_live_entry_search_inputs.cln
*    • uks_live_entry_search_inputs.cdist
*
*    • uks_live_entry_search_inputs.callbackfunc	// See outputs for details of this one
*
*
*   Optional Inputs:
*
*    • uks_live_entry_search_inputs.eqsexc
*    • uks_live_entry_search_inputs.showeqs
*    • uks_live_entry_search_inputs.showhtml
*    • uks_live_entry_search_inputs.rid
*    • uks_live_entry_search_inputs.maxent
*    • uks_live_entry_search_inputs.stars
*    • uks_live_entry_search_inputs.sleepmin
*    • uks_live_entry_search_inputs.sleepmax
*    • uks_live_entry_search_inputs.subtplid
*    • uks_live_entry_search_inputs.subtpldesclen
*    • uks_live_entry_search_inputs.tidcobf
*    • uks_live_entry_search_inputs.tidcobfmin
*    • uks_live_entry_search_inputs.reqbookable
*    • uks_live_entry_search_inputs.remdups
*    • uks_live_entry_search_inputs.remdupsrewrites
*    • uks_live_entry_search_inputs.remdupsprefaff
*    • uks_live_entry_search_inputs.dupcheckforceeqs
*    • uks_live_entry_search_inputs.tariffmin
*    • uks_live_entry_search_inputs.tariffmax
*    • uks_live_entry_search_inputs.facilities
*    • uks_live_entry_search_inputs.themes
*    • uks_live_entry_search_inputs.formcache
*
*
*
*
*
*  OUTPUT:
*
*   • Outputs are done via a callback function as defined in the uks_live_entry_search_inputs.callbackfunc input.
*
*   • The name of the callback function should be assigned as uks_live_entry_search_inputs.callbackfunc=my_callback_function;
*     without any '' marks due to it being effectively a pointer and not a name string.
*
*     • As long as the assignment is done within the same script block it can be above or below the actual function, else
*       the function must exist by the time this assignment takes place.
*
*   • The callback function will be triggered at the end of the AJAX process and is the only way to find out whether the
*     lookup actually worked. Checking the return value of the _initiator function just checks as far as the AJAX triggering
*     which is unlikely to fail unless AJAX just didn't initiate (eg: very old browser).
*
*
*
*   Main Output Objects:
*
*     • The name of the output object is purely for example and should be the name given in the () bit
*       of the callback function, eg: in this case it might be my_callback_func(uks_live_entry_search_results)
*
*       Within this object there are a number of values which will always exist, although might be blank. The
*       most important of these is the .status value which tells us whether the lookup worked or an error occured.
*
*       • uks_live_entry_search_results.status		: 0=Fine, 1=No Entries, 2=Server Error, 3=Input Error
*       • uks_live_entry_search_results.eqs_list	: The EQS list - delimited (if requested)
*       • uks_live_entry_search_results.raw_html	: The HTML block to print (if requested)
*
*
*
*
*
*  HOW TO CALL:
*
*   • To call the functions and search, we need to create the inputs giving at least one from the top
*     group an input or we'll get a status=3 back, ie: the uks_live_entry_search_inputs above.
*
*     • Once they're setup as a global object, we then pass the object to uks_live_entry_search_initiator()
*       eg: uks_live_entry_search_initiator(uks_live_entry_search_inputs);
*
*     • The name of the object is entirely independent of the script as long as that object name is used in
*       the above call. This allows for multiple inputs to be used on one page so we can perform multiple tasks
*       with this system with no interfereance between scripts.
*
*
*     • It's a good idea to test for a return value on that function, but only "false" will indicate a failure
*       before the AJAX had chance to run.
*
*       • TRUE from here only indicates that the AJAX object was created and is likely to run, but doesn't
*         prove whether the URL was valid or anything actually came back. If this is true then we can move
*         onto the proper check below.
*
*
*     • To check the AJAX data we need to create a callback function which can collect a single argument containing
*       the output details. The name of this function is determined by the uks_live_entry_search_inputs.callbackfunc
*       value as shown in the inputs section earlier, eg: .callbackfunc = my_callback_func;
*
*       • This function name can be different for any instance of the script, so allowing us to use this system
*         multiple times on a page without interferance from each option.
*
*       • What this function does is entirely externally determined, but recommendations are that it checks the value
*         of the .status property of the object passed to it to see what result we got.
*
*         • If it's 0 then we can carry on using the EQS or HTML data as appropriate, eg: pass to another function.
*         • If it's 1 then maybe print a message about no search results for this lookup, or whatever's appropriate.
*         • If it's 2 then something went caput at the server end so maybe try again later.
*         • If it's 3 then one or more major inputs is missing, eg: no EQS, TID or C/O
*
*         Eg: If we'd set the callback function to be my_callback_func(object_containing_data){} then we'd want to
*             check the value of "object_containing_data.status" for the above values.
*
*
*   • Finally we need to call this script which should probably be done towards the top of the page since nothing will
*     run until called upon, eg: <script src="live_entry_search_ajax.js" language="JavaScript" type="TEXT/JAVASCRIPT"></script>
*
*
*
*
*  DEBUGGING:
*
*   • If Firebug is enabled we can also trace the outputs there in the console.
*
*
***************************************************************************/






/*************************************************************************
*
*  Global Settings:
*
***************************************************************************/

var uks_live_entry_search_processor_script  = 'http://' + window.location.hostname + '/live-search-outputs/';
var uks_live_entry_search_processor_timeout = 10000; /* ms before aborting AJAX (10000 = 10 seconds) */







/*************************************************************************
*
*  Fixed & Server Variables:
*
*   • Since we want to be able to use this system pottentially several times on
*     a page for different things, anything global really needs to be an array.
*
*     In the _initiator function we create a unique ID that is then passed as
*     one of the input object properties called .instanceid and we use this to
*     generate the ID values for these arrays to keep everything in sync.
*
*
***************************************************************************/

var uks_live_entry_search_settings = new Object();
	uks_live_entry_search_settings.output_mode  = 1; 		// 1=Call a pre-set function, 2=Use non-async mode (doesn't work in FF currently)

var uks_live_entry_search_ajax_object  = new Array();		// The AJAX object container array
var uks_live_entry_search_ajax_aborted = new Array(); 		// Incase we have to abort the lookup





// Make this compatible when not running Firebug...!
//
//  Without this the script will run into all kinds problems if we're not running
//  FF Firebug, which most people won't be. So this effectively fakes that and lets
//  FF, IE, Safari etc. get on with working.
//
//  To see any errors, use Firebug in Firefox and view the console section (needs reload).

if (typeof(console) === "undefined" || typeof(console.log) === "undefined" || typeof(console.error) === "undefined") {

	var console   = new Object();
    console.log   = function(fakeinput) { };
    console.error = function(fakeinput) { };
    console.info  = function(fakeinput) { };
    console.debug = function(fakeinput) { };
    console.warn  = function(fakeinput) { };

}







/*************************************************************************
*
*  								FUNCTIONS
*
***************************************************************************/


function uks_live_entry_search_initiator(ajax_input_object) {



	// Make sure the settings were set

	if (!ajax_input_object) {

		console.error("FUNC ajax_entry_search: _initiator : No input objects available so can't do any settings");
		return false;

	}




	//
	// Setup an ID
	//
	//  This is a unique ID that can be used for things like array names to keep track of
	//  which data in a global variable relates to which lookup. It means we can have
	//  multiple versions of the system running without conflicting certain global data.
	//
	//  Also handy way to pass data from the pre to post AJAX bit as that can be global
	//  but we just need to pass the ID and we'll know which bit to lookout for.
	//

	var new_time = new Date();
	ajax_input_object.instanceid = new_time.getTime();




	// About to call AJAX
	//
	//  Initialise and reset various variables before the AJAX triggers.
	//  Since most data is either internal or reset externally there's not much to do.

	uks_live_entry_search_ajax_aborted[ajax_input_object.instanceid] = 0;




	// Call the AJAX
	//
	//  This calls the _caller function which checks all the data and assuming no
	//  errors, it sends it on to the AJAX function to download. A return value here
	//  simply indicates no input errors and AJAX initialised, not data available.

	if (!uks_live_entry_search_ajax_caller(ajax_input_object)) {

		console.error("FUNC ajax_entry_search: _initiator : AJAX caller function returned false indicating problem with AJAX object initiating");
		return false;

	}
	else {

		// Just says well that bit worked so not wait for the data.
		return true;

	}




	//
	// If we get to this point then the AJAX process appears to have worked.
	//
	//  The above check can only test whether the AJAX object was created and not whether
	//  we got any data back due to the break caused by the AJAX callback function.
	//
	//  Therefore from this point on we have to wait for the custom callback function to
	//  be triggered (see notes above), and then we can test the .status part of the output
	//  object to see if the lookup worked or not.
	//



}





function uks_live_entry_search_ajax_caller(ajax_input_object) {



	var tmp_valid_main_input_found = 0;

	var tmp_instance_id = parseInt(ajax_input_object.instanceid); // Unique ID for this call




	if (!ajax_input_object) {

		console.error("FUNC ajax_entry_search: _ajax_caller: No input objects passed to function, ie: 'uks_live_entry_search_inputs' object not made available as argument");
		return false;

	}




	//
	// Test EQS values which can be - delimited
	//

	if (ajax_input_object.eqs) {


		var tmp_split_eqs_test_array_new = new Array();
		var tmp_eqs_output_counter = 0;


		var tmp_split_eqs_test_array = ajax_input_object.eqs.split('-'); // Split into component parts

			ajax_input_object.eqs = ''; 								 // Clear so it not used unless valid


		if (tmp_split_eqs_test_array.length > 0) {


			for (var eqstest=0; eqstest < tmp_split_eqs_test_array.length; eqstest++) {

				if (tmp_split_eqs_test_array[eqstest].match(/[0-9]+[A-Z]{3,4}A[0-9]/)) {

					tmp_split_eqs_test_array_new[tmp_eqs_output_counter] = tmp_split_eqs_test_array[eqstest];
					tmp_eqs_output_counter++;

				}

			}


			if (tmp_split_eqs_test_array_new.length > 0) {

				ajax_input_object.eqs = '';
				ajax_input_object.eqs = tmp_split_eqs_test_array_new.join('-');

				tmp_valid_main_input_found = 1;

			}


		}


	}




	//
	// Test for TID value
	//

	if (ajax_input_object.tid) {

		var tmp_test_tid_value = parseInt(ajax_input_object.tid);

		ajax_input_object.tid  = 0; // Clear so not used unless valid

		if ((tmp_test_tid_value > 0) && (tmp_test_tid_value != isNaN())) {

			ajax_input_object.tid = tmp_test_tid_value;
			tmp_valid_main_input_found = 1;

		}

	}




	//
	// Test for valid C/O values
	//


	if ((ajax_input_object.clt) && (ajax_input_object.cln) && (ajax_input_object.cdist)) {

		var tmp_test_co_clt   = parseFloat(ajax_input_object.clt);
		var tmp_test_co_cln   = parseFloat(ajax_input_object.cln);
		var tmp_test_co_cdist = parseInt(ajax_input_object.cdist);

		ajax_input_object.clt   = 0;
		ajax_input_object.cln   = 0;
		ajax_input_object.cdist = 0;

		if ((tmp_test_co_clt != isNaN()) && (tmp_test_co_cln != isNaN())) {

			if ((tmp_test_co_clt != 0) && (tmp_test_co_cln != 0)) {

				if (tmp_test_co_cdist > 0) {

					tmp_valid_main_input_found = 1;

					ajax_input_object.clt   = tmp_test_co_clt;
					ajax_input_object.cln   = tmp_test_co_cln;
					ajax_input_object.cdist = tmp_test_co_cdist;

				}

			}

		}

	}





	// If no main input, return false()

	if (tmp_valid_main_input_found != 1) {

		console.error("FUNC ajax_entry_search: _ajax_caller: Major inputs missing, eg: eqs, tid, c/o etc. - probably not properly set in 'uks_live_entry_search_inputs' object");

		return false;

	}





	//
	// Prepare the AJAX call
	//

	var poststr 	 = '';
	var final_url 	 = '';


	poststr  = '';
	poststr  = "eq="  					+ ajax_input_object.eqs;
	poststr += "&tid=" 					+ ajax_input_object.tid;
	poststr += "&clt=" 					+ ajax_input_object.clt;
	poststr += "&cln=" 					+ ajax_input_object.cln;
	poststr += "&cdist=" 				+ ajax_input_object.cdist;
	poststr += "&eqexc=" 				+ ajax_input_object.eqsexc;
	poststr += "&eqexcbymatch=" 		+ ajax_input_object.eqsexcbymatch;
	poststr += "&showeqs=" 				+ ajax_input_object.showeqs;
	poststr += "&showhtml=" 			+ ajax_input_object.showhtml;
	poststr += "&rid=" 					+ ajax_input_object.rid;
	poststr += "&rcache="				+ ajax_input_object.rcache;
	poststr += "&maxent="				+ ajax_input_object.maxent;
	poststr += "&stars=" 				+ ajax_input_object.stars;
	poststr += "&sleepmin="				+ ajax_input_object.sleepmin;
	poststr += "&sleepmax="				+ ajax_input_object.sleepmax;
	poststr += "&subtplid="				+ ajax_input_object.subtplid;
	poststr += "&subtpldesclen="		+ ajax_input_object.subtpldesclen;
	poststr += "&tidcobf="				+ ajax_input_object.tidcobf;
	poststr += "&tidcobfmin="			+ ajax_input_object.tidcobfmin;
	poststr += "&reqbookable="			+ ajax_input_object.reqbookable;
	poststr += "&dupcheck="				+ ajax_input_object.dupcheck;
	poststr += "&dupcheckrewrites="		+ ajax_input_object.dupcheckrewrites;
	poststr += "&dupcheckprefaffs="		+ ajax_input_object.dupcheckprefaff;
	poststr += "&dupcheckforceeqs="		+ ajax_input_object.dupcheckforceeqs;

	poststr += "&tariffmin="			+ ajax_input_object.tariffmin;
	poststr += "&tariffmax="			+ ajax_input_object.tariffmax;
	poststr += "&facilities="			+ ajax_input_object.facilities;
	poststr += "&themes="				+ ajax_input_object.themes;

	poststr += "&formcache="			+ ajax_input_object.formcache;
	poststr += "&extcache="				+ ajax_input_object.extcache;
	poststr += "&usecacheid="			+ ajax_input_object.usecacheid;
	poststr += "&formcacheprefix="		+ ajax_input_object.formcacheprefix;
	poststr += "&extcacheprefix="		+ ajax_input_object.extcacheprefix;




	// Remove the 'undefined' if something not set
	poststr = poststr.replace(/undefined/gi, "");



	// Debug message
	console.info("INFO: FUNC ajax_entry_search: ajax_caller:\nThe URL call was: " + uks_live_entry_search_processor_script + '?' + poststr + "\n");

	if (document.getElementById('livesearchdebugurl')) {
		document.getElementById('livesearchdebugurl').innerHTML = uks_live_entry_search_processor_script + '?' + poststr;
	}



	//
	// Call the AJAX function
	//
	//  The async_static test essentially says if output mode is not = 1 then send false (ie: static)
	//  else by default send true which puts us in async mode. Currently doesn't work without more work
	//  in the AJAX bit anyway, so it's always true (and not 100% sure we want it to be non-async anyway).
	//

	var tmp_ajax_async_or_static 		  					= (uks_live_entry_search_settings.output_mode != 1) ? 'false' : 'true';

		uks_live_entry_search_ajax_object[tmp_instance_id] 	= new uks_ajaxObject_live_search_mod(uks_live_entry_search_processor_script, uks_live_entry_search_ajax_processor);
	var tmp_live_search_status  		  					= uks_live_entry_search_ajax_object[tmp_instance_id].update(poststr,'POST',tmp_ajax_async_or_static,ajax_input_object.callbackfunc,ajax_input_object.instanceid);




	// Set the AJAX abort timeout

	setTimeout("uks_live_entry_search_ajax_timeout("+tmp_instance_id+")", uks_live_entry_search_processor_timeout);




	// Return from function
	//
	//  If we're using uks_live_entry_search_settings.output_mode=1 then this will return almost
	//  immediately and probably long before the AJAX has downloaded any data. We don't use it's
	//  return to go searching since we'll be calling the callback function instead.
	//
	//  If we're using the uks_live_entry_search_settings.output_mode=2 then this should indicate
	//  the end of the AJAX process so checking for a return from this function should indicate that
	//  we can check the data variables for the results.

	if (tmp_live_search_status === true) {
		return true;
	}
	else {

		console.error("FUNC ajax_entry_search: _ajax_caller: Something seems to have gone wrong inside the AJAX call, eg: fault in calling URL (see info section of firebug)");
		return false;

	}



}




//
// POST AJAX BEING INITIATED - NOW COLLECT DATA //
//





function uks_live_entry_search_ajax_processor(responseText, responseStatus, responseXML, finalCallbackFunc, instanceId) {



var int_ajax_search_results_obj = new Object();
 	int_ajax_search_results_obj.status    	= 2;			// 0 for OK, 1 for slight prob, 2 server error, 3 input error
 	int_ajax_search_results_obj.eqs_list  	= ''; 			// EQS list - delimited
 	int_ajax_search_results_obj.raw_html	= ''; 			// HTML block to print
 	int_ajax_search_results_obj.cache_id	= ''; 			// An MD5 ID for the cached form data


	instanceId = parseInt(instanceId); // The unique ID for this lookup



	if (responseStatus==200) {



		// The JSON code returning from AJAX call

		var ajax_response 	= responseText;
		var ajax_error_code	= 0;
		var tmp_ajax_data_download_code = 0;




		// Find only JSON data
		//
		//  Make sure it's only the JSON data that gets unserialised
		//
		//  The checks make sure that we find something from the match() just incase the
		//  output wasn't the required JSON data. Also gets around a glitch whereby match
		//  returns null as the value if nothing found and FF for one complains about this
		//  being assigned, but only in Firebug (not the console which is helpful!).
		//

		var json_ajax_outer_regex 	= /.*<!--JSON_DATA_START-->(.+)<!--JSON_DATA_END-->.*/;
		var tmp_response_data 	  	= ajax_response.match(json_ajax_outer_regex);

		if (tmp_response_data instanceof Array) {

			var ajax_response = tmp_response_data[1];

		}
		else {

			var ajax_response;
			tmp_ajax_data_download_code = 2;

			console.error("FUNC ajax_entry_search: _ajax_processor: Any data returned from the AJAX call does not contain the JSON START and END tags suggesting server fault or possibly timeout.");

		}




		// The format of eval() is critical
		//
		//  See: http://msdn.microsoft.com/en-us/library/bb299886.aspx#intro_to_json_topic4
		//  to save hours of bafflement until that pointed to the formatting of the eval() call
		//  otherwise it comes back with 'undefined' for anything in the array.
		//
		//  We need to check the value of "tmp_ajax_data_download_code" from above as that determines
		//  whether any JSON we got back was likely to be valid looking data. If not then we just send
		//  blank array parts to prevent any errors.

		var json_code_array = new Array();

		if (tmp_ajax_data_download_code != 2) {
			json_code_array = eval( "(" + ajax_response + ")" );
		}
		else {
			json_code_array.search_eqs  = '';
			json_code_array.search_html = '';
		}





		// Collect the AJAX data
		//
		//  - The first bit gets the results from the server as it sees it, which hopefully
		//    will tie in with the real state of the JSON output.
		//
		//  - The second bit checks whether the server send a status of 0 but we didn't find a lot
		//    of JSON data which generally points to something going caput in the server end. Shouldn't
		//    happen, but worth checking just incase.
		//
		//  - After that we collect the data from the server in the form of the EQS and HTML blocks
		//    depending what was requested. On error these will be empty since they were cleared in
		//    the _initiator function at the beginning.


		int_ajax_search_results_obj.status = parseInt(json_code_array.search_status);

		int_ajax_search_results_obj.status = (tmp_ajax_data_download_code == 2) ? 2 : int_ajax_search_results_obj.status;


		if ((int_ajax_search_results_obj.status == 0) && (tmp_ajax_data_download_code == 0)) {

			if (json_code_array.search_eqs) {
				int_ajax_search_results_obj.eqs_list  = json_code_array.search_eqs.join("-");
			}

			if (json_code_array.search_html) {
				int_ajax_search_results_obj.raw_html  = json_code_array.search_html;
			}

			if (json_code_array.search_cache_id) {
				int_ajax_search_results_obj.cache_id  = json_code_array.search_cache_id;
			}

		}




		// Debug incase of AJAX status 2
		//
		//  Handy debugging info for the Firebug console if we're using it.

		if (int_ajax_search_results_obj.status == 2) {

			console.error("FUNC ajax_entry_search: _ajax_processor: AJAX JSON returned status 2 - Server Error");

		}
		else if (int_ajax_search_results_obj.status == 3) {

			console.error("FUNC ajax_entry_search: _ajax_processor: AJAX JSON returned status 3 - 1+ major inputs were missing");

		}
		else if (int_ajax_search_results_obj.status == 1) {

			console.info("INFO: FUNC _ajax_processor: AJAX JSON returned status 1 - No entries available for this lookup");

		}
		else {
			// No errors in the output
		}



	}





	//
	// Anything in this part runs regardless of whether we got http status 200
	//




	// Check if the lookup aborted (timeout)
	//
	//  We use the instanceId to make sure this is the right lookup that aborted and if
	//  so we'll return a status 2 to the callback function so we know there's no data coming.

	if (uks_live_entry_search_ajax_aborted[instanceId] == 1) {

		int_ajax_search_results_obj.status = 2;
		console.error("FUNC _ajax_processor: AJAX process was aborted with instance ID " + instanceId);

	}




	// If running in mode=1, call the callback function
	//
	//  This allows whatever calls the AJAX system to know that the downloads
	//  have finished and we're ready to collect the status and data.

	if (uks_live_entry_search_settings.output_mode == 1) {
		finalCallbackFunc(int_ajax_search_results_obj);
	}




	// Clear the AJAX object
	//
	//  Since this one won't be used anymore but might still contain some data
	//  we might as well clear it the best we can and remove the memory usage.

	uks_live_entry_search_ajax_object[instanceId] = null;




	// Do return
	//
	//  Doesn't really do anything useful as it's only returning to the AJAX code
	//  but it keeps FF errors quiet. If we could get output_mode=2 to work with
	//  non-async then it'd be handy, but doesn't look like that's gonna happen.

	return true;



}







function uks_live_entry_search_ajax_timeout(instanceId) {


	if (uks_live_entry_search_ajax_object[instanceId]) {

		if (uks_live_entry_search_ajax_object[instanceId].updating != false) {

			instanceId = parseInt(instanceId);

			console.error("FUNC _ajax_timeout: Aborting over-running AJAX connection");

			uks_live_entry_search_ajax_aborted[instanceId] = 1;
			uks_live_entry_search_ajax_object[instanceId].abort();

		}

	}


	return true;


}







// ------------ AJAX CODE ITSELF ------------ //
//                                            //
// This is pretty standalone code, although this version has been tweaked more than others
// so if looking for a more standard version, try something like live tariffs AJAX script.
//
//
// Credits:
//
// Original script by: http://www.hunlock.com/blogs/The_Ultimate_Ajax_Object
// (recommended reading as it also has other useful bits inc. how to use the timeout).
//
//
//  Trev Tweaks:
//
//  - The .update function now accepts another parameter for a final callback function.
//    Not the same one as normally used in AJAX, but one to say the call worked for use
//    with external calling scripts, otherwise we never know.
//
//    - Also added this callback function link to the "this.callback" code so it's passed back
//      as a 4th parameter of that and picked up in the function which accepts the AJAX data
//      (aka the final callback function mentioned above).
//
//  - Added a link to the Firebug console so we can more easily debug using Firefox with the
//    Firebug addon. Handy for seeing exactly what the script is doing without lots of alerts.
//
//    - If using elsewhere, remember to include the console code at the top of any script to enable
//      this to work when Firebug isn't active or isn't installed (ie: most systems).
//
//  - Added some more code to the .update function so we can in theory run in non-async mode, but that
//    turned out to be complicated since FF especially doesn't trigger the readystate function as normal
//    thus more re-coding will be required. Plus it seriously locks up the browser. See:
//
//   http://bytes.com/topic/javascript/answers/535643-firefox-xmlhttprequest-onreadystatechange-handler-not-called
//


function uks_ajaxObject_live_search_mod(url, callbackFunction) {


	var that=this;
	this.updating = false;

	this.abort = function() {

		if (that.updating) {

			that.updating=false;
			that.AJAX.abort();
			that.AJAX=null;

		}

	}


	this.update = function(passData,postMethod,async_mode,finalCallbackFunc,instanceId) {



		async_mode = (async_mode == 'false') ? false : true;
		instanceId = parseInt(instanceId);


		if (that.updating) {
			return false;
		}


		that.AJAX = null;


		if (window.XMLHttpRequest) {
			that.AJAX=new XMLHttpRequest();
		} else {
			that.AJAX=new ActiveXObject("Microsoft.XMLHTTP");
		}


		if (that.AJAX==null) {

			console.error("FUNC: uks_ajaxObject_live_search_mod :: Attempt to start AJAX object failed suggesting serious browser problems or no J/script");
			return false;

		} else {

//			if (async_mode == true) {

				that.AJAX.onreadystatechange = function() {

					if (that.AJAX.readyState==4) {

						that.updating=false;
						that.callback(that.AJAX.responseText,that.AJAX.status,that.AJAX.responseXML,finalCallbackFunc,instanceId);
						that.AJAX=null;

					}

				}

//			}
//			else {

//				that.updating=false;
//				that.callback(that.AJAX.responseText,that.AJAX.status,that.AJAX.responseXML);
//				that.AJAX=null;

//			}



			that.updating = new Date();

			if (/post/i.test(postMethod)) {

				var uri=urlCall+'?'+that.updating.getTime();
				that.AJAX.open("POST", uri, async_mode);
				that.AJAX.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
				that.AJAX.setRequestHeader("Content-Length", passData.length);
				that.AJAX.send(passData);

			} else {

				var uri=urlCall+'?'+passData+'&timestamp='+(that.updating.getTime());
				that.AJAX.open("GET", uri, async_mode);
		//        that.AJAX.open("GET", uri, false);
				that.AJAX.send(null);

			}

			return true;

		}


	}


	var urlCall = url;
	this.callback = callbackFunction || function () { };

}
















// -->