function checkform(of)
{
// Test if DOM is available and there is an element called required
	if(!document.getElementById || !document.createTextNode){return;}
	if(!document.getElementById('required')){return;}

// Define error messages and split the required fields
	var errorID='errormsg';
	var errorClass='error'
/* changes for linked list */
	var errorMsg='Correct the marked fields before sending.';
/* end changes for linked list */
	var errorImg='/images/alert.gif';
	var errorAlt='Error';
	var errorTitle='This field has an error!';
	var reqfields=document.getElementById('required').value.split(',');

// Cleanup old mess
	// if there is an old errormessage field, delete it
	if(document.getElementById(errorID))
	{
		var em=document.getElementById(errorID);
		em.parentNode.removeChild(em);
	}
	// remove old images and classes from the required fields
	for(var i=0;i<reqfields.length;i++)
	{
		var f=document.getElementById(reqfields[i]);
		if(!f){continue;}
		if(f.previousSibling && /img/i.test(f.previousSibling.nodeName))
		{
			f.parentNode.removeChild(f.previousSibling);
		}
		f.className='';
	}
// loop over required fields
	for(var i=0;i<reqfields.length;i++)
	{
// check if required field is there
		var f=document.getElementById(reqfields[i]);
		if(!f){continue;}
// test if the required field has an error, 
// according to its type
		switch(f.type.toLowerCase())
		{
			case 'text':
				if(f.value=='Your name:' && f.id=='realname'){cf_adderr(f)}
// special filter to handle name data on Contact Us page
				if(f.value=='Company:' && f.id=='company'){cf_adderr(f)}
// special filter to handle company data on Contact Us page
				if(f.value=='' && f.id!='email' && f.id!='phone'){cf_adderr(f)}							
// email is a special field and needs checking
				if(f.id=='email' && !cf_isEmailAddr(f.value)){cf_adderr(f)}							
// phone number is a special field and needs checking
				if(f.id=='phone' && !cf_isPhoneNumber(f.value)){cf_adderr(f)}
				break;
			case 'textarea':
				if(f.value==''){cf_adderr(f)}							
			break;
			case 'checkbox':
				if(!f.checked){cf_adderr(f)}							
			break;
			case 'select-one':
				if(!f.selectedIndex && f.selectedIndex==0){cf_adderr(f)}							
			break;
			case 'radio':
				var radioObject = document.getElementsByName(f.name);
				var checkvalue = 0;
				for (j=0, n=radioObject.length; j<n; j++) {
				   if (radioObject[j].checked) {
				      checkvalue = 1;
					  break;
				   }
				}
				if (checkvalue==0){cf_adderr(f)}
			break;
		}
	}
	return !document.getElementById(errorID);


	/* Tool methods */
	function cf_adderr(o)
	{
		// create image, add to and colourise the error fields
		var errorIndicator=document.createElement('img');
		errorIndicator.alt=errorAlt;
		errorIndicator.src=errorImg;
		errorIndicator.title=errorTitle;
		o.className=errorClass;
		o.parentNode.insertBefore(errorIndicator,o);

	//	insertAfter(errorIndicator,o);

	// Check if there is no error message
		if(!document.getElementById(errorID))
		{
		// create errormessage and insert before submit button
			var em=document.createElement('div');
			em.id=errorID;
			var newp=document.createElement('p');
			newp.appendChild(document.createTextNode(errorMsg))
			em.appendChild(newp);
/* added for linked list */
			var newul=document.createElement('ul');		
			em.appendChild(newul);
/* end added for linked list */
			// find the submit button 
			for(var i=0;i<of.getElementsByTagName('input').length;i++)
			{
				if(/submit/i.test(of.getElementsByTagName('input')[i].type))
				{
					var sb=of.getElementsByTagName('input')[i];
					break;
				}
			}
			if(sb)
			{
				sb.parentNode.insertBefore(em,sb);
			//	insertAfter(em,sb);
			}	
		} 
		/* added for linked list */
		//		var em=document.getElementById(errorID).getElementsByTagName('ul')[0];
		//		var newli=document.createElement('li');
		//		var newa=document.createElement('a');
		//		for(var i=0;i<of.getElementsByTagName('label').length;i++)
		//		{
		//			if(of.getElementsByTagName('label')[i].htmlFor==o.id)
		//			{
		//				var txt=of.getElementsByTagName('label')[i].firstChild.nodeValue;
		//				break;
		//			}
		//		}
		//
		//		newa.appendChild(document.createTextNode(txt));
		//		newa.href='#'+f.id;
		//		newa.onclick=function()
		//		{
		//			var loc=this.href.match(/#(\w.+)/)[1];
		//			document.getElementById(loc).focus();
		//			return false;
		//		}
		//		newli.appendChild(newa);
		//		em.appendChild(newli);
		/* end added for linked list */
	}
	
	function cf_isEmailAddr(str) 
	{
		return str.match(/^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$/);
	}
	
	function cf_isPhoneNumber(str) {
	var valid = 1;
	var GoodChars = "0123456789()-+. ";
	var k = 0;
	if (str=="" || str=="123456") {
		// Return false if number is empty or is 123456
		valid = 0;
	}
	for (k=0; k<=str.length-1; k++) {
		if (GoodChars.indexOf(str.charAt(k)) == -1) {
			valid = 0;
		}
	}
	return valid;
	}
	
	function insertAfter(newElement,targetElement) {
	var parent = targetElement.parentNode;
	if(parent.lastchild == targetElement) {
		//add the newElement after the target element.
		parent.appendChild(newElement);
		} else {
		// else the target has siblings, insert the new element between the target and it's next sibling.
		parent.insertBefore(newElement, targetElement.nextSibling);
		}
	}

}