/************************************************************************ * Domino JavaScript Form Validation v3.0 *   * This code is used to validate Domino forms. See the form "Contact" for * an example of how it works. *     * Borrows code from Really easy field validation with Prototype * by Andrew Tetlaw. See link below for more details. * http://tetlaw.id.au/view/blog/really-easy-field-validation-with-prototype *  * Author: Jake Howlett, Rockall Design ltd, http://www.rockalldesign.com * Date: May 2006 *************************************************************************/var Validator = {	Version: '1.0.0',	DateFormat: 'dd/mm/yyyy',	valid: true,	messages: {		"text": "This field is required. Please enter a value.",     	"date": "This field is required. Please enter a valid date in the format",		"radio": "This field is required. Please select a value.",		"checkbox": "This field is required. Please select at least one option.",		"number": "This field is required. Please enter a valid number",		"email": "This field is required. Please enter a valid email addresss",		"regex": "This field is required. Please enter a properly formatted entry",		"undefined": "This field is required."	},	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');						var message = ( fld.message ) ? fld.message : Validator.messages[fld.type];						advice.appendChild(document.createTextNode(message));						advice.appendChild(document.createElement('br'));						advice.className = 'validation-advice';						advice.id = id;						advice.style.display = 'none';									if (fld.type=="radio" || fld.type=="checkbox"){							if (obj[0]){								obj[0].parentNode.insertBefore(advice, obj[0].previousSibling);							} else {								obj.parentNode.insertBefore(advice, obj.previousSibling);							}						} 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');				summary.appendChild(document.createTextNode("There were problems with this form. Please correct and re-submit"));				summary.className = 'validation-summary';				summary.id = id;				summary.style.display = 'none';				this.insert_summary_here.parentNode.insertBefore(summary, this.insert_summary_here.nextSibling);				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();						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":						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 "regex":						return fld.pattern.test(f.value);					break;					default:						return f.value.trim() != "";					break;				}			break; //end case:text			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+$/, '');};
