/////////////////////////////////////////////////////////////////////////////////////////////////////
/////																							/////
/////			EARS form validation suite İRoy Ayres 2003. No part may be reused without		/////
/////			permission of the author - contact rgemini@rgemini.co.uk for permission.		/////
/////																							/////
/////////////////////////////////////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////////////////////////////////////////

//		Enough of that - here are the Validate and Reset routines

/////////////////////////////////////////////////////////////////////////////////////////////////////

function validateForm(F)							// Main routine, called whenever submit pressed
{	var f, izitok=true;								// f is field no, izitok keeps track if any errors
	for (f=0;f<F.length;f++)						// Check those fields with ids that begin with 'v'
	{	if( (F[f].id) && F[f].id.charAt(0)=='v')	// There will be a validation routine for this feld
		{	var p='val'+F[f].id.substring(1);		// Called val+name if the id is v+name
			if (!eval((p))) alert('Can\'t find validation routine "'+p+'"');
			var fldok = eval(p)(F[f]) ;		// Calls the validation routine for the field & displays any error
			izitok = fldok ? izitok : false;		// Keep track of whether the form as a whole is still ok
		}											
	}

	if (!izitok)
	{	// Errors found - so tell the user so
		switch (F.name)
		{	case "CWMorder" : var op = "        ---- " + F.ThisMessageAbout.value + " ----\n\nYour order" ;
							break;
			case "CWMmessage" : var op = "        ---- Casework Manager message form ----\n\nYour message"; 
							break;		
			default : var op = "        ---- " + F.ThisMessageAbout.value + " ----\n\nYour form" ; break;
		}	
		alert(op + " could not be sent because the form is not correctly filled in.\n\nPlease see the error message(s) displayed on the form.");
	}
	else
	{	// Extra logic to process pricing information into the hidden field Purchase
		pricing = '';
		pricetot = 0;
		for (f=0;f<F.length;f++)
		{	mytype = F[f].type;
			if (!(mytype == 'radio' || mytype == 'checkbox') || F[f].checked)
			{	att = F[f].attributes;
				for (a=0;a<att.length;a++)
				{	an = att[a].name;
					if (an == 'pricetext') pricing += att[a].value;
					if (an == 'price') 
					{	pricing += '=&pound;' + att[a].value + "; ";
						pricetot -= -att[a].value;	// ensure arithmetic add rather than concatenation
					}
				}
			}
		}
		if (pricetot > 0) pricing += 'Total &pound;' + pricetot +'.';
		F.Purchase.value = pricing;
	}
	
	return izitok;				// Will only be true if all the validations returned true - so
}								// the OnSubmit handler will send the form depending on this value

function resetForm(F)								// Routine called when the Reset button is pressed
{	for (var f=0;f<F.length;f++)					// Check those fields that have validation routines
	{	if( (F[f].id) && F[f].id.charAt(0)=='v')	// There will be an error message div called e+name
			itemOK(F[f]);							// Ensure the error status is cleared
		if (F[f].type=='textarea' || F[f].type=='text')
			F[f].value='' ;
		else
			if (F[f].type=='checkbox') F[f].checked=false ;			
	}	
	return false;
}


/////////////////////////////////////////////////////////////////////////////////////////////////////

//		General routines for handling error display on all form fields and getting radio  values

/////////////////////////////////////////////////////////////////////////////////////////////////////

function itemBad(w,pmsg)		// Sets the error message for form item w and displays the error div
													// - item has id v+name, the error div has id e+name
{	w.style.backgroundColor='#FFCC00';				// Change background colour to show error
	var e=document.getElementById('e'+w.id.substring(1));	// Locate the error div for this item
	if (e.childNodes.length==0)						// Originally empty - this routine puts the text in it if required
	{	var onewt=document.createTextNode(pmsg);	// W3 standard technique, rather than IE proprietry innerText
		e.appendChild(onewt);	
	}
		e.style.visibility='visible';				// Display the error message
	return false;									// So we can propagate the status through the calling stack
}

function itemOK(w)									// Hides any error indication for form item w
{	w.style.backgroundColor='#FFFFCC';				// Change background colour to show ok
	var e=document.getElementById('e'+w.id.substring(1));
	e.style.visibility='hidden';					// Hide the error message
	return true;									// So we can propagate the status through the calling stack
}


function radiovalve(w)								// Returns the value of the selected radio button
{	if (w.length)	var r= w ;						// Param is either the array of buttons,
	else var r=w.form[w.name];						// or one of the buttons. Ensure 'r' is the array.
	for (var v=0;v<r.length;v++)					// Only needs to be called once for the group
		if (r[v].checked ) return r[v].value ;		
	return false;
}


/////////////////////////////////////////////////////////////////////////////////////////////////////

//		Specific validation routines for individual fields. All follow the same format
//		and make use of regular expressions to perform the actual validation. The naming
//		standard is that field id v+name will have a validation routine called val+name
//		and an error display div, initially hidden, called e+name.
//		These routines take the field item object as parameter and return their results 
//		by calling itemBad and itemOK.

/////////////////////////////////////////////////////////////////////////////////////////////////////

function valName(w)						
{	w.onChange='valName(this)';
	w.onblur='valName(this)';
	if (w.value.search(/^[a-z]+[.,-]?\s[a-z]+/i)<0)
		return itemBad(w,"This does not appear to be a valid name");
	return itemOK(w);
}

function valSubmitter(w)
{	return valName(w);
}

function valEmail(w)
{	w.onChange='valEmail(this)';
	w.onblur='valEmail(this)';
	if (w.value.search(/^[a-z](\w|\-)*(.[a-z](\w|\-)*)*@([a-z](\w|\-)+.)*[a-z]{2,}.[a-z]{2,6}$/i) <0 )
		return itemBad(w,"This does not appear to be a valid email address");
	return itemOK(w);
}

function valMessage(w)
{	w.onChange='valMessage(this)';
	w.onblur='valMessage(this)';
	if (w.value.length==0)
		return itemBad(w,"There is no text in your message");
	return itemOK(w);
}

function valTemp(w)
{	return valEmail(w);
}

function valMemNo(w)
{	w.onChange='valMemNo(this)';
	w.onblur='valMemNo(this)';
	if (w.value.search(/(^[0-8]\d{5}(\d|x)$)/i)<0)
		return itemBad(w,"This does not appear to be a valid Lib Dem membership number");
	return itemOK(w);
}

function valCons(w)
{	w.onChange='valCons(this)';
	if (w.value.search(/^\w+/i)<0)
		return itemBad(w,"This does not appear to be a constituency name");
	return itemOK(w);
}

function valWard(w)
{	w.onChange='valWard(this)';
	if (w.value.search(/^\w+/i)<0)
		return itemBad(w,"This does not appear to be a valid Ward name");
	return itemOK(w);
}
	
function valAddr(w)
{	w.onChange='valAddr(this)';
	if (w.value.search(/^(\w+[.,-]?\s*)*.\n\w+[.,-]?./i)<0)
		return itemBad(w,"This does not appear to be a valid address");
	return itemOK(w);
}	

function valPCode(w)
{	w.onChange='valPCode(this)';
	if (w.value.search(/^[a-z]{1,3}[0-9]{1,3}\s*[0-9]{1,3}[a-z]{2,3}/i)<0)
		return itemBad(w,"This does not appear to be a valid postcode");
	return itemOK(w);
}

function valHomeNo(w){return valPhone(w)}
function valWorkNo(w){return valPhone(w)}
function valMobNo(w){return valPhone(w)}
function valFaxNo(w){return valPhone(w)}

function valPhone(w)
{	w.onChange='valPhone(this)';	
	if (w.value.length>0 && 
			w.value.search(/^(\+?[0-9]{2,3})?\s*([0-9]{2,7})?\s*[0-9]{3,4}\s*[0-9]{3,4}$/i)<0)
		return itemBad(w,"This does not appear to be a valid telephone number");
	return itemOK(w);
}

function valPrefCon(w)										// Slightly more complex - checks that the
{	w.onChange='valPrefCon(this)';							// chosen contact method actually exists.
	var pc=radiovalve(w), F=w.form;
	switch (pc)
	{	case 'Mobile' : f=F["Mobile"]; break;
		case 'HomePhone' : f=F["HomePhone"]; break;
		case 'WorkPhone' :f=F["WorkPhone"]; break;
		case 'FaxNo' : f=F["FaxNo"]; break;
		case 'Phone' : f=F["Phone"]; break;
		default : return itemOK(w);
	}
	if (f.value==null || f.value=='') 
		return itemBad (w,'You have not provided the phone number for your preferred means of contact');
	return itemOK(w);
}


