/*
	required.js
	
	For each form element that has been assigned the special required class (see below),
	this script will search out the label for the element and assign it the
	required class for styling purposes. It will also add a callback function to
	the form submission button(s) that will check to make sure that values are
	present for those fields that are required.
*/

addEvent(window, 'load', required_init);

var __aRequiredFields = new Object;
var __sRequiredClass = 'required';

function required_init() {
    if (!document.getElementsByTagName) return;
	
	var aFormTags = new Array('input', 'select', 'textarea');
	for (var i = 0; i < aFormTags.length; i++) {
		_assignRequired(document.getElementsByTagName(aFormTags[i]));
	}
}

/*
	Given a list of form elements, looks for ones that are required and
	modifies it appropriately.
*/
function _assignRequired(aFormElements) {
	for (var i = 0; i < aFormElements.length; i++) {
		var oElem = aFormElements[i];
		if ((' ' + oElem.className + ' ').indexOf(__sRequiredClass) != -1 && (oElem.id)) {
			requiredAdd(oElem.id);
		}
	}
}

/*
	Dynamically adds a single form element to the required list of elements. If
	no form processor handler has been set up for the given form, this will set
	it up.
*/
function requiredAdd(sElemId) {
	var oLabel = _requiredLabel(sElemId);
	if (oLabel != null) {
		addCSSClass(oLabel, __sRequiredClass);
	}
	
	// Get the form that contains this element
	var sFormId = getObject(sElemId).form.id;
	
	if (__aRequiredFields[sFormId] == null) {
		__aRequiredFields[sFormId] = new Array(sElemId);
		_requiredActions(sFormId);
	} else {
		__aRequiredFields[sFormId].push(sElemId);
	}
	
	return true;
}

/*
	Removes a single form element from the required list of elements for a
	given form.
*/
function requiredRemove(sElemId) {

	var oLabel = _requiredLabel(sElemId);
	if (oLabel != null) {
		removeCSSClass(oLabel, __sRequiredClass);
	}
	
	// Get the form that contains this element
	var sFormId = getObject(sElemId).form.id;
	
	// Remove form fields from list of fields to check. Of course, if the
	// list is not yet present, don't worry about removing anything.
	if (__aRequiredFields[sFormId]) {	
		for (var i = 0; i < __aRequiredFields[sFormId].length; i++) {
			var oElem = getObject(__aRequiredFields[sFormId][i]);
			if (sElemId == oElem.id) {
				__aRequiredFields[sFormId].splice(i, 1);
				break;
			}
		}	
	}
}

/*
	Callback function that gets run when a form is about to be submitted.
*/
function requiredCheck(e) {

	// Get the form that triggered this function.
	if (!e) var e = window.event;
	var oFormButton = getTarget(e);
	var sFormName = oFormButton.form.name;

	for (var i = 0; i < __aRequiredFields[sFormName].length; i++) {
		if (isEmpty(__aRequiredFields[sFormName][i])) {			
			alert('You must complete the highlighted fields before continuing.');
			getObject(__aRequiredFields[sFormName][i]).focus();
			return false;
		}
	}
	return true;
}

/*
	Retrieves the label for a given element.
*/
function _requiredLabel(sElemId) {
	var oElem = getObject(sElemId + '_label');
	if (oElem == null) {
		// Look for the item with the 'for' attribute set to the element's ID
		var aLabels = document.getElementsByTagName('label');
		for (var i = 0; i < aLabels.length; i++) {
			if (attribute(aLabels[i], 'for') == sElemId) {
				oElem = aLabels[i];
				break;
			}
		}
	}
	return oElem;
}

function _requiredActions(sForm) {
	var oForm = getObject(sForm);
	if (oForm != null) {
		// Add an 'onclick' event handler to any form submit buttons
		// that are not excluded.
		aInputElements = oForm.getElementsByTagName('input');
		for (var i = 0; i < aInputElements.length; i++) {
			if (attribute(aInputElements[i], 'type') == 'submit'  && 
				aInputElements[i].className.indexOf('excluded') == -1)
			{
				// Overrides any other 'onsubmit' event handler that may
				// be defined on the submit button. Use with caution.
				aInputElements[i].onclick = requiredCheck;
			}
		}
	}
	return true;
}
