/* ------------------------------------------------------------------------------- +

	File:		forms.js
	Author:		Ben Nadel
	Date:		February 02, 2005
	Desc:		This has functions for form-related actions.

+ ------------------------------------------------------------------------------- */

// This adds the given option to the given select object and then selects
// the new option
function AddAndSelectNewOption(objSelect, strText, strValue){
	objSelect.options[objSelect.options.length] = new Option(strText, strValue);
	
	// Select the last option
	objSelect.selectedIndex = (objSelect.options.length - 1);
}


// Forwards browser window to the given location string. If the form
// object was passed as a second argument, then the form will be disabled
function Cancel(strUrl, objForm){
	// If no form was passed, param it to be the data form
	objForm = ParamArgument(objForm, document.forms["data_form"]);

	// Check to see if the form was passed
	if (objForm){
		DisableForm(objForm);
	}
	
	// Redirect browser
	window.location.href = strUrl;
}


// This checkes all the checkboxes with the given name in the given form
function CheckAllCheckBoxesWithName(objForm, strName){
	var objBoxes = objForm[strName];
	
	// Check to make sure we have a valid checkbox element(s)
	if (objBoxes){
		// We have a valid checkbox. The tricky thing here is that the 
		// checkbox may be single, or it may be acting as an array of
		// checkbox objects.
		
		// Check for length
		if (objBoxes.length){
			// We have an array of checkboxes
			
			// Loop over the checkboxes 
			for (var i = 0 ; i < objBoxes.length ; i++){
				objBoxes[i].checked = true;
			}
			
		} else {
			// We have a single checkbox, so check it
			objBoxes.checked = true;
		}	
	}
	
	return;
}


// This confirms that the user wants to navigate away from a form
// that may or may not have dirty information that needs to be saved
/*
function ConfirmDirtyFormSubmission(){
	try {
		event.returnValue = "You are about to leave a page that may have unsaved information.";
	} catch (error){
		// This browser cannot handle this
	}
}
*/

// Deletes the options with the given value 
function DeleteSelectOptionsByValue(objSelect, strValue){
	var arrOptions = objSelect.options;
	
	// Loop over options and convert selected to null
	for (var i = (arrOptions.length - 1) ; i >= 0 ; i--){
		// Check to see if the option has the deletable value
		if (arrOptions[i].value == strValue){
			// Make this option null 
			arrOptions[i] = null;
		}
	}
}


// Deletes the selected options from the select box
function DeleteSelectedOptions(objSelect){
	var arrOptions = objSelect.options;
	
	// First, move all the selected options to the bottom
	MoveSelectedOptionsToBottom(objSelect);
	
	// Now, loop over options and convert selected to null
	for (var i = (arrOptions.length - 1) ; i >= 0 ; i--){
		// Check to see if the option is selected
		if (arrOptions[i].selected){
			// Make this option null 
			arrOptions[i] = null;
		}
	}
}


// This is called when submitting a form. It will go through the 
// form elements and disable all the buttons, submits and otherwise.
function DisableForm(objForm){
	for (var i = 0 ; i < objForm.elements.length ; i++){
		if (objForm.elements[i].tagName.toLowerCase() == "input"){
			if ((objForm.elements[i].type.toLowerCase() == "button") ||
				(objForm.elements[i].type.toLowerCase() == "submit") ||
				(objForm.elements[i].type.toLowerCase() == "image")
				){
				// Disable the input
				objForm.elements[i].disabled = true;
				
				// Only change the class if it's not an image
				if (objForm.elements[i].type.toLowerCase() != "image"){
					//objForm.elements[i].className = "button-disabled";
				}
			}		
		}
		
		// Disable any events that might trigger a form-submit
		objForm.elements[i].onclick = null;
		objForm.elements[i].onchange = null;
		objForm.elements[i].onfocus = null;
		objForm.elements[i].onblur = null;
		objForm.elements[i].onkeydown = null;
		objForm.elements[i].onkeyup = null;
	}
	
	// Also, since the form has already been submitted, let's have it return false
	// if it tries to submit again. I am worried though that this might stop the
	//previous form submission.
	objForm.onsubmit = new function(){
		return(false);
	}
}


// This formats the phone number input
function FormatPhoneNumberInput(objInput){
	var strValue = objInput.value;
	var strPreValue = strValue;
	
	// Strip out the non-integer values
	strValue = StripNonInteger(strValue);
	
	// Strip out leading and training spaced
	strValue = strValue.replace(new RegExp("(^[ ]{1,})|([ ]{1,}$)", "gi"), "");
	
	// Check to see if the first digit is one. If so, then we have to delete it
	strValue = strValue.replace(new RegExp("(^[1]{1})", "gi"), "");
	
	// Check to see what length we have
	if (strValue.length <= 7){
		// Format the number to be 999-9999
		objInput.value = NumberMask(strValue, "999-9999");
	} else if (strValue.length <= 10){
		// Forma the number to be (999) 999-9999
		objInput.value = NumberMask(strValue, "(999) 999-9999");
	} else {
		// This is an invalid length, so just put old value back in
		objInput.value = strPreValue;
	}
}


// THis formats the Url input field. It makes user that the URL starts with
// "http://" if it doesn, then it is prepended to the url
function FormatUrlInput(objInput){
	var strValue = Trim(objInput.value);
	
	// Only check input IF we have a length
	if (strValue.trim().length > 0){	
		// Check to see if the http is found (will also pass if https)
		if (!strValue.match(new RegExp("(^https?://)"))){
			// The Url is not formatted properly. Set it.
			objInput.value = ("http://" + strValue);
		}
	}
	
	return;
}


// This creates a deliniated list of values of all the options
// in the given select box. It uses both the selected and the 
// non-selected options when building the list.
function GetSelectOptionsValueList(objSelect, strDelimiter){
	var arrOptions = objSelect.options;
	var strValueList = "";
	strDelimiter = ParamArgument(strDelimiter, ",");
	
	// Loop over the options and get the values
	for (var i = 0 ; i < arrOptions.length ; i++){
		// Check to see if we need to append the delimiter
		if (i > 0){
			strValueList += strDelimiter;
		}
		
		// Append the next value
		strValueList += arrOptions[i].value;
	}
	
	// Return the value list
	return(strValueList);
}


// This creates a deliniated list of values of only the options
// in the given select box that are currently selected.
function GetSelectedOptionsValueList(objSelect, strDelimiter){
	var arrOptions = objSelect.options;
	var strValueList = "";
	strDelimiter = ParamArgument(strDelimiter, ",");
	
	// Loop over the options and get the values
	for (var i = 0 ; i < arrOptions.length ; i++){
		// Check to see if the option is selected
		if (arrOptions[i].selected){
			// Check to see if we need to append the delimiter
			if (strValueList.length > 0){
				strValueList += strDelimiter;
			}
			
			// Append the next value
			strValueList += arrOptions[i].value;
		}
	}
	
	// Return the value list
	return(strValueList);
}


// This moves the selected options in the specified direction, and then
// updates the input that holds the value list of ALL the options.
function MoveSelectedOptionsAndUpdateValueList(objSelect, strDirection, objInput, strDelimiter){
	strDelimiter = ParamArgument(strDelimiter, ",");

	// Check to see which direction
	switch (strDirection){
		case "TOP":
			MoveSelectedOptionsToTop(objSelect);
			break;
		case "UP":
			MoveSelectedOptionsUp(objSelect);
			break;
		case "DOWN":
			MoveSelectedOptionsDown(objSelect);
			break;
		case "BOTTOM":
			MoveSelectedOptionsToBottom(objSelect);
			break;
	}
	
	// Now, update the value list
	objInput.value = GetSelectOptionsValueList(objSelect, strDelimiter);
}


// Moves the selected options in a select box down
function MoveSelectedOptionsDown(objSelect){
	var arrOptions = objSelect.options;
	
	// Check to make sure the select has more than one size
	if (objSelect.size > 1){
	
		// Loop over the options and swap out
		for (var i = (arrOptions.length - 2) ; i >= 0 ; i--){
			// Check to see that the current option is highlighted and
			// that the one above it is NOT highlighted
			if (arrOptions[i].selected && !arrOptions[i+1].selected){
				// Swap options
				SwapSelectOptions(arrOptions[i], arrOptions[i+1]);
			}
		}
		
	}
}


// Moves the selected options to the bottom of the select box
function MoveSelectedOptionsToBottom(objSelect){
	var arrOptions = objSelect.options;
	
	// Check to make sure the select has more than one size
	if (objSelect.size > 1){
	
		// Loop over the array and swap options
		for (var i = 0 ; i <= (arrOptions.length - 2) ; i++){
			// Do a double loop to make sure the selected one always moves as low
			// as it can possibly go
			for (var j = (arrOptions.length - 2) ; j >= i ; j--){
				// Check to see if the current option is selected and 
				// that the next option is NOT selected
				if (arrOptions[j].selected && !arrOptions[j+1].selected){
					// Swap these two options
					SwapSelectOptions(arrOptions[j], arrOptions[j+1]);
				}
			}
		}
		
	}
}


// Moves the selected options to the top of the select box
function MoveSelectedOptionsToTop(objSelect){
	var arrOptions = objSelect.options;
	
	// Check to make sure the select has more than one size
	if (objSelect.size > 1){
		
		// Loop over the array and swap options
		for (var i = arrOptions.length ; i >= 0 ; i--){
			// Do a double loop to make sure the selected one always moves as high
			// as it can possibly go
			for (var j = 1 ; j < i ; j++){
				// Check to see if the current option is selected and 
				// that the previous option is NOT selected
				if (arrOptions[j].selected && !arrOptions[j-1].selected){
					// Swap these two options
					SwapSelectOptions(arrOptions[j], arrOptions[j-1]);
				}
			}
		}
		
	}
}


// Moves the selected options in a select box up
function MoveSelectedOptionsUp(objSelect){
	var arrOptions = objSelect.options;
	
	// Check to make sure the select has more than one size
	if (objSelect.size > 1){
	
		// Loop over the options and swap out
		for (var i = 1 ; i < arrOptions.length ; i++){
			// Check to see that the current option is highlighted and
			// that the one above it is NOT highlighted
			if (arrOptions[i].selected && !arrOptions[i-1].selected){
				// Swap options
				SwapSelectOptions(arrOptions[i], arrOptions[i-1]);
			}
		}
		
	}
}


// This assumes that there is an attribute in an input box called "defaultvalue". 
// This removes the value of a text field if it is equal to the default value.
function RemoveInputDefaultValue(objInput){
	var strDefaultValue = ParamArgument(objInput.getAttribute("defaultvalue"), "");
	
	// Check to see if the current value is the default value
	if (objInput.value == strDefaultValue){
		// It is the default value, so remove it
		objInput.value = "";
	} 
}


// This sets the focus to the default element of the form, but only if the 
// form is not dirty, otherwise we may be interupting the user experience
function SetFormDefaultElementFocus(strElementName){
	var objForm = document.forms["data_form"];
	var objDefaultElement = objForm.elements[strElementName];
	var objDirtyBit = objForm.elements["form_dirty_bit"];
	var blnIsDirty = (objDirtyBit.value == "1");
	
	
	// Check to see if the default element exists and that the form is 
	// not dirty (ie. it has not been accessed by the user.
	if (objDefaultElement && !blnIsDirty){
		// The form should be good to throw focus
		objDefaultElement.focus();
	}
}


// This assumes that there is an attribute in an input box called "defaultvalue". 
// This puts the default value into the text field on blur if the text field is empty.
function SetInputDefaultValue(objInput){
	var strDefaultValue = ParamArgument(objInput.getAttribute("defaultvalue"), "");
	
	// Check to see if the current value is empty
	if (objInput.value == ""){
		// It is empty, so put the default value back in
		objInput.value = strDefaultValue;
	} 
}


// This sorts the options of the given select box in an Ascending 
// alphabetical manner based on the option text values.
function SortOptionsAlphabetically(objSelect){
	var arrOptions = objSelect.options;
	
	// Check to make sure the select has more than one size
	if (objSelect.size > 1){
	
		// When doing a bubble sort, we want to start out going to the
		// end of the options list. However, since the heaviest value
		// will always fall to the bottom on each iteration, we don't
		// need to keep going to the end of the list. Therefore, subtract
		// one from the end each time.
		for (var intEnd = (arrOptions.length - 1) ; intEnd > 0 ; intEnd--){
			// On the inner loop, we want to start at the top of the list
			// and keep going till be meet the end of where we need to be.
			// Since we don't want to do extra work, just go to intEnd 
			// and not to the physical end of the list.
			for (var i = 0 ; i < intEnd ; i++){
				// Check to see if the current option text is great than
				// the next one. 
				if (arrOptions[i].text > arrOptions[i+1].text){
					// The text is great and therefore we need to swap the
					// two options.
					SwapSelectOptions(arrOptions[i], arrOptions[i+1]);
				}			
			}		
		}
	
	}
}


// This sorts the given select box alphabetically based on the text
// and then updates the given input value list with the values of 
// the newly sorted select box.
function SortOptionsAlphabeticallyAndUpdateValueList(objSelect, objInput, strDelimiter){
	// Sort the options alphabetically 
	SortOptionsAlphabetically(objSelect);

	// Now, update the value list
	objInput.value = GetSelectOptionsValueList(objSelect, strDelimiter);
}


// This merely submits the data form and then disables it.
function SubmitForm(objForm){
	objForm = ParamArgument(objForm, document.forms["data_form"]);
	
	// Submit the form
	objForm.submit();
	
	// Disable the current form to remove duplicate submissions
	DisableForm(objForm);
}


// This submits the form directly to a new action page, no going back 
// to the same page to process form information first. This should be
// used when going from a list page to detail action page. Especially
// useful when you are passing around "wizzard" type data.
function SubmitFormWithAction(strAction, strActionID){
	var objForm = document.forms["data_form"];
	var objAction = objForm.elements["action"];
	var objUniqueID = objForm.elements["unique_id"];
	var objSubmitted = objForm.elements["submitted"];
	var objDataBaseID = null;
	strActionID = ParamArgument(strActionID, "0");
	
	// The value of the unique id field should hold the name of the 
	// unique id value that we are using from the database. 
	objDataBaseID = objForm.elements[objUniqueID.value];
	
	// Make sure that submitted is zero since we are going to a new page
	objSubmitted.value = "0";
	
	// Set the action for the new page
	objAction.value = strAction;
	
	// Set the unique id for the new page if we have a unique id
	if (objDataBaseID){
		objDataBaseID.value = strActionID;
	}
	
	// Submit the form 
	SubmitForm(objForm);
}


// This is used with the data_form form pages. It submits the form back 
// to the same page after setting the new_action input value. Of course, we
// don't want to submit back to the page if we have not made any changes. So, 
// we are attempting to find out if the form has been changed... if it is dirty.
// However, this is only true if we have a unique id value - if we don't there might
// be required info on this page.
function SubmitFormWithNewAction(strNewAction){
	var objForm = document.forms["data_form"];
	var objActionURL = objForm.elements["action_url"];
	var objNewAction = objForm.elements["new_action"];
	var objUniqueID = objForm.elements["unique_id"];
	var objDataBaseID = objForm.elements[objUniqueID.value];
	var blnDirty = (objForm.elements["form_dirty_bit"].value == "1") ? true : false ;
	
	// Set the new action
	objNewAction.value = strNewAction;
	
	// Submit the form
	SubmitForm(objForm);
	
	
	/*
	// Check to see if the form is dirty
	if (blnDirty || (parseInt(objDataBaseID.value) == 0)){
		// The form is dirty, so we DO want to submit the form back to itself
		
		// Set the new action
		objNewAction.value = strNewAction;
		
		// Submit the form
		SubmitForm(objForm);
		
	} else {
		// The form is NOT dirty, so don't waste time submitting it back to itself. Just
		// set the location based on the actions and ids 
		
		// Set the url in format:
		// URL...?action=NEW_ACTION&UNIQUE_ID=ID
		location.href = (
			objActionURL.value + "?action=" + 
			strNewAction + "&" + 
			objUniqueID.value + "=" + 
			objDataBaseID.value
			);
			
	}
	*/
}


// This is used with the data_form form pages. It submits the form back 
// to the same page after setting the new_action_gorup input value. Of course, 
// we don't want to submit back to the page if we have not made any changes. So, 
// we are attempting to find out if the form has been changed... if it is dirty.
// However, this is only true if we have a unique id value - if we don't there might
// be required info on this page.
function SubmitFormWithNewActionGroup(strNewActionGroup){
	var objForm = document.forms["data_form"];
	var objActionURL = objForm.elements["action_url"];
	var objNewActionGroup = objForm.elements["new_action_group"];
	var objUniqueID = objForm.elements["unique_id"];
	var objDataBaseID = objForm.elements[objUniqueID.value];
	var blnDirty = (objForm.elements["form_dirty_bit"].value == "1") ? true : false ;
	
	// Set the new action
	objNewActionGroup.value = strNewActionGroup;
	
	// Submit the form
	SubmitForm(objForm);
	
	/*
	// Check to see if the form is dirty
	if (blnDirty || (parseInt(objDataBaseID.value) == 0)){
		// The form is dirty, so we DO want to submit the form back to itself
		
		// Set the new action
		objNewActionGroup.value = strNewActionGroup;
		
		// Submit the form
		SubmitForm(objForm);
		
	} else {
		// The form is NOT dirty, so don't waste time submitting it back to itself. Just
		// set the location based on the actions and ids 
		
		// Set the url in format:
		// URL...?action=NEW_ACTION&UNIQUE_ID=ID
		location.href = (
			objActionURL.value + "?action_group=" + 
			strNewActionGroup + "&" + 
			objUniqueID.value + "=" + 
			objDataBaseID.value
			);
	}
	*/
}


// This is used to submit a form after changing the column you want to 
// sort on. If you change the current sort column to itself, it will 
// merely change the sort direction. Otherwise, it will change the 
// sort and the direction will default to ASC
function SubmitFormWithNewSort(strSortName){
	var objForm = document.forms["data_form"];
	var objSortBy = objForm.elements["search_sort_by"];
	var objSortByDirection = objForm.elements["search_sort_by_direction"];
	
	// Check to see if we have valid sort elements
	if (objSortBy && objSortByDirection){
		// The elements exist, so now check to see if we are picking a
		// new column, or just changing direction
		if (objSortBy.value == strSortName){
			// We are just changing direction on the same column
			
			// Change the current sort direction
			objSortByDirection.value = (objSortByDirection.value == "ASC") ? "DESC" : "ASC" ;
			
		} else {
			// We are sorting on a new column
			
			// Chance column and set direction to asc
			objSortBy.value = strSortName;
			objSortByDirection.value = "ASC";
		}		
	}	
	
	// Submit the form
	SubmitForm(objForm);
}


// This is used to submit a form after changing one value in the form. This
// is meant to stay in the same type of page, but change a property of it.
// For example, for paging through a list, this might change the offset value
// then resubmit the form. This method can take multiples of two arguments.
function SubmitFormWithNewValue(strElementName, strValue){
	var objForm = document.forms["data_form"];
	var objElement = objForm.elements[strElementName];
	
	// Loop over the arguments in two to set values
	for (var i = 0 ; i < arguments.length ; i+=2){
		// Get the element
		objElement = objForm.elements[arguments[i]];
		
		// Check to see if we have a valid argument 
		if (objElement){
			// The element exists, so set the value
			objElement.value = arguments[i + 1];
		}
	}
	
	/*
	// Check to see if we have a valid element
	if (objElement){
		// The element exists, so set the value
		objElement.value = strValue;
	}	
	*/
	
	// Submit the form
	SubmitForm(objForm);
}


// This is meant to submit the form, process the data, and then refresh
// the page with no values. This is used to add multiple items in a row
// without having to leave the page.
function SubmitFormWithPageRefresh(){
	var objForm = document.forms["data_form"];
	var objRefresh = objForm.elements["page_refresh"];
	
	// Set the page refresh
	objRefresh.value = "1";
	
	// Submit the form
	SubmitForm(objForm);
}


// This is used with the data_form form pages. It submits the form back
// to the same page after it sets up the sub action and the sub action
// id input values.
function SubmitFormWithSubAction(strSubAction, strSubActionID){
	var objForm = document.forms["data_form"];
	var objSubAction = objForm.elements["sub_action"];
	var objSubActionID = objForm.elements["sub_action_id"];
	
	// Set the sub action and action id
	objSubAction.value = strSubAction;
	objSubActionID.value = strSubActionID;
	
	// Submit the form
	SubmitForm(objForm);
}


// This basically submits the form with a sub action but no sub action ID.
// It is a bit of a hack, but it basically gets the form to submit back 
// to itself for "Update Data" type links.
function SubmitFormWithUpdate(){
	// Submit the form with sub action
	SubmitFormWithSubAction("update", "0");
}


// This swaps two options in a select box
function SwapSelectOptions(objOption1, objOption2){
	var objTempOption = new Option("", "");
	var arrProperties = new Array("text","value","className","selected");
	
	// Move all the properties of option 2 into the temp option
	for (var i = 0 ; i < arrProperties.length ; i++){
		objTempOption[ arrProperties[i] ] = objOption2[ arrProperties[i] ];
	}
	
	// Move all the properties of option 1 into option 2
	for (var i = 0 ; i < arrProperties.length ; i++){
		objOption2[ arrProperties[i] ] = objOption1[ arrProperties[i] ];
	}
	
	// Move all the properties of the temp option back to option 1
	for (var i = 0 ; i < arrProperties.length ; i++){
		objOption1[ arrProperties[i] ] = objTempOption[ arrProperties[i] ];
	}
}


// This transfers the selected options of the source select box to the
// options list of the destination select box.
function TransferSelectedOptions(objSourceSelect, objDestinationSelect){
	var arrSourceOptions = objSourceSelect.options;
	var arrDestinationOptions = objDestinationSelect.options;
	
	// Loop over the source options to find the selected ones
	for (var i = 0 ; i < arrSourceOptions.length ; i++){
		// Check to see if this one is selected
		if (arrSourceOptions[i].selected){
			// This option is selected, so transfer it
			
			// Add the option the destination list
			arrDestinationOptions[arrDestinationOptions.length] = new Option(
				arrSourceOptions[i].text,
				arrSourceOptions[i].value
				);
		
			// Select the newly transfered option
			// arrDestinationOptions[arrDestinationOptions.length - 1].selected = true;
		}
	}	
	
	// Loop over the source select backwards and remove the selected items
	// so that we don't keep duplicate records.
	for (var i = (arrSourceOptions.length - 1) ; i >= 0 ; i--){
		// Check to see if this one is selected
		if (arrSourceOptions[i].selected){
			// This option is selected, so nullify it
			arrSourceOptions[i] = null;
		}
	}
}


// This transfers options from one select to another and then updates
// the given value list with the options of the destination select box.
function TransferSelectedOptionsAndUpdateValueList(objSourceSelect, objDestinationSelect, objValueListSelect, objInput, strDelimiter){
	// Transfer the selected options
	TransferSelectedOptions(objSourceSelect, objDestinationSelect);
	
	// Now, update the value list
	objInput.value = GetSelectOptionsValueList(objValueListSelect, strDelimiter);
}


// This uncheckes all the checkboxes with the given name in the given form
function UncheckAllCheckBoxesWithName(objForm, strName){
	var objBoxes = objForm[strName];
	
	// Check to make sure we have a valid checkbox element(s)
	if (objBoxes){
		// We have a valid checkbox. The tricky thing here is that the 
		// checkbox may be single, or it may be acting as an array of
		// checkbox objects.
		
		// Check for length
		if (objBoxes.length){
			// We have an array of checkboxes
			
			// Loop over the checkboxes 
			for (var i = 0 ; i < objBoxes.length ; i++){
				objBoxes[i].checked = false;
			}
			
		} else {
			// We have a single checkbox, so check it
			objBoxes.checked = false;
		}	
	}
	
	return;
}