
/**
 * Author: Chris Wetherell
 * ExtendedForm (object)
 *
 * A form class for managing validation and access.
 *
 * Typical usage:
 * form = new ExtendedForm(document.forms[0]);
 * form.setCompareAndSubmitOnChange();
 */
function ExtendedForm(form) {
	this.form = form;
	this.getElementById = getElementById;
	this.getElementValueById = getElementValueById;
	this.setOriginalFormValues = setOriginalFormValues;
	this.setCompareAndSubmitOnChange = setCompareAndSubmitOnChange;
	this.getSelectElementTextById = getSelectElementTextById;
	this.setMaxlengthById = setMaxlengthById;
	this.setDisabledById = setDisabledById;
	this.setNumeralsOnlyById = setNumeralsOnlyById;
	this.setAllChars = setAllChars;
}

function setNumeralsOnlyById(sId) {
    var obj = this.getElementById(sId);
    obj.onblur = function() {
        var val = this.value;
        checkForAbsoluteNumerals(obj);
    }
}
function checkForAbsoluteNumerals(obj) {
    if (!isAbsoluteNumeral(obj.value)){
        alert("Numbers only, please.");
        obj.value = "";
        obj.focus();
    }
}

function setDisabledById(sId) {
    try {
        var obj = this.getElementById(sId);
        obj.disabled=true;
    } catch(e) {}
}

function isAbsoluteNumeral(n) {
    if (isNaN(n)) return false;
    if (n.indexOf("+")!=-1) return false;
    if (n.indexOf("-")!=-1) return false;
    if (n.indexOf(".")!=-1) return false;
    return true;
}

function setAllChars(sId) {
    try {
        var obj = this.getElementById(sId);
        obj.onblur = function() { }
    } catch(e) {}
}

function setMaxlengthById(sId,maxlength) {
    try {
        var obj = this.getElementById(sId);
        obj.maxLength = maxlength;
    } catch(e) {}
}

/**
 * For detecting if any non-hidden form element values have changed from their original values as sent to the browser...
 */
function setCompareAndSubmitOnChange() {
	this.setOriginalFormValues();
	this.form.onsubmit=new Function("e", "return CompareAndSubmitOnChange(this);");
}

function setOriginalFormValues() {
	var elements = this.form.elements;

	var copy_of_orig_form = document.createElement("FORM");
	copy_of_orig_form.setAttribute("id","original_form_values");
	document.getElementsByTagName("BODY")[0].appendChild(copy_of_orig_form);
	document.getElementById("original_form_values").style.display="none";

	for (var i=0; i<elements.length; i++) {
		var name = getFormElementName(elements[i]);
		var type = elements[i].type;
		if (type=="hidden") continue;
		if (name==null || name.length==0) continue;

		var val = getFormElementValue(this.form, elements[i]);

		var hiddenvalue = document.createElement("INPUT");
		hiddenvalue.setAttribute("type","hidden");
		hiddenvalue.setAttribute("value",val);
		hiddenvalue.setAttribute("id","original_value_"+name);
		document.forms["original_form_values"].appendChild(hiddenvalue);
	}
}

function CompareAndSubmitOnChange(form) {
	var HasFormChanged = FormComparisonCheck(form);
	if (!HasFormChanged) {
		alert("No changes were made.");
		return false;
	}
	/* erase this! - for testing only - let the form submit... */
	else { alert("Hmm...the form has changed."); return false; }
}

function FormComparisonCheck(form) {
	var elements = form.elements;
	var HasFormChanged = false;

	for (var i=0; i<elements.length; i++) {
		var name = getFormElementName(elements[i]);
		var type = elements[i].type;
		if (type=="hidden") continue;
		if (name==null || name.length==0) continue;

		var newValue = getFormElementValue(form, elements[i]);
		var origValue = getFormElementValue(form, document.getElementById("original_value_"+name));
		//alert(name+": "+newValue+"--"+origValue);
		if (newValue!=undefined && newValue!=origValue) {
			//alert(name+" changed.");
			HasFormChanged = true;
		}
	}
	return HasFormChanged;
}

function getFormElementName(el) {
		var name = el.name;
		if (name==null || name.length==0) {
			name=el.id;
		}
		return name;
}

function getFormElementValue(form, el) {
	var val;
	var type = el.type;

	if (type=="checkbox") val = getCheckboxValue(el);
	else if (el.length>0 && el.type==undefined) val = getRadioArrayValue(el);
	else if (type=="radio") val = getRadioElementValue(form, el);
	else val = el.value;

	return val;
}

function getCheckboxValue(el) {
	return el.checked.toString();
}

function getSelectElementTextById(name) {
	var select = this.getElementById(name);
	try {
	    val = select.options[select.selectedIndex].text;
	} catch(e) {}
	return val;
}

function getRadioElementValue(form, el) {
	var val;
	var radio = form.elements[el.name];
	for (var j=0; j<radio.length; j++) {
		if (radio[j].checked) val=radio[j].value;
	}
	return val;
}

function getRadioArrayValue(el) {
	var val;
	var radio = el;
	for (var j=0; j<radio.length; j++) {
		if (radio[j].checked) val=radio[j].value;
	}
	return val;
}

function getElementById(sId) {
    var el;
    el = this.form.elements[sId];

    var elHasLength = true;
    try {
	    if (el.length>0) return el;
    } catch(e) {
        elHasLength = false;
    }
    if (el==undefined || el.value==undefined) el = document.getElementById(sId);
    if (el==undefined && !elHasLength) {
        alert("No HTML form element with an ID or NAME of '"+sId+"' exists.");
    }
    return el;
}

function getElementValueById(sId) {
	var el = this.getElementById(sId);
	if (el==undefined) return null;
	var val = getFormElementValue(this.form, el);
	return val;
}
