﻿// ===================================================================
// Insyst Ajax stuff
//
// Ajax_Array[N][0] = table name, eg BaseTask
// Ajax_Array[N][1] = PKName
// Ajax_Array[N][2] = ParentKey	(PKVal of parent table)
// Ajax_Array[N][3] = Div ID
// Ajax_Array[N][4] = one-based num rows, eg 5 rows = 5; 0 rows = 0
// Ajax_Array[N][5] = csv list of changed FormID, eg Goal3,Goal5
// Ajax_Array[N][6] = SetBGColor function pointer
// Ajax_Array[N][7] = onInsert function pointer
// Ajax_Array[N][8] = onUpdate function pointer
// Ajax_Array[N][9] = onDelete function pointer
// ===================================================================

var Ajax_Array = new Array(); 
Ajax_Array[0] = ''; 

var AJAX_TNAME = 0;
var AJAX_PKNAME = 1;
var AJAX_PARENTKEY = 2;
var AJAX_DIVID = 3;
var AJAX_GRIDROWS = 4;
var AJAX_SAVELIST = 5;
var AJAX_BGCOLORFN = 6;
var AJAX_INSERTFN = 7;
var AJAX_UPDATEFN = 8;
var AJAX_DELETEFN = 9;

var AJAX_SPECIALFIELDS = 10;	// array of fields that need special processing when inserting a row

var VisibleAlertsFlag;

var Color_onChange = "#F8FFCC";
var Color_GreyedOut = "#E0E0E0";
var Color_Processed = "#FFFFFF";
var Color_Delete = "#FFCCFF";

var Cache_Save_On = new Image();	Cache_Save_On.src = "/iCMS/images/Button_Save_On.gif";
var Cache_Save_Off = new Image();	Cache_Save_Off.src = "/iCMS/images/Button_Save_Off.gif";
var Cache_Insert_On = new Image();	Cache_Insert_On.src = "/iCMS/images/Button_Insert_On.gif";
var Cache_Insert_Off = new Image();	Cache_Insert_Off.src = "/iCMS/images/Button_Insert_Off.gif";

function Ajax_LoadMassive(FormID, CtlName, CtlType, CtlKey, CtlSource, CtlDataSource, ParentCtl, ParentKey, onLoad_String, onChange_String, onFocus_String, onBlur_String)
{
	var XDiv;
	var DisplayText;
	var URL = '/iCMS/iCMS_Massive.asp?';

	URL += 'FormID=' + FormID;
	URL += '&CtlName=' + CtlName;
	URL += '&CtlType=' + CtlType;
	URL += '&CtlKey=' + CtlKey;
	URL += '&CtlSource=' + CtlSource;
	URL += '&CtlDataSource=' + CtlDataSource;

	if (ParentCtl != CtlName)
	{
		URL += '&ParentCtl=' + ParentCtl;
		URL += '&ParentKey=' + ParentKey;
	}

	URL += '&onLoad=' + onLoad_String;
	URL += '&onChange=' + onChange_String;
	URL += '&onFocus=' + onFocus_String;
	URL += '&onBlur=' + onBlur_String;
	//alert(URL);

	XDiv = document.getElementById(FormID + '_' + CtlName + '_Loading');	// show the animation span
	XDiv.style.display = "inline";

	AjaxRequest.get
	(
		  {
			'url': URL,
			'onSuccess' : function(req)
				{
					//alert(req.responseText); 
					if (CtlType == 'Combo')
					{
						XDiv = document.getElementById(FormID + '_' + CtlName + '_Button');		// hide the ... button span
						XDiv.style.display = "none";

						XDiv = document.getElementById(FormID + '_' + CtlName + '_Text');		// hide the displaytext span
						XDiv.style.display = "none";
						DisplayText = XDiv.innerHTML;	// save the display text so we can put it in the Filter box
						XDiv.innerHTML = '';			// get rid of the displayed text

						XDiv = document.getElementById(FormID + '_' + CtlName + '_Hidden');		// hide the hidden span
						XDiv.style.display = "none";
						XDiv.innerHTML = '';			// get rid of the hidden control

						XDiv = document.getElementById(FormID + '_' + CtlName + '_Hidden');		// hide the animation span
						XDiv.style.display = "none";	

						XDiv = document.getElementById(FormID + '_' + CtlName + '_Clr');		// hide the clear span
						XDiv.style.display = "none";

						XDiv = document.getElementById(FormID + '_' + CtlName + '_Loading');	// hide the animation span
						XDiv.style.display = "none";

						XDiv = document.getElementById(FormID + '_' + CtlName);					// hide the combo span
						XDiv.style.display = "none";
						XDiv.innerHTML = req.responseText;										// reset the contents
						XDiv.style.display = "inline";											// show the combo span

						XDiv = document.getElementById(FormID + '_' + CtlName + '_Clr');		// reshow the clear span
						if (XDiv != null)
						{
							XDiv.style.display = "inline";
						}

						XDiv = document.getElementById(FormID + '_' + CtlName + '_Filter');		// how the filter span
						//XDiv.innerHTML = DisplayText;
						if (XDiv != null)
						{
							XDiv.style.display = "inline";
						}
						
						if (onChange_String != '')
						{
							XDiv = document.getElementById(FormID + '_' + CtlName + '_Go');		// show the go span
							if (XDiv != null)
							{
								//XDiv.innerHTML = "<input type=button class='CMS_Button_SL' value='go' onClick=\"" + onChange_String + "\">";
								//alert(XDiv.innerHTML);
								XDiv.style.display = "inline";
							}
						}
					}
					else
					{
						XDiv = document.getElementById('SL_' + CtlName + '_' + FormID);		// put the selectlist in
						XDiv.innerHTML = req.responseText;

						XDiv = document.getElementById('SS_' + CtlName + '_' + FormID);		// put the selectlist in
						XDiv.innerHTML = '&nbsp;';												// clear the text
					}
				},
			'onError':function(req){ alert('Error!\nStatusText='+req.statusText+'\nContents='+req.responseText);},

			'timeout': 60000,
			'onTimeout':function(req){ alert('Timed Out!'); }
		  }
	);
}

/*---------------------------------------------------------------------------------------------------------------
函式名稱：	Ajax_LoadPage(Div_Animation,Div_Target,URL)
Called By:	
撰寫日期：	2007-06-04
撰寫人員：	Jones Lin
函式功能：	1. use ajax to separate large content loading from the base page [for example ivote or shayne home pages]
			2. expose team to programming with Ajax
敘述:		loads a passed page via ajax, hides the animation when loading is complete,
			and puts the page's content into the target div
參數：		- Div_Animation, name of the div holding the animation
			- Div_Target, name of the div to hold the page's content
			- URL, page to load via ajax

使用範例：	Ajax_LoadPage('Animation_PIC', 'Div_target', 'http://localhost')
---------------------------------------------------------------------------------------------------------------*/
function Ajax_LoadPage(Div_Animation,Div_Target,URL)
{
	
	var XDiv;

	XDiv = document.getElementById(Div_Animation);	// show the animation span
	XDiv.style.display = "inline";

	AjaxRequest.get
	(
		  {
			'url': URL,
			'onSuccess' : function(req)
				{
						XDiv = document.getElementById(Div_Animation);		// hide the animation span
						XDiv.style.display = "none";
						//alert('Error!\n Can Not Display the Page \n URL='+URL);
						XDiv = document.getElementById(Div_Target);			// 
						//alert('stage 1');
						//alert('req.responseText: '+req.responseText);
						XDiv.innerHTML = req.responseText;					// reset the contents
						//alert('stage 2');
						XDiv.style.display = "inline";						// show the combo span
						//alert('stage 3');
						
					
				},
			//'onError':function(req){ alert('Error!\nStatusText='+req.statusText+'\nContents='+req.responseText);},
			'onError':function(req){ 
										//alert('Error!\n Can Not Display the Page \n URL='+URL);
									},
			'timeout': 30000,
			'onTimeout':function(req){ 
										//alert('Timed Out!');
									}
		  }
	);
}



// function stuffs fields that need special processing when inserting a row [file, image, etc]
function Ajax_StuffSpecialField(TableName, FieldName, FieldType)
{
	var AjaxRow = Ajax_FindIndex_Simple(TableName)
	var NumSpecialFields = Ajax_Array[AjaxRow][AJAX_SPECIALFIELDS].length;
	//alert('TableName: ' + TableName + '\nFieldName: ' + FieldName + '\nFieldType: ' + FieldType + '\nAjaxRow: ' + AjaxRow + '\nNumSpecialFields: ' + NumSpecialFields);

	Ajax_Array[AjaxRow][AJAX_SPECIALFIELDS][NumSpecialFields] = new Array();
	Ajax_Array[AjaxRow][AJAX_SPECIALFIELDS][NumSpecialFields][0] = FieldName;
	Ajax_Array[AjaxRow][AJAX_SPECIALFIELDS][NumSpecialFields][1] = FieldType;

}

function Ajax_StuffArray(TableName, PKName, GridRows, ParentKey, DivID, Fn_BGColor, Fn_Insert, Fn_Update, Fn_Delete)
{
	var NumBlocks = Ajax_Array.length;
	Ajax_Array[NumBlocks] = new Array();
	
	Ajax_Array[NumBlocks][AJAX_TNAME] = TableName;
	Ajax_Array[NumBlocks][AJAX_PKNAME] = PKName;
	Ajax_Array[NumBlocks][AJAX_GRIDROWS] = GridRows;	// one-based NumRows, so 0 = no data
	Ajax_Array[NumBlocks][AJAX_PARENTKEY] = ParentKey;
	Ajax_Array[NumBlocks][AJAX_DIVID] = DivID;
	Ajax_Array[NumBlocks][AJAX_SAVELIST] = '';
	Ajax_Array[NumBlocks][AJAX_BGCOLORFN] = Fn_BGColor;
	Ajax_Array[NumBlocks][AJAX_INSERTFN] = Fn_Insert;
	Ajax_Array[NumBlocks][AJAX_UPDATEFN] = Fn_Update;
	Ajax_Array[NumBlocks][AJAX_DELETEFN] = Fn_Delete;

	Ajax_Array[NumBlocks][AJAX_SPECIALFIELDS] = new Array();
}

function Ajax_FindIndex(TableName, ParentKey)
{
	var RetVal = -1;

	for (var Loopy=1; Loopy < Ajax_Array.length; Loopy++)
	{
		//alert ('TName: ' + Ajax_Array[Loopy][AJAX_TNAME] + '\nParentKey: ' + Ajax_Array[Loopy][AJAX_PARENTKEY]);
		if (Ajax_Array[Loopy][AJAX_TNAME] == TableName && Ajax_Array[Loopy][AJAX_PARENTKEY] == ParentKey)
		{
			RetVal = Loopy;
			break;
		}
	}
	return RetVal;
}

function Ajax_FindIndex_Simple(TableName)
{
	var RetVal = -1;

	for (var Loopy=1; Loopy < Ajax_Array.length; Loopy++)
	{
		//alert ('TName: ' + Ajax_Array[Loopy][AJAX_TNAME] + '\nParentKey: ' + Ajax_Array[Loopy][AJAX_PARENTKEY]);
		if (Ajax_Array[Loopy][AJAX_TNAME] == TableName)
		{
			RetVal = Loopy;
			break;
		}
	}
	return RetVal;
}


function DeleteChecked(WhichTable, FormID, ParentKey, CurrentState)
{
	var AjaxRow = Ajax_FindIndex(WhichTable, ParentKey);
	var XMode;

	//alert('iCMS.js: DeleteChecked\nWhichTable:' + WhichTable + '\nFormID: ' + FormID + '\nCurrentState:' + CurrentState);
	if (CurrentState == true)
	{
		XMode = 'delete';
	}
	else
	{
		XMode =  'process';
	}
	Ajax_Array[AjaxRow][AJAX_BGCOLORFN](FormID, ParentKey, XMode);
}


/*---------------------------------------------------------------------------------------------------------------
函式名稱：	Ajax_SaveList_Add(WhichTable, FormID)
撰寫日期：	2005-12-28
撰寫人員：	Sunil Narayan
函式功能：	Adds FormID to list whenever a row is updated; checks if FormID exists in list; if not, add it
參數：		- WhichTable, identifies grid
			- FormID, identifies form row

使用範例：	Ajax_SaveList_Add('Goal3')
---------------------------------------------------------------------------------------------------------------*/
function Ajax_SaveList_Add(WhichTable, FormID, ParentKey)
{
	//alert('WhichTable: ' + WhichTable + '\nFormID: ' + FormID + '\nParentKey: ' + ParentKey);
	var AjaxRow = Ajax_FindIndex(WhichTable, ParentKey)

	if (Ajax_Array[AjaxRow][AJAX_SAVELIST] =='')
	{
		Ajax_Array[AjaxRow][AJAX_SAVELIST] = FormID;
	}
	else
	{
		var FormID_Array = Ajax_Array[AjaxRow][AJAX_SAVELIST].split(",");
		var FoundFlag = false;
		
		for (var loopy = 0;loopy < FormID_Array.length;loopy++) 
		{
			if (FormID_Array[loopy] ==FormID)
			{
				FoundFlag = true;
				break;
			}
		}
		if (!FoundFlag)
		{
			Ajax_Array[AjaxRow][AJAX_SAVELIST] += ("," + FormID);
		}
	}
	//document.getElementById("Debug1").innerText = Ajax_Array[AjaxRow][AJAX_SAVELIST];
	//alert(Ajax_Array[AjaxRow][AJAX_SAVELIST]);
}

function Ajax_SendForm(WhichTable, FormBase, ParentKey)	// eg, Ajax_SendForm('Project_Expense', 'CMS_Form_', 1)
{
	var AjaxRow = Ajax_FindIndex(WhichTable, ParentKey);
	var PKName = Ajax_Array[AjaxRow][AJAX_PKNAME];
	var DivID = Ajax_Array[AjaxRow][AJAX_DIVID];

	var FormString;						// eg CMS_Form_Goal3
	var FormID;							// eg Goal3
	var FormRoot = WhichTable + '_' + ParentKey;

	var RecordID;						// Identity value of the data row
	var validFlag = true;				// whether form passed validation
	var DoSubmit_Flag = true			// flag to see if we can submit
	var HasUpdates_Flag = false;
	var HasInserts_Flag = false;

	if (Ajax_Array[AjaxRow][AJAX_SAVELIST] != '')
	{
		var FormID_Array = Ajax_Array[AjaxRow][AJAX_SAVELIST].split(",");

		// -------------------
		// forms to update
		// -------------------
		for (var loopy = 0;loopy < FormID_Array.length;loopy++) 
		{
			FormID = FormID_Array[loopy];
			FormString = FormBase + FormID;					// eg "CMS_Form_Goal3"
			
			//alert('FormString: ' + FormString + '\nFormBase: ' + FormBase + '\nFormID: ' + FormID + '\nFormRoot: ' + FormRoot);

			if (FormID != FormRoot + '_0')					// ie don't process "CMS_Form_Goal0". we always put the insert row form as ID zero
			{
				DoSubmit_Flag = true						

				if (FormBase == 'CMS_Form_')				// currently, Validate only works on forms named 'CMS_Form_Something'
				{
					DoSubmit_Flag = ValidateForm(WhichTable, FormID);	// eg Validate('Planner_Goal', 'Planner_Goal_0_3')
				}

				if (DoSubmit_Flag)							// if we skipped Validation due to incompatible form name, or if we passed validation 
				{
					HasUpdates_Flag = true;
					var status = AjaxRequest.submit
						(
							document.forms[FormString],
							{
								'onSuccess':function(req)
									{
										var FormRetVal = req.responseText;
										if (!isNumeric(FormRetVal))
										{
											var repStr1 = new RegExp("<br>", "g");	// having trouble replacing when \n as the newline character, so use a dummy
											FormRetVal=FormRetVal.replace(repStr1, "\n")
											alert(FormRetVal);
											//document.getElementById("Debug1").innerText = FormRetVal;
										}
										else
										{
											RecordID = FormRetVal;
										}
									}
							}
						);
					
					Ajax_Array[AjaxRow][AJAX_BGCOLORFN](FormID, ParentKey, 'process');	//SetBGColor(FormID, 'process');
					if (Ajax_Array[AjaxRow][AJAX_UPDATEFN] != '')
					{
						Ajax_Array[AjaxRow][AJAX_UPDATEFN](FormID, ParentKey);
					}
				}
				else
				{
					validFlag=false;
				}
			}
		}

		// -------------------
		// form to insert
		// -------------------
		for (var loopy = 0;loopy < FormID_Array.length; loopy++) 
		{
			FormID = FormID_Array[loopy];
			FormString = FormBase + FormID;					// eg "CMS_Form_Goal3"

			//alert('FormString: ' + FormString + '\nFormBase: ' + FormBase + '\nFormID: ' + FormID);
			if (FormID == FormRoot + '_0')					// ie ONLY process "CMS_Form_Goal_0". we always put the insert row form as ID zero
			{
				DoSubmit_Flag = true;				
				if (FormBase == 'CMS_Form_')				// currently, Validate only works on forms named 'CMS_Form_Something'
				{
					DoSubmit_Flag = ValidateForm(WhichTable, FormID);	// eg Validate('Planner_Goal', 'Planner_Goal_0_3')
				}
				if (DoSubmit_Flag)							// if we skipped Validation due to incompatible form name, or if we passed validation 
				{
					validFlag = false;						// control the message flag from in here
					HasInserts_Flag = true;
					var status = AjaxRequest.submit
						(
							document.forms[FormString],
							{
								'onSuccess':function(req)
									{
										var FormRetVal = req.responseText;
										if (!isNumeric(FormRetVal))
										{
											/*var repStr1 = new RegExp("dummyfoo", "g");	// having trouble replacing when \n as the newline character, so use a dummy
											
											FormRetVal = unescape(FormRetVal);
											FormRetVal=FormRetVal.replace(repStr1, "\n")
											alert(FormRetVal);
											*/
											var repStr1 = new RegExp("<br>", "g");	// having trouble replacing when \n as the newline character, so use a dummy
											FormRetVal=FormRetVal.replace(repStr1, "\n")
											alert(FormRetVal);
											//document.getElementById("Debug1").innerText = FormRetVal;
										}
										else
										{
											RecordID = FormRetVal;
											Ajax_Array[AjaxRow][AJAX_GRIDROWS]++;  //zero-based total records += 1
											Ajax_Array[AjaxRow][AJAX_BGCOLORFN](FormID, ParentKey, 'process');		// call bgcolorFn to uncolor the row
											Ajax_InsertRow(AjaxRow, DivID, FormRoot, FormString, RecordID, PKName, WhichTable);	// call add new row
											Ajax_Array[AjaxRow][AJAX_BGCOLORFN](FormRoot + "_" + Ajax_Array[AjaxRow][AJAX_GRIDROWS], ParentKey, 'process');
											
											if (Ajax_Array[AjaxRow][AJAX_INSERTFN] != '')
											{
												Ajax_Array[AjaxRow][AJAX_INSERTFN](FormID, ParentKey);
											}

											if (VisibleAlertsFlag)
											{
												alert (Msg_Updated);
											}
										}
									} // end onSuccess
							}
						);	// end AjaxRequest.submit
				} // end if (DoSubmit_Flag)
			}
		}

		if (DoSubmit_Flag && validFlag)
		{
			if (VisibleAlertsFlag)
			{
				alert (Msg_Updated);
			}
		}
		Ajax_Array[AjaxRow][AJAX_SAVELIST] = '';
	}
}

function Ajax_InsertRow(AjaxRow, DivID, FormRoot, FormString, RecordID, PKName, WhichTable)	// eg Ajax_InsertRow('Goals_List', 'Goal', 'CMS_Form_Goal0', 999, 'prm_GoalID')
{
	var strHTML='';
	var TempVar;
	var Posn;
	var DivFooter;
	var ZeroForm = FormRoot + "_0";				// eg Goal_0
	var repStr1 = new RegExp(ZeroForm, "g");
	//var repStr2 = new RegExp('<TBODY>', "g");
	//var repStr3 = new RegExp('</TBODY>', "g");

	var RowToInsert;
	var Form_PKField;
	//alert('FormString: ' + FormString + '\nAjaxRow: ' + AjaxRow + '\nDivID: ' + DivID + '\nFormRoot: ' + FormRoot + '\nRecordID: ' + RecordID + '\nPKName: '+ PKName + '\nZeroForm: ' + ZeroForm);
	
	// ------------------------------------------------------------------------
	// save everything up to the insert row into strHTML
	// ------------------------------------------------------------------------
	//alert( 'DivID: ' + DivID );
	//document.getElementById("Debug1").innerText = DivID;
	TempVar = document.getElementById(DivID).innerHTML;
	//document.getElementById("Debug1").innerText = TempVar;

	Posn = TempVar.lastIndexOf("<TR id=TR_" + ZeroForm);	// innerHTML returns uppercase tags & strips " but keeps id case
	strHTML = TempVar.substr(0, Posn)
	//document.getElementById("Debug1").innerText = strHTML;	// display the text we grabbed

	// ------------------------------------------------------------------------
	// store everything after the end of the ZeroForm <tr></tr>
	// ------------------------------------------------------------------------
	Posn = TempVar.indexOf("</TR>", Posn) + 5;					// indexOf("</TR>", Posn) = position of first </tr> starting from Posn bytes in 
	DivFooter = TempVar.substr(Posn)
	//document.getElementById("Debug2").innerText = DivFooter;	// display the text we grabbed

	// ------------------------------------------------------------------------
	// assign new values to the ZeroForm
	// ------------------------------------------------------------------------

	if (typeof document.forms[FormString][PKName] != "undefined")
	{
		Form_PKField = PKName;
	}
	else if (typeof document.forms[FormString]['prm_' + PKName] != "undefined")
	{
		Form_PKField = 'prm_' + PKName;
	}
	else
	{
		Form_PKField = "prm_CurrentRec_PK_Val"	// for CMS
	}
	//alert(Form_PKField);

	document.forms[FormString][Form_PKField].value = RecordID;		// assign RecordID to the PK
	document.forms[FormString]["prm_Mode"].value = 1;				//assign prm_Mode = 1 (update)
	document.forms[FormString]["Del" + ZeroForm].value = RecordID;	//assign task id for delete

	// ------------------------------------------------------------------------
	// switch ZeroForm's action divs around so that del & select become visible
	// ------------------------------------------------------------------------
	var TempVar = document.getElementById("SaveDel_" + ZeroForm).innerHTML;		// save original Action button div so we can restore it later
	document.getElementById("SaveDel_" + ZeroForm).innerHTML = document.getElementById("DelSelect_" + ZeroForm).innerHTML;	// switch the divs
	document.getElementById("DelSelect_" + ZeroForm).innerHTML = "";			// clear the unnecessary hidden div
	
	RowToInsert = document.getElementById("TR_" + ZeroForm).outerHTML;		// grab the entire current contents of the ZeroForm
	//document.getElementById("Debug1").innerText = RowToInsert;			// show the new Zero

	RowToInsert = RowToInsert.replace(repStr1, FormRoot + "_" + Ajax_Array[AjaxRow][AJAX_GRIDROWS]);	// replace all instances of ZeroForm with the new rowcount
	//document.getElementById("Debug1").innerText = RowToInsert;			// show the inserted row

	strHTML += RowToInsert;		// append RowToInsert to strHTML

	// ------------------------------------------------------------------------
	// switch ZeroForm's action divs back so Save & Delete Multi become visible
	// ------------------------------------------------------------------------
	document.getElementById("DelSelect_" + ZeroForm).innerHTML = document.getElementById("SaveDel_" + ZeroForm).innerHTML;
	document.getElementById("SaveDel_" + ZeroForm).innerHTML = TempVar;
	document.forms[FormString].reset();									// set ZeroForm back to empty state

	// ------------------------------------------------------------------------
	// clear any image divs
	// ------------------------------------------------------------------------
	var AjaxIndex = Ajax_FindIndex_Simple(WhichTable)
	var NumSpecialFields = Ajax_Array[AjaxIndex][AJAX_SPECIALFIELDS].length;
	var FieldName;
	var FieldType;

	if (NumSpecialFields > 0)
	{
		for (var Loopy=0; Loopy < NumSpecialFields; Loopy++)
		{
			FieldName = Ajax_Array[AjaxIndex][AJAX_SPECIALFIELDS][Loopy][0];
			FieldType = Ajax_Array[AjaxIndex][AJAX_SPECIALFIELDS][Loopy][1];

			if (FieldType == 'Image' || FieldType == 'File')
			{
				var XDiv = document.getElementById(ZeroForm + '_' + FieldName)
				XDiv.innerHTML = '';
			}
		}
	}
	
	// ------------------------------------------------------------------------
	// new blank row
	// ------------------------------------------------------------------------
	strHTML += document.getElementById("TR_" + ZeroForm).outerHTML;		//add new blank row
	//alert(DivFooter);
	strHTML += DivFooter;
	//strHTML  = strHTML.replace(repStr2, '');
	//strHTML  = strHTML.replace(repStr3, '');
	document.getElementById(DivID).innerHTML = strHTML;

	//document.getElementById("Debug1").innerText = strHTML;			// show the inserted row
	//document.getElementById("Debug1").innerText = document.body.outerHTML;			// show the inserted row
}


/*---------------------------------------------------------------------------------------------------------------
函式名稱：	Ajax_RemoveRow(DivID, FormID, RedrawMode)
Called By:	Ajax_Delete, Ajax_Delete_Multi
撰寫日期：	2005-12-31
撰寫人員：	Sunil Narayan
函式功能：	remove or hide the row
參數：		- DivID, contains the table we're working on
			- FormID, identifies the row
			- RedrawMode, 'hide' or 'refresh'; always use 'hide' because it's faster, UNLESS we need to recalculate stuff

使用範例：	Ajax_RemoveRow('Goals_List', 'Goal3', 'hide')
---------------------------------------------------------------------------------------------------------------*/

function Ajax_RemoveRow(DivID, FormID, RedrawMode)
{
	var strHTML = '';
	var TempVar;
	var Posn;
	var DivFooter;
	var RowToInsert;

	//alert('DivID: ' + DivID + '\nFormID: ' + FormID + '\nRedrawMode: ' + RedrawMode)
	if (RedrawMode == 'hide')
	{
		document.getElementById("TR_" + FormID).style.display= 'none';
	}
	else if (RedrawMode == 'remove')
	{
		// ------------------------------------------------------------------------
		// save everything up to the row we want to delete into strHTML
		// ------------------------------------------------------------------------
		TempVar = document.getElementById(DivID).innerHTML;
		//document.getElementById("Debug1").innerText = TempVar;	// display the text we grabbed
		Posn = TempVar.indexOf("<TR id=TR_" + FormID + ">");	// innerHTML returns uppercase tags & strips quotes but keeps id case
		if (Posn == -1)
		{
			Posn = TempVar.indexOf("<TR id=TR_" + FormID + " ");	// formatting may add a space + style stuff
		}
		if (Posn != -1)
		{
			strHTML = TempVar.substr(0, Posn)
			//document.getElementById("Debug1").innerText = strHTML;	// display the text we grabbed

			// ------------------------------------------------------------------------
			// store everything AFTER the end of the row we want to delete
			// ------------------------------------------------------------------------
			Posn = TempVar.indexOf("</TR>", Posn) + 5;					// indexOf("</TR>", Posn) = position of first </tr> starting from Posn bytes in 
			strHTML += TempVar.substr(Posn)
			//document.getElementById("Debug2").innerText = TempVar.substr(Posn);		// display the text we grabbed

			document.getElementById(DivID).innerHTML = strHTML;
			//alert('Unable to find... DivID: ' + DivID + '\nFormID: ' + FormID + '\nPosn: ' + Posn);
		}
		else
		{
			alert('Unable to locate\nDivID: ' + DivID + '\nFormID: ' + FormID + '\nPosn: ' + Posn);
		}
	}
}



/*---------------------------------------------------------------------------------------------------------------
函式名稱：	Ajax_Delete(WhichTable, DivID, FormBase, FormID, RedrawMode)
Called By:	Front & Back end forms that want to delete a row
撰寫日期：	2005-12-31
撰寫人員：	Sunil Narayan
函式功能：	use Ajax to delete a record from the db, and hide/remove the table row without refreshing
參數：		- WhichTable, which table we're working on
			- DivID, contains the table we're working on
			- FormBase, identifies the Form
			- FormID, identifies the row
			- RedrawMode, 'hide' or 'refresh'; always use 'hide' because it's faster, UNLESS we need to recalculate stuff

使用範例：	Ajax_Delete('Goals_List', 'CMS_Form_', 'Goal3', 'hide')
---------------------------------------------------------------------------------------------------------------*/

function Ajax_Delete(WhichTable, FormBase, FormID, ParentKey, RedrawMode)	
{
	var AjaxRow = Ajax_FindIndex(WhichTable, ParentKey);
	var DivID = Ajax_Array[AjaxRow][AJAX_DIVID];

	var FormString = FormBase + FormID;
	var Del_Confirm;
	
	Del_Confirm = confirm(Msg_ConfirmDelete);
	if (Del_Confirm == true)
	{
		//alert('iCMS.js: Ajax_Delete\nWhichTable:' + WhichTable + '\nDivID: ' + DivID + '\nFormID:' + FormID + '\nFormString:' + FormString + '\nRedrawMode:' + RedrawMode);
		document.forms[FormString]["prm_Mode"].value = 2;
		var status = AjaxRequest.submit	(
											document.forms[FormString],
											{
												'onSuccess':function(req)
												{
													if (req.responseText != '' && req.responseText != 0)
													{
														document.getElementById("Debug1").innerText = req.responseText;
													}
												}
											}
										);
		Ajax_RemoveRow(DivID, FormID, RedrawMode);
		//Ajax_Array[AjaxRow][AJAX_GRIDROWS]--;		// we don't want to subtract...
		if (Ajax_Array[AjaxRow][AJAX_DELETEFN] != '')
		{
			Ajax_Array[AjaxRow][AJAX_DELETEFN](FormID, ParentKey);
		}
	}
}

/*---------------------------------------------------------------------------------------------------------------
函式名稱：	Ajax_Delete_Multi(DivID, FormBase, FormRoot, DelTable, RedrawMode)
Called By:	Front & Back end forms that want to delete a selected list of rows
撰寫日期：	2005-12-31
撰寫人員：	Sunil Narayan
函式功能：	use Ajax to delete multiple records from the db, and hide/remove the table rows without refreshing
參數：		- DivID, contains the table we're working on
			- FormBase, identifies the Form
			- FormRoot, identifies the root name of the form [eg 'Goal' or 'ToDo_3_']
			- DelTable, root name of table we're trying to delete from
			- RedrawMode, 'hide' or 'refresh'; always use 'hide' because it's faster, UNLESS we need to recalculate stuff

使用範例：	Ajax_Delete_Multi('Goals_List', 'CMS_Form_', 'Goal', 'Goal', 'hide')
			Ajax_Delete_Multi('TSD_List', 'CMS_Form_', 'TSD', 'TSD' ,'remove');
			Ajax_Delete_Multi('Assignment_List', 'CMS_Form_', 'Assignment5_', 'Assignment', 'hide')
			Ajax_Delete_Multi('ToDo_List', 'CMS_Form_', 'ToDo5_', 'ToDo', 'hide')
---------------------------------------------------------------------------------------------------------------*/
function Ajax_Delete_Multi(WhichTable, FormBase, ParentKey, RedrawMode)
{
	var AjaxRow = Ajax_FindIndex(WhichTable, ParentKey);
	var RowsToDelete = '';
	var Del_Confirm;
	var FormID;
	var FormRoot = WhichTable + '_' + ParentKey;
	var FormString;
	var DivID = Ajax_Array[AjaxRow][AJAX_DIVID];
	var CMSID;

	var NumRows_Orig = Ajax_Array[AjaxRow][AJAX_GRIDROWS];
	//alert('DivID: ' + DivID + '\nFormBase: ' + FormBase + '\nFormRoot: ' + FormRoot + '\nWhichTable: ' + WhichTable + '\nRedrawMode: ' + RedrawMode + '\nNumRows_Orig: ' + NumRows_Orig);
	
	Del_Confirm = confirm(Msg_ConfirmDelete);
	if (Del_Confirm == true)
	{
		//alert(Ajax_Array[AjaxRow][AJAX_GRIDROWS]);
		for(var loopy=1; loopy <= Ajax_Array[AjaxRow][AJAX_GRIDROWS]; loopy++)
		{
			FormID = FormRoot + '_' + loopy;	// eg Goal3
			FormString = FormBase + FormID;		// eg CMS_Form_Goal3
			if (typeof document.forms[FormString] != "undefined")
			{
				CMSID = document.forms[FormString]["prm_CMSID"].value;
				//alert('FormID: ' + FormID + ' \nFormString: ' + FormString + '\nchecked: ' + document.forms[FormString]["SelectForDelete"].checked);
				if (document.forms[FormString]["SelectForDelete"].checked)
				{
					RowsToDelete += document.forms[FormString]["SelectForDelete"].value + ','
					Ajax_RemoveRow(DivID, FormID, RedrawMode);
					//Ajax_Array[AjaxRow][AJAX_GRIDROWS]--;
				}
			}
		}
		RowsToDelete = RowsToDelete.substr(0, RowsToDelete.length -1)			// lose the trailing comma
		//alert(RowsToDelete);
		//Ajax_Array[AjaxRow][AJAX_GRIDROWS] = NumRows_Orig;
		document.forms["Delete_Multi"]["prm_WhichTable"].value = WhichTable;
		document.forms["Delete_Multi"]["prm_DeleteList"].value = RowsToDelete;	
		document.forms["Delete_Multi"]["prm_Mode"].value = 3;
		document.forms["Delete_Multi"]["prm_CMSID"].value = CMSID;

		var status = AjaxRequest.submit	(
											document.forms["Delete_Multi"], 
											{
												'onSuccess':function(req)
												{
													if (req.responseText != '' && req.responseText != 0)
													{
														alert(req.responseText);
													}
												}
											}
										);	
		if (Ajax_Array[AjaxRow][AJAX_DELETEFN] != '')
		{
			Ajax_Array[AjaxRow][AJAX_DELETEFN](FormID);
		}
		//document.forms["Delete_Multi"].submit();
	}
}


// ===================================================================
// Author: Matt Kruse <matt@ajaxtoolbox.com>
// WWW: http://www.AjaxToolbox.com/
//
// NOTICE: You may use this code for any purpose, commercial or
// private, without any further permission from the author. You may
// remove this notice from your final code if you wish, however it is
// appreciated by the author if at least my web site address is kept.
//
// You may *NOT* re-distribute this code in any way except through its
// use. That means, you can include it in your product, or your web
// site, or any other form where the code is actually being used. You
// may not put the plain javascript up on your site for download or
// include it in your javascript libraries for download. 
// If you wish to share this code with others, please just point them
// to the URL instead.
// Please DO NOT link directly to my .js files from your site. Copy
// the files to your server and use them there. Thank you.
// ===================================================================

/**
 * The AjaxRequest class is a wrapper for the XMLHttpRequest objects which 
 * are available in most modern browsers. It simplifies the interfaces for
 * making Ajax requests, adds commonly-used convenience methods, and makes 
 * the process of handling state changes more intuitive.
 * An object may be instantiated and used, or the Class methods may be used 
 * which internally create an AjaxRequest object.
 */
function AjaxRequest() {
	var req = new Object();
	
	// -------------------
	// Instance properties
	// -------------------

	/**
	 * Timeout period (in ms) until an async request will be aborted, and
	 * the onTimeout function will be called
	 */
	req.timeout = null;
	
	/**
	 *	Since some browsers cache GET requests via XMLHttpRequest, an
	 * additional parameter called AjaxRequestUniqueId will be added to
	 * the request URI with a unique numeric value appended so that the requested
	 * URL will not be cached.
	 */
	req.generateUniqueUrl = true;
	
	/**
	 * The url that the request will be made to, which defaults to the current 
	 * url of the window
	 */
	req.url = window.location.href;
	
	/**
	 * The method of the request, either GET (default), POST, or HEAD
	 */
	req.method = "GET";
	
	/**
	 * Whether or not the request will be asynchronous. In general, synchronous 
	 * requests should not be used so this should rarely be changed from true
	 */
	req.async = true;
	
	/**
	 * The username used to access the URL
	 */
	req.username = null;
	
	/**
	 * The password used to access the URL
	 */
	req.password = null;
	
	/**
	 * The parameters is an object holding name/value pairs which will be 
	 * added to the url for a GET request or the request content for a POST request
	 */
	req.parameters = new Object();
	
	/**
	 * The sequential index number of this request, updated internally
	 */
	req.requestIndex = AjaxRequest.numAjaxRequests++;
	
	/**
	 * Indicates whether a response has been received yet from the server
	 */
	req.responseReceived = false;
	
	/**
	 * The name of the group that this request belongs to, for activity 
	 * monitoring purposes
	 */
	req.groupName = null;
	
	/**
	 * The query string to be added to the end of a GET request, in proper 
	 * URIEncoded format
	 */
	req.queryString = "";
	
	/**
	 * After a response has been received, this will hold the text contents of 
	 * the response - even in case of error
	 */
	req.responseText = null;
	
	/**
	 * After a response has been received, this will hold the XML content
	 */
	req.responseXML = null;
	
	/**
	 * After a response has been received, this will hold the status code of 
	 * the response as returned by the server.
	 */
	req.status = null;
	
	/**
	 * After a response has been received, this will hold the text description 
	 * of the response code
	 */
	req.statusText = null;

	/**
	 * An internal flag to indicate whether the request has been aborted
	 */
	req.aborted = false;
	
	/**
	 * The XMLHttpRequest object used internally
	 */
	req.xmlHttpRequest = null;

	// --------------
	// Event handlers
	// --------------
	
	/**
	 * If a timeout period is set, and it is reached before a response is 
	 * received, a function reference assigned to onTimeout will be called
	 */
	req.onTimeout = null; 
	
	/**
	 * A function reference assigned will be called when readyState=1
	 */
	req.onLoading = null;

	/**
	 * A function reference assigned will be called when readyState=2
	 */
	req.onLoaded = null;

	/**
	 * A function reference assigned will be called when readyState=3
	 */
	req.onInteractive = null;

	/**
	 * A function reference assigned will be called when readyState=4
	 */
	req.onComplete = null;

	/**
	 * A function reference assigned will be called after onComplete, if 
	 * the statusCode=200
	 */
	req.onSuccess = null;

	/**
	 * A function reference assigned will be called after onComplete, if 
	 * the statusCode != 200
	 */
	req.onError = null;
	
	/**
	 * If this request has a group name, this function reference will be called 
	 * and passed the group name if this is the first request in the group to 
	 * become active
	 */
	req.onGroupBegin = null;

	/**
	 * If this request has a group name, and this request is the last request 
	 * in the group to complete, this function reference will be called
	 */
	req.onGroupEnd = null;

	// Get the XMLHttpRequest object itself
	req.xmlHttpRequest = AjaxRequest.getXmlHttpRequest();
	if (req.xmlHttpRequest==null) { return null; }
	
	// -------------------------------------------------------
	// Attach the event handlers for the XMLHttpRequest object
	// -------------------------------------------------------
	req.xmlHttpRequest.onreadystatechange = 
	function() {
		if (req==null || req.xmlHttpRequest==null) { return; }
		if (req.xmlHttpRequest.readyState==1) { req.onLoadingInternal(req); }
		if (req.xmlHttpRequest.readyState==2) { req.onLoadedInternal(req); }
		if (req.xmlHttpRequest.readyState==3) { req.onInteractiveInternal(req); }
		if (req.xmlHttpRequest.readyState==4) { req.onCompleteInternal(req); }
	};
	
	// ---------------------------------------------------------------------------
	// Internal event handlers that fire, and in turn fire the user event handlers
	// ---------------------------------------------------------------------------
	// Flags to keep track if each event has been handled, in case of 
	// multiple calls (some browsers may call the onreadystatechange 
	// multiple times for the same state)
	req.onLoadingInternalHandled = false;
	req.onLoadedInternalHandled = false;
	req.onInteractiveInternalHandled = false;
	req.onCompleteInternalHandled = false;
	req.onLoadingInternal = 
		function() {
			if (req.onLoadingInternalHandled) { return; }
			AjaxRequest.numActiveAjaxRequests++;
			if (AjaxRequest.numActiveAjaxRequests==1 && typeof(window['AjaxRequestBegin'])=="function") {
				AjaxRequestBegin();
			}
			if (req.groupName!=null) {
				if (typeof(AjaxRequest.numActiveAjaxGroupRequests[req.groupName])=="undefined") {
					AjaxRequest.numActiveAjaxGroupRequests[req.groupName] = 0;
				}
				AjaxRequest.numActiveAjaxGroupRequests[req.groupName]++;
				if (AjaxRequest.numActiveAjaxGroupRequests[req.groupName]==1 && typeof(req.onGroupBegin)=="function") {
					req.onGroupBegin(req.groupName);
				}
			}
			if (typeof(req.onLoading)=="function") {
				req.onLoading(req);
			}
			req.onLoadingInternalHandled = true;
		};
	req.onLoadedInternal = 
		function() {
			if (req.onLoadedInternalHandled) { return; }
			if (typeof(req.onLoaded)=="function") {
				req.onLoaded(req);
			}
			req.onLoadedInternalHandled = true;
		};
	req.onInteractiveInternal = 
		function() {
			if (req.onInteractiveInternalHandled) { return; }
			if (typeof(req.onInteractive)=="function") {
				req.onInteractive(req);
			}
			req.onInteractiveInternalHandled = true;
		};
	req.onCompleteInternal = 
		function() {
			if (req.onCompleteInternalHandled || req.aborted) { return; }
			req.onCompleteInternalHandled = true;
			AjaxRequest.numActiveAjaxRequests--;
			if (AjaxRequest.numActiveAjaxRequests==0 && typeof(window['AjaxRequestEnd'])=="function") {
				AjaxRequestEnd(req.groupName);
			}
			if (req.groupName!=null) {
				AjaxRequest.numActiveAjaxGroupRequests[req.groupName]--;
				if (AjaxRequest.numActiveAjaxGroupRequests[req.groupName]==0 && typeof(req.onGroupEnd)=="function") {
					req.onGroupEnd(req.groupName);
				}
			}
			req.responseReceived = true;
			req.status = req.xmlHttpRequest.status;
			req.statusText = req.xmlHttpRequest.statusText;
			req.responseText = req.xmlHttpRequest.responseText;
			req.responseXML = req.xmlHttpRequest.responseXML;
			if (typeof(req.onComplete)=="function") {
				req.onComplete(req);
			}
			if (req.xmlHttpRequest.status==200 && typeof(req.onSuccess)=="function") {
				req.onSuccess(req);
			}
			else if (typeof(req.onError)=="function") {
				req.onError(req);
			}

			// Clean up so IE doesn't leak memory
			delete req.xmlHttpRequest['onreadystatechange'];
			req.xmlHttpRequest = null;
		};
	req.onTimeoutInternal = 
		function() {
			if (req!=null && req.xmlHttpRequest!=null && !req.onCompleteInternalHandled) {
				req.aborted = true;
				req.xmlHttpRequest.abort();
				AjaxRequest.numActiveAjaxRequests--;
				if (AjaxRequest.numActiveAjaxRequests==0 && typeof(window['AjaxRequestEnd'])=="function") {
					AjaxRequestEnd(req.groupName);
				}
				if (req.groupName!=null) {
					AjaxRequest.numActiveAjaxGroupRequests[req.groupName]--;
					if (AjaxRequest.numActiveAjaxGroupRequests[req.groupName]==0 && typeof(req.onGroupEnd)=="function") {
						req.onGroupEnd(req.groupName);
					}
				}
				if (typeof(req.onTimeout)=="function") {
					req.onTimeout(req);
				}
			// Opera won't fire onreadystatechange after abort, but other browsers do. 
			// So we can't rely on the onreadystate function getting called. Clean up here!
			delete req.xmlHttpRequest['onreadystatechange'];
			req.xmlHttpRequest = null;
			}
		};

	// ----------------
	// Instance methods
	// ----------------
	/**
	 * The process method is called to actually make the request. It builds the
	 * querystring for GET requests (the content for POST requests), sets the
	 * appropriate headers if necessary, and calls the 
	 * XMLHttpRequest.send() method
	*/
	req.process = 
		function() {
			if (req.xmlHttpRequest!=null) {
				// Some logic to get the real request URL
				if (req.generateUniqueUrl && req.method=="GET") {
					req.parameters["AjaxRequestUniqueId"] = new Date().getTime() + "" + req.requestIndex;
				}
				var content = null; // For POST requests, to hold query string
				for (var i in req.parameters) {
					if (req.queryString.length>0) { req.queryString += "&"; }
					req.queryString += escape(i) + "=" + escape(req.parameters[i]);
				}
				if (req.method=="GET") {
					if (req.queryString.length>0) {
						req.url += ((req.url.indexOf("?")>-1)?"&":"?") + req.queryString;
					}
				}
				req.xmlHttpRequest.open(req.method,req.url,req.async,req.username,req.password);
				if (req.method=="POST") {
					if (typeof(req.xmlHttpRequest.setRequestHeader)!="undefined") {
						req.xmlHttpRequest.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
					}
					content = req.queryString;
				}
				if (req.timeout>0) {
					setTimeout(req.onTimeoutInternal,req.timeout);
				}
				req.xmlHttpRequest.send(content);
			}
		};

	/**
	 * An internal function to handle an Object argument, which may contain
	 * either AjaxRequest field values or parameter name/values
	 */
	req.handleArguments = 
		function(args) {
			for (var i in args) {
				// If the AjaxRequest object doesn't have a property which was passed, treat it as a url parameter
				if (typeof(req[i])=="undefined") {
					req.parameters[i] = args[i];
				}
				else {
					req[i] = args[i];
				}
			}
		};

	/**
	 * Returns the results of XMLHttpRequest.getAllResponseHeaders().
	 * Only available after a response has been returned
	 */
	req.getAllResponseHeaders =
		function() {
			if (req.xmlHttpRequest!=null) {
				if (req.responseReceived) {
					return req.xmlHttpRequest.getAllResponseHeaders();
				}
				alert("Cannot getAllResponseHeaders because a response has not yet been received");
			}
		};

	/**
	 * Returns the the value of a response header as returned by 
	 * XMLHttpRequest,getResponseHeader().
	 * Only available after a response has been returned
	 */
	req.getResponseHeader =
		function(headerName) {
			if (req.xmlHttpRequest!=null) {
				if (req.responseReceived) {
					return req.xmlHttpRequest.getResponseHeader(headerName);
				}
				alert("Cannot getResponseHeader because a response has not yet been received");
			}
		};

	return req;
}

// ---------------------------------------
// Static methods of the AjaxRequest class
// ---------------------------------------

/**
 * Returns an XMLHttpRequest object, either as a core object or an ActiveX 
 * implementation. If an object cannot be instantiated, it will return null;
 */
AjaxRequest.getXmlHttpRequest = function() {
	if (window.XMLHttpRequest) {
		return new XMLHttpRequest();
	}
	else if (window.ActiveXObject) {
		// Based on http://jibbering.com/2002/4/httprequest.html
		/*@cc_on @*/
		/*@if (@_jscript_version >= 5)
		try {
			return new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e) {
			try {
				return new ActiveXObject("Microsoft.XMLHTTP");
			} catch (E) {
				return null;
			}
		}
		@end @*/
	}
	else {
		return null;
	}
};

/**
 * See if any request is active in the background
 */
AjaxRequest.isActive = function() {
	return (AjaxRequest.numActiveAjaxRequests>0);
};

/**
 * Make a GET request. Pass an object containing parameters and arguments as 
 * the second argument.
 * These areguments may be either AjaxRequest properties to set on the request 
 * object or name/values to set in the request querystring.
 */
AjaxRequest.get = function(args) {
	AjaxRequest.doRequest("GET",args);
};

/**
 * Make a POST request. Pass an object containing parameters and arguments as 
 * the second argument.
 * These areguments may be either AjaxRequest properties to set on the request 
 * object or name/values to set in the request querystring.
 */
AjaxRequest.post = function(args) {
	AjaxRequest.doRequest("POST",args);
};

/**
 * The internal method used by the .get() and .post() methods
 */
AjaxRequest.doRequest = function(method,args) {
	if (typeof(args)!="undefined" && args!=null) {
		var myRequest = new AjaxRequest();
		myRequest.method = method;
		myRequest.handleArguments(args);
		myRequest.process();
	}
}	;

/**
 * Submit a form. The requested URL will be the form's ACTION, and the request 
 * method will be the form's METHOD.
 * Returns true if the submittal was handled successfully, else false so it 
 * can easily be used with an onSubmit event for a form, and fallback to 
 * submitting the form normally.
 */
AjaxRequest.submit = function(theform, args) {
	var myRequest = new AjaxRequest();
	if (myRequest==null) { return false; }
	var serializedForm = AjaxRequest.serializeForm(theform);
	myRequest.method = theform.method.toUpperCase();
	myRequest.url = theform.action;
	myRequest.handleArguments(args);
	myRequest.queryString = serializedForm;
	myRequest.process();
	return true;
};

/**
 * Serialize a form into a format which can be sent as a GET string or a POST 
 * content.It correctly ignores disabled fields, maintains order of the fields 
 * as in the elements[] array. The 'file' input type is not supported, as 
 * its content is not available to javascript. This method is used internally
 * by the submit class method.
 */
AjaxRequest.serializeForm = function(theform) {
	var els = theform.elements;
	var len = els.length;
	var queryString = "";
	this.addField = 
		function(name,value) { 
			if (queryString.length>0) { 
				queryString += "&";
			}
			queryString += escape(name) + "=" + escape(value);
		};
	for (var i=0; i<len; i++) {
		var el = els[i];
		if (!el.disabled) {
			switch(el.type) {
				case 'text': case 'password': case 'hidden': case 'textarea': 
					this.addField(el.name,el.value);
					break;
				case 'select-one':
					if (el.selectedIndex>=0) {
						this.addField(el.name,el.options[el.selectedIndex].value);
					}
					break;
				case 'select-multiple':
					for (var j=0; j<el.options.length; j++) {
						if (el.options[j].selected) {
							this.addField(el.name,el.options[j].value);
						}
					}
					break;
				case 'checkbox': case 'radio':
					if (el.checked) {
						this.addField(el.name,el.value);
					}
					break;
			}
		}
	}
	// sn: added 2007-04-14 to replace the plus signs
	if (queryString.indexOf("+"))
	{
		var repStr1 = new RegExp("\\+", "g");	// having submitting + signs, so replace with the decimal code
		queryString = queryString.replace(repStr1, escape("&#43;"));
		//alert(queryString);
	}

	//alert(queryString);
	return queryString;
};

// -----------------------
// Static Class variables
// -----------------------

/**
 * The number of total AjaxRequest objects currently active and running
 */
AjaxRequest.numActiveAjaxRequests = 0;

/**
 * An object holding the number of active requests for each group
 */
AjaxRequest.numActiveAjaxGroupRequests = new Object();

/**
 * The total number of AjaxRequest objects instantiated
 */
AjaxRequest.numAjaxRequests = 0;

