var Validator = {	Version: '1.0.0',	DateFormat: 'dd.mm.yyyy',	valid: true,	messages: {		"text": "",		"date": "",		"dateRequired": "",				"radio": "",		"checkbox": "",		"combobox": "",		"number": "",		"numberRequired": "",				"email": "",		"emailRequired": "",				"textarea": "",		"regex": "",		"none": "",				"undefined": ""	},	init: function(f, s){		this.form=document.forms[f];		this.messages["date"]+=" "+this.DateFormat;		this.insert_summary_here = $(s);	},	validate: function(){		this.valid= true;		this.fields.each(			function(fld){				var obj = Validator.form[fld.name];				var id = 'advice-' + fld.name;				var prop = '__advice'+fld.name;				if ( !Validator.test(fld) ){				if (!obj[prop]){						var advice = document.createElement('span');						if (fld.message) {							if (fld.message == 'none') {								var message = Validator.messages[fld.message];							} else {								var message = fld.message;							}						} else {							var message = Validator.messages[fld.type]						}											advice.appendChild(document.createTextNode(message));						advice.className = 'validation-advice';												advice.id = id;						advice.style.display = 'none';												if (fld.type=="radio"){							if (obj[0]){								if(navigator.userAgent.indexOf("MSIE") != -1){									obj[0].parentNode.insertBefore(advice, obj[1].previousSibling);								} else {									obj[0].parentNode.insertBefore(advice, obj.nextSibling);																																	}								} else {								obj.parentNode.insertBefore(advice, obj.previousSibling);							}						} else {							if (fld.type=="checkbox"){								if (obj[0]){									if(navigator.userAgent.indexOf("MSIE") != -1){										obj[0].parentNode.insertBefore(advice, obj[0].previousSibling);									} else {										obj[0].parentNode.insertBefore(advice, obj.nextSibling);																																				}																		} else {									if(navigator.userAgent.indexOf("Safari") != -1){										obj.parentNode.insertBefore(advice, obj.nextSibling);									} else {										obj.parentNode.insertBefore(advice, obj);																		}									}							} else {								obj.parentNode.insertBefore(advice, obj.nextSibling);							}							}												if(typeof Effect == 'undefined') {							advice.style.display = 'block';						} else {							new Effect.Appear(advice.id, {duration : 1 });						}						obj[prop]=true;					}					Validator.valid=false;								} else {					try {						$(id).remove();					} catch(e) {						//nothing					}						obj[prop] = '';				}			}//end .each() function		); //end .each()		var prop = '__advice' + this.form.name;		var id = "validation-summary";		if (!this.valid){			if (!this.form[prop]){				//add an error summary at the top of the form?				var summary = document.createElement('div');				var summaryText = "Please review any section marked with a cross ";				summary.appendChild(document.createTextNode(summaryText));				summary.className = 'validation-summary';				summary.id = id;				summary.style.display = 'none';				this.insert_summary_here.parentNode.insertBefore(summary, this.insert_summary_here.nextSibling);				var summaryIcon = document.createElement('span');				summaryIcon.id = 'validation-summary-icon';				summaryIcon.appendChild(document.createTextNode(' '));				summary.appendChild(summaryIcon);				if(typeof Effect == 'undefined') {					summary.style.display = 'block';				} else {					new Effect.Appear(summary.id, {duration : 1 });				}				this.form[prop]=true;			}		} else {			try {				$(id).remove();			} catch(e) {				//nothing			}			this.form[prop] = '';		}		return this.valid;	}, //end validate()	test: function(fld){		var f = Validator.form[ fld.name ];			//If it's an expression we can leap out now		if (fld.type=="custom") return eval(fld.expression);				//if validation is conditional see if it's required or not		if (fld.condition && !eval(fld.condition)) return true;				//if a test procedure is passed then simply perform that,		//passing the field object to the function		if (fld.test) return fld.test(f);				switch (f.type) {			case "text":				switch(fld.type){					case "undefined":						return f.value.trim() != "";						break											case "email":						var emailStr = f.value.trim();						if (!emailStr == "") {							var reg1 = /(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)/; // not valid							var reg2 = /^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}|[0-9]{1,3})(\]?)$/; // valid							if ( !reg1.test( emailStr ) && reg2.test( emailStr ) ) {								return true;							} else {							 	return false;							}						} else {							return true;						}							break;																	case "emailRequired":						var emailStr = f.value.trim();						var reg1 = /(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)/; // not valid						var reg2 = /^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}|[0-9]{1,3})(\]?)$/; // valid						if ( !reg1.test( emailStr ) && reg2.test( emailStr ) ) {							return true;						} else {						 	return false;						}						break;					case "date":											if(f.value.trim() != "") {													var results = new Array();							var datePat = /^(\d{1,2})(\/|-|\.)(\d{1,2})\2(\d{2}|\d{4})$/;							var matchArray = f.value.match(datePat);							if (matchArray == null) {								return false;							}							//check for two digit (20th century) years and prepend 19.							matchArray[4] = (matchArray[4].length == 2) ? '19' + matchArray[4] : matchArray[4];							// parse date into variables							if (Validator.DateFormat.charAt(0)=="d"){ //what format does the server use for dates?								results[0] = matchArray[1];								results[1] = matchArray[3];							} else {								results[1] = matchArray[1];								results[0] = matchArray[3];							}							results[2] = matchArray[4];							dateBits = results;							if (dateBits == null) return false;								//Check it is a valid date first							day = dateBits[0];							month = dateBits[1];							year = dateBits[2];							if ((month < 1 || month > 12) || (day < 1 || day > 31)) { // check month range								return false;							}							if ((month==4 || month==6 || month==9 || month==11) && day==31) {								return false;							}							if (month == 2) {								// check for february 29th								var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));								if (day>29 || (day==29 && !isleap)) {									return false;								}							}							//Now check whether a range is specified and if in bounds							var theDate = new Date(dateBits[2], parseInt(dateBits[1]) - 1, dateBits[0]);							if ( fld.min ) {								if ( fld.min.getTime() > theDate.getTime() ) return false;							}							if ( fld.max) {								if ( theDate.getTime() > fld.max.getTime() ) return false;							}							return true;													} else {													return true;													}						break;					case "dateRequired":																	var results = new Array();						var datePat = /^(\d{1,2})(\/|-|\.)(\d{1,2})\2(\d{2}|\d{4})$/;						var matchArray = f.value.match(datePat);						if (matchArray == null) {							return false;						}						//check for two digit (20th century) years and prepend 19.						matchArray[4] = (matchArray[4].length == 2) ? '19' + matchArray[4] : matchArray[4];						// parse date into variables						if (Validator.DateFormat.charAt(0)=="d"){ //what format does the server use for dates?							results[0] = matchArray[1];							results[1] = matchArray[3];						} else {							results[1] = matchArray[1];							results[0] = matchArray[3];						}						results[2] = matchArray[4];						dateBits = results;						if (dateBits == null) return false;							//Check it is a valid date first						day = dateBits[0];						month = dateBits[1];						year = dateBits[2];						if ((month < 1 || month > 12) || (day < 1 || day > 31)) { // check month range							return false;						}						if ((month==4 || month==6 || month==9 || month==11) && day==31) {							return false;						}						if (month == 2) {							// check for february 29th							var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));							if (day>29 || (day==29 && !isleap)) {								return false;							}						}						//Now check whether a range is specified and if in bounds						var theDate = new Date(dateBits[2], parseInt(dateBits[1]) - 1, dateBits[0]);						if ( fld.min ) {							if ( fld.min.getTime() > theDate.getTime() ) return false;						}						if ( fld.max) {							if ( theDate.getTime() > fld.max.getTime() ) return false;						}						return true;						break;					case "number":						if ( isNaN( f.value ) ) return false;						if ( fld.min && f.value < fld.min ) return false;						if ( fld.max && f.value > fld.max ) return false;						return true;						break;					case "numberRequired":						if ( isNaN( f.value ) ) return false;						if ( fld.min && f.value < fld.min ) return false;						if ( fld.max && f.value > fld.max ) return false;						return f.value.trim() != "";						break;					case "regex":						return fld.pattern.test(f.value);						break;											default:						return f.value.trim() != "";						break;				}				break; //end case:text			case "hidden":				return true;				break;			case "textarea":				return f.value.trim() != "";				break;			case "select-one":				return f.selectedIndex != 0				break;			case "select-multiple":				return f.selectedIndex != -1;				break;			case "file":				break;			default: //must be a checkbox or a radio group if none of above				if ( !f[0]) {//handle single item group first					switch (f.type) {						case "checkbox":							fld.type="checkbox";							return f.checked;						break						case "radio":							fld.type="radio";							return f.checked;						break						default:						break					}				} else { //handle multi-item groups					switch (f[0].type) {						case "checkbox":							fld.type="checkbox";							return Validator.hasSelection( f );						break						case "radio":							fld.type="radio";							return Validator.hasSelection( f );							return false;						break						default:						break					}				}			break		}	}, //end test()	hasSelection: function( obj ){		for (var r=0; r < obj.length; r++){			if ( obj[r].checked ) return true;		}				return false;	}} //end Validator//Extend String object and add a trim methodString.prototype.trim = function() {	a = this.replace(/^\s+/, '');	return a.replace(/\s+$/, '');};