/*
 * Name: form.js
 * Author: Andreas Gruenwald
 * Date: 2007-11-12
 * Description: Library for checking input of form fields dynamically (must-fields) and ajax.
 * 
 * Usage:
 * 	  - add class = "must":  	do all input fields that are must - fields
 * 	  - add class = "mustNum":  check numeric input (must be greater 0)
 	  - add js - script after tag: 
 	  		<script type="text/javascript">
				form_js_add_ajax('countryLong','phoneBookServlet');
			</script>
			cause an ajax request on url phoneBookServlet.
*			make shure, that this page returns xml content.
 * 			parameters "check_field" and "check_field_value" are required. you may check this in the form_ajax_page (e.g. jsp/php-page).
 * 			parameter "lang" contains language (de,en,..)
 * 			the server-page must return xml in the following structure:
 * 			<root>
 * 				<message messageType="error/warning/info">
 * 					<checkField>email</checkField>
 * 					<isError>true/false</isError>
 * 					<errorKey>EMAIL_INVALID</errorKey>
 * 					<errorText>Emailadresse falsch</errorText>
 * 					<newFieldValue>andi@falschparken.at</newFieldValue> (optional)
 *				</message>
 * 				<message>
 * 					...
 * 				</message>
 * 			</root> 
 *    and js automatically checks their content in forms.
 * 
 *   (- submit-form must have id="submitButton" !)
 *   - you MUST define a <input type="button" element with onclick="formSubmitted(document.testform,'/ajax.php')" !!!
 *   - the script is called with CONFIG_PATTERN_ALL as field name that means script has to check all fields.
 * 
 *   - if you create an element with id="form_general_errors" you may style it. general errors
 *     are displayed there, if no field name is found for it.
 *     if you create no own error box, one will be created with the same id.
 */

/*
Event.observe('first_name', 'onBlur', checkForm);
*/

var FORMS_CONFIG_CLASS_NAME_MUST  	  = 'must';
var FORMS_CONFIG_CLASS_NAME_MUST_NUM  = 'mustNum';

var FORMS_CONFIG_CLASS_NAME_AJAX  = "form_auto_ajax";
var FORMS_CONFIG_CLASS_NAME_ERROR = "error_input";
var FORMS_CONFIG_CLASS_NAME_ETEXT = "error_text";

var CONFIG_AJAX_PAGE_TAG 		= 'form_ajax_page';
var CONFIG_AJAX_REQUEST_PAGE 	= '/form_ajax.php';
//var CONFIG_AJAX_METHOD 			= 'post'; //must be post, otherwise problems in ie.
 
var CONFIG_MISSING_TEXT_DEFAULT	= 'Missing!';
var CONFIG_MISSING_TEXT_TAG 	= 'form_text_missing';

var CONFIG_MISSING_NUM_TEXT_DEFAULT	= 'No numeric value!';
var CONFIG_MISSING_NUM_TEXT_TAG 	= 'form_numeric_value_missing';

var CONFIG_CHECK_FIELD 			= "check_field";
var CONFIG_CHECK_VALUE 			= "check_value";

var CONFIG_PATTERN_ALL 			= 'form_js_all_fields';

var CONFIG_GENERAL_ERROR_BOX 	= "form_general_errors";
var CONFIG_NO_NEW_VALUE			= "undefined"; //no new value to new field after ajax request

var CONFIG_ERROR_MSG_OFFSET		= 7;
var CONFIG_DEFAULT_FORM_WIDTH   = "300px"; 
var CONFIG_REPLACE_HASH			= true;
var CONFIG_FORMS_IS_DEBUG		= false;


var formHasErrors = true;
var form_js_absolutizing = false;//true;
var form_js_allAjaxNodes;

var form_js_ajaxServlets = {};



Event.observe(window, 'load', function() {	

	//oberserve must fields
	var allNodes = getAllMustFields();
	if (allNodes != null && allNodes != '') {
		for(i = 0; i < allNodes.length; i++) {
			//alert ('now observing ' + allNodes[i].name);
			//Event.observe(allNodes[i], 'blur', must);
			Event.observe(allNodes[i], 'blur', must.generic.bindAsEventListener(must));
		}
	}
	
	var allNumNodes = getAllMustNumFields();
	if (allNumNodes != null && allNumNodes != '') {
		for(i = 0; i < allNumNodes.length; i++) {
			//alert ('now observing ' + allNodes[i].name);
			//Event.observe(allNodes[i], 'blur', must);
			Event.observe(allNumNodes[i], 'blur', mustNum.generic.bindAsEventListener(mustNum));
		}
	}
		
	var allAjaxNodes = getAutoAjaxFields();
	form_js_allAjaxNodes = allAjaxNodes;
	if (allAjaxNodes != null && allAjaxNodes != '') {
		for(i = 0; i < allAjaxNodes.length; i++) {
			//alert (allAjaxNodes[i].name);
			//Event.observe(allAjaxNodes[i], 'blur', formAjaxRequest);
			Event.observe(allAjaxNodes[i], 'blur', formAjaxRequestE.generic.bindAsEventListener(formAjaxRequestE));
		}
	}
	
	//var allAjaxQueryFields;
	//readAttribute(CONFIG_AJAX_PAGE_TAG);
	
	
	
	/*
	var submit = document.getElementById('submitButton');//$('submit');
	if(submit == null) {
		alert('Error: You must define submit form with id=submitButton')	
	}
	else {
		Event.observe(submit,'click', formSubmitted);
	}
	*/
	
	
	
	//FORMS_CONFIG_CLASS_NAME_AJAX
	//Event.observe(Element.getElementsByClassName(document.forms[0],'must'), 'blur', checkForm);		
    //Event.observe('testform', 'submitButton', checkForm);
});

function getAllMustFields() {
	//return document.getElementsByClassName(FORMS_CONFIG_CLASS_NAME_MUST);
	//$$('li.faux');
	return $$('.' + FORMS_CONFIG_CLASS_NAME_MUST); //new prototype method	should be prefered byClassName 
}

function getAllMustNumFields() {
	//return document.getElementsByClassName(FORMS_CONFIG_CLASS_NAME_MUST);
	//$$('li.faux');
	return $$('.' + FORMS_CONFIG_CLASS_NAME_MUST_NUM); //new prototype method should be prefered byClassName 
}

function getAutoAjaxFields() {
	/* 2008-02-27: take fields from js-array */
	//return $$('.' + FORMS_CONFIG_CLASS_NAME_AJAX); //new prototype method should be prefered byClassName
	var autoFields = [];
	for (var elem in form_js_ajaxServlets) {
		autoFields.push($(elem));
	}
	return autoFields;
	/*
	for (var i = 0; i < form_js_ajaxServlets.length; i++) {
		autoFields[i] = $(form_js_ajaxServlets[i]);
	}
	
	return autoFields;
	*/
}

//returns text for must-fields
function getMissingText() {
	var t = CONFIG_MISSING_TEXT_DEFAULT;
	var box = document.getElementById(CONFIG_MISSING_TEXT_TAG);
	//alert('box: ' + box + '-' + box.innerHTML);
	if (box!= null && box!= '') {
		t = box.innerHTML;
	}
	return t;
}

//returns text for must-fields (numeric)
function getMissingTextNum() {
	var t = CONFIG_MISSING_NUM_TEXT_DEFAULT;
	var box = document.getElementById(CONFIG_MISSING_NUM_TEXT_TAG);
	//alert('box: ' + box + '-' + box.innerHTML);
	if (box!= null && box!= '') {
		t = box.innerHTML;
	}
	return t;
}


var formAjaxRequestE = {    
// some stuff our 'generic' function needs  
  generic: function(event) {
    // Some generic, all-purpose checking (e.g. empty required fields)
    var field = event.target || event.srcElement;
    //alert('currentTarget: ' + text.name);
    formAjaxRequest(field);
  }  
};

/*
 * must - function 
 */
var must = {
  // some stuff our 'generic' function needs  
  generic: function(event) {
    // Some generic, all-purpose checking (e.g. empty required fields)
    var field = event.target || event.srcElement;
    //alert('form.js: currentTarget: ' + text.name);
    fMust(field);
  }  
};

/*
 * mustNum - function 
 */
var mustNum = {
  // some stuff our 'generic' function needs  
  generic: function(event) {
    // Some generic, all-purpose checking (e.g. empty required fields)
    var field = event.target || event.srcElement;
    //alert('form.js: currentTarget: ' + text.name);
    fMustNum(field);
  }  
};


function fMust(iField) {
	var field = iField;
	//alert('field:' + field);
	var eText = getMissingText();
	//alert('tempValue: ' + tempValue);
	var tempValue = field.value.replace(/(^\s+)([^\s]*)(\s+$)/, '$2');	
	if(tempValue == null || tempValue == '') {
		errorHandling(field,true,eText);
		return false;
	}
	else {
		errorHandling(field,false,eText);
		return true;
	}
}

/*
 * sames as must, but "too recursive error throwed"
 */
function mustExt(field) {
	var eText = getMissingText();
	var tempValue = field.value.replace(/(^\s+)([^\s]*)(\s+$)/, '$2');
	if(tempValue == '') {
		errorHandling(field,true,eText);
		return false;
	}
	else {
		errorHandling(field,false,eText);
		return true;
	}
}

function fMustNum(iField) {
	var field = iField;
	//alert('field:' + field);
	var eText = getMissingTextNum();
	//alert('tempValue: ' + tempValue);
	var tempValue = field.value.replace(/(^\s+)([^\s]*)(\s+$)/, '$2');	
	if(tempValue == null || tempValue == '') {
		errorHandling(field,true,eText);
		return false;
	}
	else if (isNaN(parseFloat(tempValue))) {
		errorHandling(field,true,eText);
		return false;		
	}
	else {
		errorHandling(field,false,eText);
		return true;
	}
}

/*
 * sames as mustNum, but "too recursive error throwed"
 */
function mustNumExt(field) {
	var eText = getMissingTextNum();
	var tempValue = field.value.replace(/(^\s+)([^\s]*)(\s+$)/, '$2');
	if(tempValue == '') {
		errorHandling(field,true,eText);
		return false;
	}
	else if (isNaN(parseFloat(tempValue))) {
		errorHandling(field,true,eText);
		return false;		
	}	
	else {
		errorHandling(field,false,eText);
		return true;
	}
}



/*
 * error-handling: set field to error.
 */
function errorHandling(field,isError,errorTag) {
	var ERROR_ID_TEXT = '_text_span';
	
	if(isError) {
		
		//field.focus(); disabled at the moment..
		
		field.addClassName(FORMS_CONFIG_CLASS_NAME_ERROR);	
		
		var eT = document.getElementById(field.id + ERROR_ID_TEXT);
		if(eT == null) {		
			//create tag for errortext
			var my_span = document.createElement('span');					
			my_span.innerHTML = errorTag;
			//set unique id for errortext
			var id = document.createAttribute('id');
			id.nodeValue = field.id + ERROR_ID_TEXT;	
			my_span.setAttributeNode(id);
			//set class
			var cl = document.createAttribute('class');
			cl.nodeValue = FORMS_CONFIG_CLASS_NAME_ETEXT;
			my_span.setAttributeNode(cl);



			field.parentNode.appendChild(my_span);
			/* 2008-04-18 problem on absolutizing: position is wrong, when a div-layer is 
						  shown after absolutizing
			*/
			if (form_js_absolutizing) {			
				/* added on 2008-02-27 - absolute positioning */
				//if (!Prototype.Browser.IE) { //added on 2008-04-02 but removed on 2008-06-26 again (for login-page)					
					Element.absolutize(my_span);
			  		if (my_span.style.width == 0 || my_span.style.width == "0px") {	  	
			  			my_span.style.width = CONFIG_DEFAULT_FORM_WIDTH;
			  			my_span.style.textAlign = "left";
			  		} 			
			  		var leftPos = Position.cumulativeOffset(field)[0];
			  		var fieldSize = parseInt((field.style.width.replace('px','')));			
			  		if (fieldSize == NaN) {
						fieldSize = 0;
					}	
					var newPos =  leftPos + fieldSize + CONFIG_ERROR_MSG_OFFSET + 'px';	  		  	
			  		my_span.style.left 	= newPos;
			  		/* end added on 2008-02-27 */
			  	//}			  	
			}
		}
		else {
			//update with new value
			eT.innerHTML = errorTag;
		}			
	}
	else {		
		field.removeClassName(FORMS_CONFIG_CLASS_NAME_ERROR);
		var eT = document.getElementById(field.id + ERROR_ID_TEXT);
		if(eT != null) {
			$(field.id + ERROR_ID_TEXT).remove();			
		}
	}
	return;
}

function isMustField(n) {
	if(n == FORMS_CONFIG_CLASS_NAME_MUST) {
		return true;
	}
}

function isMustNumField(n) {
	if (n == FORMS_CONFIG_CLASS_NAME_MUST_NUM) {
		return true;	
	}
}

/*
 * ajax-request for checking single-fields or alle fields (f = "***all***")
 * for those request you have to fill ajaxDest with the destination of request.
 * and form must contain the used form for the request.
 * 2008-03-20: new optional parameter params: contains params like 
 	{
		mobile_number: msisdn,
		email_address: email,
		...
	}
	if you use it, parameter "msisdn" will be renamed to "mobile_number" on submittion
 */
function formAjaxRequest(f,pSync,ajaxDest,form, params) {
	//alert("formAjaxRequest!!! field:" + f + "pSync: " + pSync);
	//debugger;
	
	var noError = true;	
	var async = true;
	if(pSync) {
		async = false;
	}
	
	var field = this;
	var ajaxDestination = null;	
	if(f == CONFIG_PATTERN_ALL) {
		field = f;
		ajaxDestination = ajaxDest;
		if(ajaxDestination == null) {
			ajaxDestination = CONFIG_AJAX_REQUEST_PAGE;
		}		
		ajaxDestination += '|?|' + CONFIG_PATTERN_ALL + "=true";
		
		var myArray = Form.getElements(form);
		//alert('amount: ' + myArray.length);
		/*
		for (var index = 0; index < myArray.length; ++index) {
  			var f = myArray[index];
  			if (!(f.name == null || f.name == "")) {  
  				ajaxDestination += "&" + f.name + "=" +
				Form.Element.getValue(f);
  			}
		}*/
		
		if (params == null) {
			//changed on 17th Feb 2007 in fact of errros on websms !!!
			for (var i = 0; i < form.length; i++) {
				if (!(form[i].name == null || f.name == "")) {
					if (params != null) {
						alert('Params is defined: ' + params);
					}
					ajaxDestination += "&" + form[i].name + "=" +
					Form.Element.getValue(form[i]);
				}
				 //Form.Element.getValue(form.elements[i]);  
				//getValueform.elements[i].value;
			}
		}
		else {
			for (var p in params) {
				ajaxDestination += "&" + p + "=" + params[p];
			}
		}
	
		 
							//+ CONFIG_CHECK_FIELD 
							//+ '=' + field + '&' + CONFIG_CHECK_VALUE + '=' + '***';		
	}
	else {	
		if(f.className != null) {
			field = f;
		}
		//var field = this;	
		//first check if form contains no errors
		var cl = field.classNames();
		if (cl.find(isMustField)) {
			//alert("must field checking...");
			if(!mustExt(field)) {
				//alert(" form contains errors!");
				return false;
			}
		}
		else if (cl.find(isMustNumField)) {
			//alert("must field checking...");
			if(!mustNumExt(field)) {
				//alert(" form contains errors!");
				return false;
			}
		}
		
		//reset errors
		errorHandling(field,false,'');  
		 
		
		//ajaxDestination = field.readAttribute(CONFIG_AJAX_PAGE_TAG);
		/*
		if(ajaxDestination == null) {
			ajaxDestination = CONFIG_AJAX_REQUEST_PAGE;
		}			
		*/
		ajaxDestination = getFormJsAjaxServlet(field.id);
		

		ajaxDestination += '|?|' + CONFIG_CHECK_FIELD 
					+ '=' + field.id + '&' + CONFIG_CHECK_VALUE + '=' + Form.Element.getValue(field); 
					//field.value; --> changed for checkboxes,...
	}	
	
    formJsAlert("Destination: " + ajaxDestination);
	if ($(CONFIG_GENERAL_ERROR_BOX) == null) {
		alert('You must define ' + CONFIG_GENERAL_ERROR_BOX + " - div for error handling!");
	}
	
	Element.hide(CONFIG_GENERAL_ERROR_BOX);
	$(CONFIG_GENERAL_ERROR_BOX).update("");
    
	var aParams = ajaxDestination.split('|?|');
	var params = 0;
	if(aParams.length >= 2) {
		ajaxDestination = aParams[0];
		params = aParams[1];
	}
	
	params = params.replace(/%/g,'%25'); //due to prototype decodeUrl
	if (CONFIG_REPLACE_HASH) {
		//replace hash, cause java interprets it as an anchor	
		params = params.replace(/#/g,'%23');		
	}
	
	formJsAlert('starting ajax request with ajaxDestination: ' + ajaxDestination 
	+ ' and asynch: ' + async + ' and params ' + params);
		
	new Ajax.Request(ajaxDestination,
	  {
	    method: 'post',
	    parameters: params, //encodeURIComponent(params), //due prototype.js 
	    asynchronous: async,  
	    onSuccess: function(transport){
	      formJsAlert('success' + transport.status);
	   	  formJsAlert('text: ' + transport.responseText);
	      var response = transport.responseXML || ("no response xml");
	      //alert ('reponse.documentElement: ' + response.documentElement);
	      var rXml = formJsTreeXML(response.documentElement);
	     
	     
	      //alert('success: ' + transport.responseXML);
	      //alert('errorText:' + rXml.errorText[0].data);
	      
	      if (rXml.self.tagName == 'parsererror') {
	      	eText = 'Responsed xml document caused parsererror(s)!!! ' + ajaxDestination;
	      	noError = false;
	      	$(CONFIG_GENERAL_ERROR_BOX).update(eText); 	      	
	    	//document.getElementById(CONFIG_GENERAL_ERROR_BOX).innerHTML = eText;
	    	Element.show(CONFIG_GENERAL_ERROR_BOX);	
	    	//alert(eText);      	
	      }
	      //alert('no parsererror found');
	      
	      if(noError) {
	      	for (var i = 0; i < rXml.message.length; i++) {	      		
		      var isError = rXml.message[i].isError[0].data;
		      var field	  = rXml.message[i].checkField[0].data;
		      var eText   = rXml.message[i].errorText[0].data;
		      
		      //alert(isError);
		      //alert(field);
		      //alert(eText);	
		      
		      //clear undefined text, e.g. birthday check: isError on fields day/month/year, but
		      //only the year is delivered with an errorText "Invalid birthday date."
		      if (eText == null || eText == 'undefined') {
		      	//alert('eText was undefined.');
		      	eText = '';	
		      }	      
		      //alert("is Error from ajax: " + isError);
		      
		      if(isError == "true") {
		      	//add to general error box
		      	if($(field) == null) {
		      		$(CONFIG_GENERAL_ERROR_BOX).update($(CONFIG_GENERAL_ERROR_BOX).innerHTML 
		      					+ eText + '<br />');
		      		Element.show($(CONFIG_GENERAL_ERROR_BOX));
		      	}		      	
		      	else {
		     		errorHandling(document.getElementById(field),isError,eText);
		      	}
		      	//alert("set noError to false..");
		      	noError = false;
		      }
		      //update field value
		      if(rXml.message[i].newFieldValue[0].data != null 
		      && rXml.message[i].newFieldValue[0].data != CONFIG_NO_NEW_VALUE) {
		      	$(field).value = rXml.message[i].newFieldValue[0].data;
		      }
	      	}
	      }
	      //alert('error: ' + isError);
	      //alert("Success! \n\n" + responseXML);	      	     
	    },
	    onFailure: function(){
	    	var eText = 'Ajax request for field ' + field.id + ' went wrong.';
			formJsAlert(eText);
	    	if(field.id == null || field.id == 'undefined') {
	    		eText = 'Axjax request returned error.'
	    	}
	    	document.getElementById(CONFIG_GENERAL_ERROR_BOX).innerHTML = eText;
	    			//'Ajax request for field ' + field.id + ' went wrong...';
	    	Element.show(CONFIG_GENERAL_ERROR_BOX);
	    	//alert('Ajax request for field ' + field.id + ' went wrong...')
	    	noError = false;
	    }
	  });	
	  formJsAlert("return with " + noError + ".");
	  return noError;
}

/*
 * is called when form is submitted.
 * if ajaxDestination is null or undefined, every field is checked for itself..
 * 
 * checkSingleFields: if true (default = true), every field is checked for itself.
 
  * 2008-03-20: new optional parameter params: contains params like 
 	{
		mobile_number: msisdn,
		email_address: email,
		...
	}
	if you use it, parameter "msisdn" will be renamed to "mobile_number" on submittion
 */
function formSubmitted(form,ajaxDestination,checkSingleFields,params,fakeSubmit) {
	formJsAlert('formSubmitted called! form: ' + form);
	
	//check must fields
	var isError = false;
	formHasErrors = false;
	var allMustNodes = getAllMustFields();	
	for(i = 0; i < allMustNodes.length; i++) {
		if(!mustExt(allMustNodes[i])) {
			//alert("is error set 1");
			isError = true;
		}
	}
	
	var allMustNumNodes = getAllMustNumFields();	
	for(i = 0; i < allMustNumNodes.length; i++) {
		if(!mustNumExt(allMustNumNodes[i])) {
			//alert("is error set 1");
			isError = true;
		}
	} 
	
	 
	//check ajax requests
	if (!isError && ajaxDestination != "") {
		if (checkSingleFields || checkSingleFields == null) {
			// disabled on 2008-02-27: use global allAjaxNodes var allAjaxNodes = getAutoAjaxFields();
			for(i = 0; i < form_js_allAjaxNodes.length; i++) {
				var ret = formAjaxRequest(form_js_allAjaxNodes[i],true);
				if (!ret) {
					isError = true;
				}
			}
		}
		else {
			//check all fields together
			formJsAlert('now checking formAjaxRequest');			
			var ret = formAjaxRequest(CONFIG_PATTERN_ALL,true,ajaxDestination,form,params);
			//alert('ret: ' + ret);
			if(!ret) {
				isError = true;
			}
		}
		

	}	
	if (fakeSubmit == null) {
		fakeSubmit = false;
	}

	if(!isError) {
		formHasErrors = false;
		
		if(form != null) {
			if (fakeSubmit == false) {
				form.submit();
			}
		}
			
	}
	else {
		formHasErrors = true;
	}
	return formHasErrors;
}

/*
	this may be called onKeyPress - event of a form. it calls FormSubmitted, if enter is pressed,
	otherwise it does nothing.
*/
function formSubmittedOnEnter(e, form,ajaxDestination,checkSingleFields,params) {
	var keycode;
	if (window.event) {
		keycode = window.event.keyCode;
	}
	else if (e) {
		keycode = e.which;
	}
	else {
		return true;
	}
	
	if (keycode == 13) {
	   return formSubmitted(form,ajaxDestination,checkSingleFields,params);
	}
	else {
	   return true;
	}
}

function formJsTreeXML(node, parent)
    {
        if (!node) {
            return false;
        }

        if (node.nodeType != 1) {
            return false;
        }

        var nodes = node.childNodes;
        var len = nodes.length;
        var tag, tmp, tree;
        var passed = false;

        parent = parent? parent : {'self': node};

        for (var i = 0; i < len; i++) {
            if (nodes[i].nodeType != 1) {
                continue;
            }

            tag = nodes[i].tagName; // .toLowerCase()
            element = nodes[i];

            if (!parent[tag]) {
                parent[tag] = {'length': 0, 'tag': tag};
            }

            index = parent[tag].length++;

            if (element.hasChildNodes()) {
              if (element.childNodes.length == 1 && element.firstChild.nodeType != 1) {
                parent[tag][index] = {'length': 0, 'tag': tag, 'data': element.firstChild.data};
              } else {
                parent[tag][index] = formJsTreeXML(element, parent[tag][index]);
              }
            } else {
                parent[tag][index] = {'length': 0, 'tag': tag, 'data': element.data};
            }
        }

        return parent;
  }
  
  /*
  	use this function to add ajax-Servlet's to the xhtml/html-page
  */
  function form_js_add_ajax(fieldName,servletName) {
  	form_js_ajaxServlets[fieldName] = servletName;
  }
  
  function getFormJsAjaxServlet(key) {
  	if (form_js_ajaxServlets[key] == null) {
  		return CONFIG_AJAX_REQUEST_PAGE;
  	}
  	else {
  		return form_js_ajaxServlets[key];
  	}
  }
  
  function formJsAlert(msg) {
  	if (CONFIG_FORMS_IS_DEBUG) {
		alert(msg) ;
	}
  }
  
  function formsJS_updateErrorBox(msg) {
  	$(CONFIG_GENERAL_ERROR_BOX).update(msg);
  	Element.show(CONFIG_GENERAL_ERROR_BOX);
  }
  
  function getRadioValue(name) {
    for (var i = 0; i < name.length; i++) {
      if (name[i].checked) {
         return name[i].value;
      }
    }
    return '';
  }
  
  function setRadioValue(name,value) {
    for (var i = 0; i < name.length; i++) {
      if (name[i].value == value) {
         name[i].checked = true;
      }
      else {
      	name[i].checked = false;
      }
    }
    return '';
  }


/*
Event.observe(element, eventName, handler[, useCapture = false])

Event.findElement(event, tagName) -> Element
*/
