/* Automated form validation using a set of basic validation checks.              */
/* Copyright © 2008 Frontmedia Studio Ltd.                                        */
/*                                                                                */
/* Version 2.5 (12/02/09)                                                         */
/*                                                                                */
/*    Bug fixes for 'checked' validation type.                                    */
/*                                                                                */
/* Version 2.4 (26/06/08)                                                         */
/*                                                                                */
/*    Changed 'select' validation type.                                           */
/*    Added 'notselect' validation type.                                          */
/*    Added 'selectvalue' validation type.                                        */
/*    Added 'notselectvalue' validation type.                                     */
/*                                                                                */
/* Version 2.3 (11/06/08)                                                         */
/*                                                                                */
/*    Added 'checkbox' validation type.                                           */
/*                                                                                */
/* Version 2.2 (14/05/08)                                                         */
/*                                                                                */
/*    Added validatePermissionCheckbox().                                         */
/*                                                                                */
/* Version 2.1 (08/05/08)                                                         */
/*                                                                                */
/*    Added 'maxmoney' validation type.                                           */
/*    Added 'minmoney' validation type.                                           */
/*                                                                                */
/* Version 2.0 (01/05/08)                                                         */
/*                                                                                */
/*    Added validateMinSelectRequired().                                          */
/*                                                                                */
/* Version 1.9 (14/03/08)                                                         */
/*                                                                                */
/*    Added fix to trim() function to remove linebreaks in Safari.                */
/*                                                                                */
/* Version 1.8 (06/03/08)                                                         */
/*                                                                                */
/*    Updated compareFields() to bypass checks when both fields are empty.        */
/*                                                                                */
/* Version 1.7 (28/02/08)                                                         */
/*                                                                                */
/*    Added fix for attempting to focus a hidden or disabled field.               */
/*                                                                                */
/* Version 1.6 (19/02/08)                                                         */
/*                                                                                */
/*    Added validateAddNew().                                                     */
/*                                                                                */
/*    Added validateUnitSelect().                                                 */
/*                                                                                */
/*    Added 'numcomma' validation type.                                           */
/*                                                                                */
/* Version 1.5 (30/08/07)                                                         */
/*                                                                                */
/*    Pre-validation functions are now global, rather than being tied to the      */
/*    form itself. This means that a pre-validation function can now perform      */
/*    ANY task, regardless of whether it relates specifically to the form.        */
/*    This is useful for things like hidden updates or calculations.              */
/*                                                                                */
/*    Added 'neq' validation type.                                                */
/*                                                                                */
/*    Added 'neq' comparison to compareFields().                                  */
/*                                                                                */
/*    Added 'neq' comparison to compareDateSelect().                              */
/*                                                                                */
/*    Added validateMinRequired().                                                */
/*                                                                                */
/*    Updated the CSS class changing to maintain existing classes on elements.    */
/*                                                                                */
/* Version 1.4 (29/08/07)                                                         */
/*                                                                                */
/*    Modified the behaviour of the Javascript alert box error messages to        */
/*    compile and display a list of errors, rather than showing a single error    */
/*    and terminating.                                                            */
/*                                                                                */
/*    Allowed CSS class changing on the field 'row', even if the associated       */
/*    'error' row doesn't exist. Useful for highlighting when using only a        */
/*    Javascript alert box for error reports.                                     */
/*                                                                                */
/*    Added CSS class changing for <label> tag with relevant 'for' value, along   */
/*    with class changing for the form element itself.                            */
/*                                                                                */
/* Version 1.3 (28/02/07)                                                         */
/*                                                                                */
/*    Added jump-to-top when an error is detected.                                */
/*                                                                                */
/* Version 1.2 (23/02/07)                                                         */
/*                                                                                */
/*    Added Pre-validation Components.                                            */
/*                                                                                */
/* Version 1.1 (04/01/07)                                                         */
/*                                                                                */
/*    Added validateFileExtensions().                                             */
/*                                                                                */
/* Version 1.0 (25/12/06)                                                         */
/*                                                                                */
/*    Initial version.                                                            */
/*                                                                                */
/* The following code must appear in <script> tags after your form:               */
/*                                                                                */
/* <script language="javascript" type="text/javascript">                          */          
/* <!--                                                                           */
/* var formValidator = new FormValidator("customerForm");                         */
/* formValidator.addValidation("fieldName","validation type","An error message"); */
/* formValidator.addValidation("fieldName","validation type","An error message"); */
/* ...                                                                            */
/* ...                                                                            */
/* -->                                                                            */
/* </script>                                                                      */
/*                                                                                */
/* You can also add an additional more complicated validation function adding the */
/* following:                                                                     */
/*                                                                                */
/* ...                                                                            */
/* formValidator.addExtraValidation("functionName('fieldName', argument1, ...)"); */
/* ...                                                                            */
/*                                                                                */
/* In a similar way, you can also add a pre-validation function which will run    */
/* before any validation takes place. This is useful for calculating form values  */
/* or making sure that external javascripts (eg. tinyMCE) do their cleanup:       */
/*                                                                                */
/* ...                                                                            */
/* formValidator.addPreValidation("functionName()");                              */
/* ...                                                                            */
/*                                                                                */
/* You should format the rows of your form layout in the following way:           */
/*                                                                                */
/* <tr id="fieldNameError" class="error" style="display: none;">                  */
/*   <td class="label">&nbsp;</td>                                                */
/*   <td><span id="fieldNameMessage"> </span></td>   */
/* </tr>                                                                          */
/* <tr id="fieldNameRow">                                                         */
/*   <td class="label">Field Label</td>                                           */
/*   <td><input name="fieldName" id="fieldName" type="text" maxlength="50" /></td>*/
/* </tr>                                                                          */
/*                                                                                */
/* If you choose not to use this layout method, the validation will still work,   */
/* but will default to individual Javascript alert boxes for each error.          */
/*                                                                                */
/* You may also optionally present a global error message, alerting the user to   */
/* the fact that there were errors somewhere in the form, by including this row   */
/* at the top of your form table:                                                 */
/*                                                                                */
/* <tr id="globalError" class="error" style="display: none;">                     */
/*   <td class="label"><img src="error.gif" /> Error</td>                         */
/*   <td>There was a problem.</td>                                                */
/* </tr>                                                                          */
/*                                                                                */
/*                                                                                */
/* Current validation types:                                                      */
/*                                                                                */
/* required: Use for required text, textarea and password fields                  */
/* maxlength=n: Limit the length of input in a field to n characters              */
/* minlength=n: Ensure that the length of input in a field is at least n chars    */
/* maxvalue=n: Limit the value entered into a field to n                          */
/* minvalue=n: Ensure that a value entered into a field is at least n             */
/* maxmoney=n: Limit the money value entered into a field to n                    */
/* minmoney=n: Ensure that a money value entered into a field is at least n       */
/* alpha: Value must be alphabetic only (A-Z,a-z)                                 */
/* alphauc: Value must be upper-case alphabetic only (A-Z)                        */
/* alphalc: Value must be lower-case alphabetic only (a-z)                        */
/* alphanumeric: Value must be alpha-numeric only (A-Z,a-z,0-9)                   */
/* alnumspace: Value must be alpha-numeric, but may contain spaces                */
/* alnumhyphen: Value must be alpha-numeric, but may contain hyphens              */
/* alnumhyphenspace: As alnumhyphen, but may also contain spaces                  */
/* alnumdash: Value must be alpha-numeric, but may contain dashes (-_/)           */
/* alnumdashspace: As alnumdash, but may also contain spaces                      */
/* numeric: Value must be numeric only (0-9)                                      */
/* decimal: Value must be numeric, with optional decimal part (eg. 10, 10.1, -10) */
/* positivedecimal: Value must be a positive decimal                              */
/* numcomma: Value must be numeric (0-9). Can contain commas.                     */
/* money: Value must be in money format. Can contain commas and 2 decimal places. */
/* username: Value must be alpha-numeric, but may also contain: .-_               */
/* email: Value must be a valid e-mail address                                    */
/* telephone: Value must be numeric, but may also contain spaces and: +-()        */
/* uktelephone: Value must be a valid UK telephone number                         */
/* postcode: Value must be a valid UK postcode                                    */
/* datetime: Value must be a valid date/time in UK format                         */
/* usdatetime: Value must be a valid date/time in US format                       */
/* eq=n: Value must be equal to n                                                 */
/* neq=n: Value must not be equal to n                                            */
/* lt=n: Value must be less than n (same as maxvalue)                             */
/* gt=n: Value must be greater than n (same as minvalue)                          */
/* regexp: Validates value against a valid regular expression                     */
/* select=n: Select input must have option with index n selected                  */
/* notselect=n: Select input must not have option with index n selected           */
/* selectvalue=n: Select input must have option with value n selected             */
/* notselectvalue=n: Select input must not have option with value n selected      */
/* checkbox=n: Used for single-named checkbox(es) to force n items to be checked  */
/*                                                                                */
/* Current extra validation functions:                                            */
/*                                                                                */
/* validateMultiSelect(inputItem, errorString, minS, maxS)                        */
/* Checks a multi-select input to make sure that a minimum of minS and optionally */
/* a maximum of maxS selections have been made.                                   */
/*                                                                                */
/* validateCheckboxes(inputList, errorString, minC, maxC)                         */
/* Examines a list of checkbox inputs to make sure that a minimum of minC and     */
/* optionally a maximum of maxC boxes have been checked.                          */
/*                                                                                */
/* validateRadios(inputItem, errorString, itemIndex)                              */
/* Checks a named radio button group to see if a selection has been made.         */
/* You may also optionally specify an index number of a specific radio button     */
/* that must be selected.                                                         */
/*                                                                                */
/* compareFields(inputItem, inputCompare, comparison, errorString)                */
/* Compares the values of two input fields based on the specified comparison      */
/* (eg. eq, neq, lt, gt, lte, gte)                                                */
/*                                                                                */
/* validateMinRequired(inputList, errorString, minR)                              */
/* Examines a list of field inputs to make sure that a minimum of minR fields     */
/* have been filled.                                                              */
/*                                                                                */
/* validateMinSelectRequired(selectList, errorString, minR)                       */
/* Examines a list of selects to make sure that a minimum of minR selects have    */
/* been chosen.                                                                   */
/*                                                                                */
/* validateDateSelect(daySelectItem, monthSelectItem, yearSelectItem,             */
/*                    errorString)                                                */
/* Checks the contents of a set of date select fields (eg. Day Month Year) for a  */
/* valid date. If the date is optional (ie. if there are more than 12 options for */
/* month), and no values have been selected, the check is bypassed.               */
/*                                                                                */
/* compareDateSelect(daySelectItem, monthSelectItem, yearSelectItem,              */
/*                   comparison, errorString,                                     */
/*                   daySelectCompare, monthSelectCompare, yearSelectCompare)     */
/* Compares the contents of two sets of date select fields (eg. Day Month Year)   */
/* based on the specified comparison (eg. lt, gt, eq). If the second set of date  */
/* select fields is not specified, the date is compared to the current date       */
/* instead.                                                                       */
/*                                                                                */
/* validateFileExtensions(inputItem, extList, errorString)                        */
/* Checks a file upload input to make sure that only those file extensions in the */
/* comma-delimited list (extList) are allowed eg. 'jpg,jpeg,gif'.                 */
/*                                                                                */
/* validateAddNew(selectItem, inputItem, addNewValue, errorString)                */
/* Checks an 'add new' select and text input combination to make sure that a      */
/* value has been entered if the user has chosen to add a new item.               */
/*                                                                                */
/* validateUnitSelect(inputItem, selectItem, promptIndex, errorString)            */
/* Checks to see if a specified field has been filled, and if so makes sure that  */
/* a specified select option has not been selected. Useful for adding a 'units'   */
/* selection for a numeric field.                                                 */
/*                                                                                */
/* validatePermissionCheckbox(inputItemList, checkboxItem, errorString)           */
/* Checks a comma-delimited list of text input fields to see if any have a value. */
/* If one or more values are found, a checkbox is examined to make sure it is     */
/* checked. This is useful for a form where certain terms and conditions apply to */
/* a group of optional fields.                                                    */

var alertMessage = '';

function trim(str) {
  return str.replace(/^(\s|\xA0)+|(\s|\xA0)+$/g, '');
}

function findYPos(obj) {
	var curtop = 0;
	if (obj.offsetParent) {
		curtop = obj.offsetTop
		while (obj = obj.offsetParent) {
			curtop += obj.offsetTop
		}
	}
	return curtop;
}

function getLabelFor(formElement) {
	if(document.getElementById(formElement)) {
		var formLabels = document.getElementsByTagName('label');
		for(var i = 0; i < formLabels.length; i++) {
			if(checkAttribute(formLabels[i],'for',formElement)) {
				return formLabels[i];
			}
		}
	}
	return false;
}

function checkAttribute(testElement,targetAttribute,targetValue) {
	if(testElement.getAttribute(targetAttribute)) {
		if(testElement.getAttribute(targetAttribute) == targetValue) {
			return true;
		}
	}
	if(testElement.attributes.length) {
		for(var i = 0; i < testElement.attributes.length; i++) {
			if(testElement.attributes[i].nodeName.toLowerCase() == targetAttribute.toLowerCase()) {
				if(testElement.attributes[i].value == targetValue) {
					return true;
				}
			}
		}
	}
	return false;
}
	
function FormValidator(formName) {
	/* Form validator object */
  this.formObject=document.forms[formName];
	this.formObject.preValidationSet = new Array();
	this.formObject.extraValidationSet = new Array();
	this.formObject.oldSubmit = this.formObject.onsubmit;
	this.formObject.onsubmit = onSubmitHandler;
	this.addValidation = addValidation;
	this.addPreValidation = addPreValidation;
	this.addExtraValidation = addExtraValidation;
	this.clearAllValidations = clearAllValidations;
	this.formObject.initGlobalError = initGlobalError;
	this.formObject.showGlobalError = showGlobalError;
	this.formObject.initError = initError;
	this.formObject.showError = showError;
	this.formObject.showErrorRow = showErrorRow;
	this.formObject.addError = addError;
}

function addPreValidation(functionString) {
	/* Add an extra global function to the validator         */
	/* Useful for preparing form content prior to validation */
  this.formObject.preValidationSet[this.formObject.preValidationSet.length] = functionString;
}

function addExtraValidation(functionString) {
	/* Add an extra validation function to the form */
  this.formObject.extraValidationSet[this.formObject.extraValidationSet.length] = functionString;
	var functionName = functionString.substring(0,functionString.indexOf('('));
	this.formObject[functionName] = eval(functionName);
}

function clearAllValidations() {
	/* Removes all validation checks */
	for(var i=0; i < this.formObject.elements.length; i++) {
		this.formObject.elements[i].validationSet = null;
	}
}

function onSubmitHandler() {
	var validated = true;
	var focusField = '';
	alertMessage = '';
	initGlobalError();
	/* Run any pre-validation functions */
	if(this.preValidationSet.length > 0) {
	  for(var i=0; i < this.preValidationSet.length; i++) {
      returnValue = eval(this.preValidationSet[i]);
			if(typeof returnValue != 'undefined' && !returnValue) {
				validated = false;
			}
		}
	}
	/* Run the validation set for each form element */
	for(var i=0; i < this.elements.length; i++) {
		initError(this.elements[i]);
	}
	for(var i=0; i < this.elements.length; i++) {
		if(this.elements[i].validationSet && !this.elements[i].validationSet.validateSet()) {
			if(focusField == '') {
				focusField = this.elements[i].name;
			}
			validated = false;
		}
	}
	/* Run any additional validation functions for this form */
	if(this.extraValidationSet.length > 0) {
	  for(var i=0; i < this.extraValidationSet.length; i++) {
      if(!eval('this.' + this.extraValidationSet[i])) {
		   validated = false;
		  }
		}
	}
	if(!validated) {
		showGlobalError();
		window.scrollTo(0,findYPos(this));
		if(focusField != '') {
			if (typeof this[focusField].name != "undefined") {
				if(this[focusField].disabled != true && this[focusField].style.display != "none") {
					this[focusField].focus();
				}
			} else if (typeof this[focusField].length != "undefined" && this[focusField].length > 0) {
				if(this[focusField][1].disabled != true && this[focusField][1].style.display != "none") {
					this[focusField][1].focus();
				}
			}
		}
		if(alertMessage != '') {
			alert(alertMessage);
		}
		return false;
	}
	/* If onsubmit already set for the form, run that function now */
	if(typeof this.oldSubmit == 'function'){
		return this.oldSubmit();
	}
	return true;
}

function addValidation(itemName,descriptor,errorString) {
  /* Adds a validation check to a form field */
	var itemObject = this.formObject[itemName];
	if(!itemObject.validationSet) {
	  itemObject.validationSet = new ValidationSet(itemObject);
	}
  itemObject.validationSet.addValidationCheck(descriptor,errorString);
}

function ValidationCheck(inputItem,descriptor,errorString) {
	/* Validation check object */
  this.descriptor = descriptor;
	this.errorString = errorString;
	this.itemObject = inputItem;
	this.validate = validate;
}

function validate() {
	/* Run an individual validation check */
	if(!validateData(this.descriptor,this.itemObject)) {
		addError(this.itemObject, this.errorString);
		return false;
	}
	return true;
}

function ValidationSet(inputItem) {
	/* Validation object set object */
  this.validationSet = new Array();
	this.addValidationCheck = addValidationCheck;
	this.validateSet = validateSet;
	this.itemObject = inputItem;
}

function addValidationCheck(descriptor,errorString) {
	/* Add a validation check to the set */
  this.validationSet[this.validationSet.length] = new ValidationCheck(this.itemObject,descriptor,errorString);
}

function validateSet() {
	/* Run all validation checks in the set */
	var fieldValidated = true;
	for(var i=0; i < this.validationSet.length; i++) {
	  if(!this.validationSet[i].validate()) {
		  fieldValidated = false;
			break;
	  }
	}
	if(!fieldValidated) {
		showError(this.itemObject);
		return false;
	}
	return true;
}

function initGlobalError() {
	if(document.getElementById('globalError')) {
		document.getElementById('globalError').style.display = 'none';
	}
}

function showGlobalError() {
	if(document.getElementById('globalError')) {
		document.getElementById('globalError').style.display = '';
	}
}

function initError(inputItem) {
	if(inputItem.name != "") {
		var fieldError = inputItem.name + 'Error';
		var fieldMessage = inputItem.name + 'Message';
		var fieldRow = inputItem.name + 'Row';
		var fieldLabel = getLabelFor(inputItem.name);
		var field = inputItem.name;
		if(document.getElementById(fieldError)) {
			document.getElementById(fieldError).style.display = 'none';
		}
		if(document.getElementById(fieldMessage)) {
			document.getElementById(fieldMessage).innerHTML = ' ';
		}
		if(document.getElementById(fieldRow)) {
			if(document.getElementById(fieldRow).className) {
				document.getElementById(fieldRow).className = document.getElementById(fieldRow).className.replace(/error/gi, '');
			} else {
				document.getElementById(fieldRow).className = '';
			}
		}
		if(document.getElementById(field)) {
			if(document.getElementById(field).className) {
				document.getElementById(field).className = document.getElementById(field).className.replace(/error/gi, '');
			} else {
				document.getElementById(field).className = '';
			}
		}
		if(fieldLabel) {
			if(fieldLabel.className) {
				fieldLabel.className = fieldLabel.className.replace(/error/gi, '');
			} else {
				fieldLabel.className = '';
			}
		}
	}
}

function showError(inputItem) {
	var fieldError = inputItem.name + 'Error';
	if(document.getElementById(fieldError)) {
		document.getElementById(fieldError).style.display = '';
	}
	showErrorRow(inputItem);
}

function showErrorRow(inputItem) {
	var fieldRow = inputItem.name + 'Row';
	var fieldLabel = getLabelFor(inputItem.name);
	var field = inputItem.name;
	if(document.getElementById(fieldRow)) {
		if(document.getElementById(fieldRow).className) {
			document.getElementById(fieldRow).className = document.getElementById(fieldRow).className + ' error';
		} else {
			document.getElementById(fieldRow).className = 'error';
		}
	}
	if(document.getElementById(field)) {
		if(document.getElementById(field).className) {
			document.getElementById(field).className = document.getElementById(field).className + ' error';
		} else {
			document.getElementById(field).className = 'error';
		}
	}
	if(fieldLabel) {
		if(fieldLabel.className) {
			fieldLabel.className = fieldLabel.className + ' error';
		} else {
			fieldLabel.className = 'error';
		}
	}
}

function addError(inputItem, errorString) {
	var fieldMessage = inputItem.name + "Message";
	if(document.getElementById(fieldMessage)) {
		if(trim(document.getElementById(fieldMessage).innerHTML) == ' ' || trim(document.getElementById(fieldMessage).innerHTML) == ''){
	    document.getElementById(fieldMessage).innerHTML = errorString;
			return true;
		} else {
			document.getElementById(fieldMessage).innerHTML = trim(document.getElementById(fieldMessage).innerHTML) + '<br />' + errorString;
			return true;
		}
	} else {
		alertMessage = alertMessage + errorString + '\n';
		return true;
	}
}

function validateDecimal(decimalValue) {
	/* Validates decimal numbers */
  if(trim(decimalValue).length <= 0) {
	  return true;
	}
  return decimalValue.match(/^(\+|-)?[0-9][0-9]*(\.[0-9]*)?$/) != null;
}

function validateDecimalNonNeg(decimalValue) {
	/* Validates non-negative decimals */
  if(trim(decimalValue).length <= 0) {
	  return true;
	}
  return decimalValue.match(/^[0-9][0-9]*(\.[0-9]*)?$/) != null;
}

function validateNumericComma(numCommaValue) {
	/* Validates an integer value with optional commas */
  if(trim(numCommaValue).length <= 0) {
	  return true;
	}
  return numCommaValue.match(/^(\+|-)?([1-9]{1}[0-9]{0,2}(\,[0-9]{3})*|[1-9]{1}[0-9]{0,}|0)$/) != null;
}

function validateMoney(moneyValue) {
	/* Validates a decimal money value with optional decimal point values up to 2 characters */
  if(trim(moneyValue).length <= 0) {
	  return true;
	}
  return moneyValue.match(/^(\+|-)?([1-9]{1}[0-9]{0,2}(\,[0-9]{3})*(\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\.[0-9]{0,2})?|0(\.[0-9]{0,2})?|(\.[0-9]{1,2})?)$/) != null;
}

function validateTelephone(telephone) {
	/* Simple validation for allowed characters in telephone numbers */
  if(trim(telephone).length <= 0) {
	  return true;
	}
	return telephone.match(/^[0-9\s\(\)\+\-]+$/) != null;
}

function validateUKTelephone(telephone) {
	/* Validates UK-specific telephone numbers */
  if(trim(telephone).length <= 0) {
	  return true;
	}
	return telephone.match(/(^0[1-9]\d{1}\s\d{4}\s?\d{4}$)|(^0[1-9]\d{2}\s\d{3}\s?\d{4}$)|(^0[1-9]\d{2}\s\d{4}\s?\d{3}$)|(^0[1-9]\d{3}\s\d{3}\s?\d{2}$)|(^0[1-9]\d{3}\s\d{3}\s?\d{3}$)|(^0[1-9]\d{4}\s\d{3}\s?\d{2}$)|(^0[1-9]\d{4}\s\d{2}\s?\d{3}$)|(^0[1-9]\d{4}\s\d{2}\s?\d{2}$)/) != null;
}

function validatePostcode(postcode) {
	/* Validates UK postcodes */
  if(trim(postcode).length <= 0) {
	  return true;
	}
	return postcode.match(/^[A-Za-z]{1,2}[0-9A-Za-z]{1,2}[ ]?[0-9]{0,1}[A-Za-z]{2}$/) != null;
}

function validateEmail(email) {
	/* Simple validation for an e-mail address */
  if(trim(email).length <= 0) {
	  return true;
	}
	var splitted = email.match(/^(.+)@(.+)$/);
	if(splitted == null) return false;
	if(splitted[1] != null ) {
		var regexp_user=/^\"?[\w-_\.]*\"?$/;
		if(splitted[1].match(regexp_user) == null) return false;
	}
	if(splitted[2] != null) {
		var regexp_domain=/^[\w-\.]*\.[A-Za-z]{2,4}$/;
		if(splitted[2].match(regexp_domain) == null) 
		{
		var regexp_ip =/^\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\]$/;
		if(splitted[2].match(regexp_ip) == null) return false;
		}// if
		return true;
	}
  return false;
}

function validateUSDateTime(datetimeString) {
	/* Validates US format dates and/or times (eg. mm/dd/yy hh:mm:ss)*/
  return datetimeString.match(/(?=\d)^(?:(?!(?:10\D(?:0?[5-9]|1[0-4])\D(?:1582))|(?:0?9\D(?:0?[3-9]|1[0-3])\D(?:1752)))((?:0?[13578]|1[02])|(?:0?[469]|11)(?!\/31)(?!-31)(?!\.31)|(?:0?2(?=.?(?:(?:29.(?!000[04]|(?:(?:1[^0-6]|[2468][^048]|[3579][^26])00))(?:(?:(?:\d\d)(?:[02468][048]|[13579][26])(?!\x20BC))|(?:00(?:42|3[0369]|2[147]|1[258]|09)\x20BC))))))|(?:0?2(?=.(?:(?:\d\D)|(?:[01]\d)|(?:2[0-8])))))([-.\/])(0?[1-9]|[12]\d|3[01])\2(?!0000)((?=(?:00(?:4[0-5]|[0-3]?\d)\x20BC)|(?:\d{4}(?!\x20BC)))\d{4}(?:\x20BC)?)(?:$|(?=\x20\d)\x20))?((?:(?:0?[1-9]|1[012])(?::[0-5]\d){0,2}(?:\x20[aApP][mM]))|(?:[01]\d|2[0-3])(?::[0-5]\d){1,2})?$/) != null;	
}

function validateDateTime(datetimeString) {
	/* Validates UK format dates and/or times (eg. dd/mm/yy hh:mm:ss)*/
  return datetimeString.match(/^(?=\d)(?:(?!(?:(?:0?[5-9]|1[0-4])(?:\.|-|\/)10(?:\.|-|\/)(?:1582))|(?:(?:0?[3-9]|1[0-3])(?:\.|-|\/)0?9(?:\.|-|\/)(?:1752)))(31(?!(?:\.|-|\/)(?:0?[2469]|11))|30(?!(?:\.|-|\/)0?2)|(?:29(?:(?!(?:\.|-|\/)0?2(?:\.|-|\/))|(?=\D0?2\D(?:(?!000[04]|(?:(?:1[^0-6]|[2468][^048]|[3579][^26])00))(?:(?:(?:\d\d)(?:[02468][048]|[13579][26])(?!\x20BC))|(?:00(?:42|3[0369]|2[147]|1[258]|09)\x20BC))))))|2[0-8]|1\d|0?[1-9])([-.\/])(1[012]|(?:0?[1-9]))\2((?=(?:00(?:4[0-5]|[0-3]?\d)\x20BC)|(?:\d{4}(?:$|(?=\x20\d)\x20)))\d{4}(?:\x20BC)?)(?:$|(?=\x20\d)\x20))?((?:(?:0?[1-9]|1[012])(?::[0-5]\d){0,2}(?:\x20[aApP][mM]))|(?:[01]\d|2[0-3])(?::[0-5]\d){1,2})?$/) != null;	
}

function validateData(strValidateStr,objValue) {
	/* Run the specified validation on the specified value */
	var epos = strValidateStr.search("="); 
	var command  = ""; 
	var cmdvalue = ""; 
	if(epos >= 0) { 
	 command  = strValidateStr.substring(0,epos); 
	 cmdvalue = strValidateStr.substr(epos+1); 
	} else { 
	 command = strValidateStr;
	}
	switch(command) 
	{ 
		case "req": 
		case "required":
		case "fill":
		case "filled":
		{ 
			if(eval(trim(objValue.value).length) == 0) {
				objValue.value = '';
				return false; 
			}
			break;             
		}
		case "maxlen": 
		case "maxlength": 
		{ 
			 if(eval(objValue.value.length) > eval(cmdvalue)) { 
				 return false; 
			 }
			 break; 
		}
		case "minlen": 
		case "minlength": 
		{ 
			if(eval(objValue.value.length) < eval(cmdvalue)) { 
			 return false;                 
			}
			break; 
		}
		case "alnum": 
		case "alphanumeric": 
		{ 
			var charpos = objValue.value.search("[^A-Za-z0-9]"); 
			if(trim(objValue.value).length > 0 && charpos >= 0) { 
				return false; 
			}
			break; 
		}
		case "num": 
		case "numeric": 
		{ 
			var charpos = objValue.value.search("[^0-9]"); 
			if(trim(objValue.value).length > 0 && charpos >= 0) { 
				return false; 
			}
			break;               
		}
		case "maxval": 
		case "maxvalue": 
		{
			 if(trim(objValue.value).length > 0 && eval(objValue.value) > eval(cmdvalue)) { 
				 return false;
			 }
			 break; 
		}
		case "minval": 
		case "minvalue": 
		{ 
			 if(trim(objValue.value).length > 0 && eval(objValue.value) < eval(cmdvalue)) { 
				 return false; 
			 }
			 break; 
		}
		case "maxmoney": 
		{
			 if(validateMoney(objValue.value)) {
				 var decimalValue = objValue.value.replace(/\,/g,'');
				 if(trim(decimalValue).length > 0 && eval(decimalValue) > eval(cmdvalue)) { 
					 return false;
				 }
			 }
			 break; 
		}
		case "minmoney":
		{
			 if(validateMoney(objValue.value)) {
				 var decimalValue = objValue.value.replace(/\,/g,'');
				 if(trim(decimalValue).length > 0 && eval(decimalValue) < eval(cmdvalue)) { 
					 return false;
				 }
			 }
			 break; 
		}
		case "dec":
		case "decimal":
		{ 
			return validateDecimal(objValue.value); 
			break; 
		}
		case "pdec":
		case "posdec":
		case "posdecimal":
		case "positivedecimal":
		{
			return validateDecimalNonNeg(objValue.value);
			break;
		}
		case "numcomma":
		{ 
			return validateNumericComma(objValue.value); 
			break; 
		}
		case "money":
		{ 
			return validateMoney(objValue.value); 
			break; 
		}
		case "alpha": 
		case "alphabetic": 
		{ 
			var charpos = objValue.value.search("[^A-Za-z]"); 
			if(trim(objValue.value).length > 0 && charpos >= 0) { 
				return false; 
			}
			break; 
		}
		case "alphauc":
		case "alphauppercase":
		case "alphabeticuc":
		case "alphabeticuppercase":
		{ 
			var charpos = objValue.value.search("[^A-Z]"); 
			if(trim(objValue.value).length > 0 && charpos >= 0) { 
				return false; 
			}
			break; 
		}
		case "alphalc":
		case "alphalowercase":
		case "alphabeticlc":
		case "alphabeticlowercase":
		{ 
			var charpos = objValue.value.search("[^a-z]"); 
			if(trim(objValue.value).length > 0 && charpos >= 0) { 
				return false; 
			}
			break; 
		}
		case "alnumhyphen":
		{
			var charpos = objValue.value.search("[^A-Za-z0-9-]"); 
			if(trim(objValue.value).length > 0 && charpos >= 0) { 
				return false; 
			}
		  break;
		}
		case "alnumhyphenspace":
		{
			var charpos = objValue.value.search("[^A-Za-z0-9- ]"); 
			if(trim(objValue.value).length > 0 && charpos >= 0) { 
				return false; 
			}
		  break;
		}
		case "alnumdash":
		{
			var charpos = objValue.value.search("[^A-Za-z0-9\-_]"); 
			if(trim(objValue.value).length > 0 && charpos >= 0) { 
				return false; 
			}
		  break;
		}
		case "alnumdashspace":
		{
			var charpos = objValue.value.search("[^A-Za-z0-9\-_ ]"); 
			if(trim(objValue.value.length) > 0 && charpos >= 0) { 
				return false; 
			}
		  break;
		}
		case "alnumspace":
		{
			var charpos = objValue.value.search("[^A-Za-z0-9 ]"); 
			if(trim(objValue.value).length > 0 && charpos >= 0) { 
				return false; 
			}
		  break;
		}
		case "username":
		{
			var charpos = objValue.value.search("[^A-Za-z0-9.-_]"); 
			if(trim(objValue.value).length > 0 && charpos >= 0) { 
				return false; 
			}
		  break;
		}
		case "email": 
		{ 
			return validateEmail(objValue.value); 
			break; 
		}
		case "tel":
		case "telephone":
		{ 
			return validateTelephone(objValue.value); 
			break; 
		}
		case "uktel":
		case "uktelephone":
		{ 
			return validateUKTelephone(objValue.value); 
			break; 
		}
		case "pc":
		case "postcode":
		{ 
			return validatePostcode(objValue.value); 
			break; 
		}
		case "dt":
		case "datetime":
		{ 
			return validateDateTime(objValue.value); 
			break; 
		}
		case "usdt":
		case "usdatetime":
		{ 
			return validateUSDateTime(objValue.value); 
			break; 
		}
		case "eq": 
		case "eqto": 
		case "equal": 
		case "equalto": 
		{ 
			if(eval(objValue.value) !=  eval(cmdvalue)) { 
				return false;                 
			}            
			break; 
		}
		case "neq": 
		case "neqto": 
		case "notequal": 
		case "notequalto": 
		{ 
			if(eval(objValue.value) ==  eval(cmdvalue)) { 
				return false;
			}            
			break; 
		}
		case "lt": 
		case "lessthan": 
		{ 
			if(trim(objValue.value).length > 0 && eval(objValue.value) >=  eval(cmdvalue)) { 
				return false;                 
			}            
			break; 
		}
		case "gt": 
		case "greaterthan": 
		{ 
			if(trim(objValue.value).length > 0 && eval(objValue.value) <=  eval(cmdvalue)) 
			{ 
			 return false;                 
			}           
			break; 
		}
		case "regexp": 
		{ 
			if(trim(objValue.value).length > 0) {
				if(!objValue.value.match(cmdvalue)) { 
					return false;                   
				}
			}
			break; 
		}
		case "select": 
		case "selected": 
		{ 
			if(cmdvalue == "") {
				cmdvalue = 0;
			}
			if(objValue.selectedIndex != eval(cmdvalue)) {
				return false;
			} 
			break; 
		}
		case "nselect": 
		case "nselected": 
		case "notselect": 
		case "notselected": 
		{ 
			if(cmdvalue == "") {
				cmdvalue = 0;
			}
			if(objValue.selectedIndex == eval(cmdvalue)) {
				return false;
			} 
			break; 
		}
		case "selectval": 
		case "selectedval": 
		case "selectvalue": 
		case "selectedvalue": 
		{
			if(cmdvalue == "") {
				cmdvalue = "";
			}
			if(objValue.options[objValue.selectedIndex].value != eval(cmdvalue)) {
				return false;
			} 
			break; 
		}
		case "nselectval": 
		case "nselectedval": 
		case "nselectvalue": 
		case "nselectedvalue": 
		case "notselectval": 
		case "notselectedval": 
		case "notselectvalue": 
		case "notselectedvalue": 
		{ 
			if(cmdvalue == "") {
				cmdvalue = "";
			}
			if(objValue.options[objValue.selectedIndex].value == eval(cmdvalue)) {
				return false;
			} 
			break; 
		}
		case "checkbox": 
		case "checked": 
		{
			if(cmdvalue == "") {
				cmdvalue = 1;
			}
			var checked = 0;
			if (typeof objValue.form[objValue.name].length != "undefined") {
				for (var i = 0; i < objValue.form[objValue.name].length; i++){
					if(objValue.form[objValue.name][i].checked) {
						checked++;
					}
				}
			} else {
				// Fix for checkbox groups with only one checkbox
				if (objValue.checked) {
					checked++;
				}
			}
			if(checked < eval(cmdvalue)) {
				return false;
			} 
			break; 
		}
	} 
	return true; 
}

function validateFileExtensions(inputItem, extList, errorString) {
	/* Checks a file upload input to make sure that only those file extensions in the comma-delimited
	   list (extList) are allowed eg. 'jpg,jpeg,gif' */
  if(typeof inputItem == 'undefined' || typeof errorString == 'undefined' || typeof extList == 'undefined') {
		alert('validateFileExtensions(inputItem, errorString, extList): Required parameter missing');
	  return false;
	}
	var itemObject = this[inputItem];
	if (trim(itemObject.value) == '') {
		return true;
	}
	var extArray = extList.split(',');
	var valid = false;
	for ( var i = 0; i < extArray.length; i++ ) {
		if (itemObject.value.toLowerCase().indexOf('.' + extArray[i].toLowerCase()) != -1) {
			valid = true;
		}
	}
	if (!valid) {
		if(addError(itemObject, errorString)){
		  showError(itemObject);
		}
		return false;
	} else {
		return true;
	}
}

function validateMultiSelect(inputItem, errorString, minS, maxS) {
	/* Checks a multi-select input to make sure that a minimum of minS and optionally a maximum of maxS selections
	   have been made */
  if(typeof inputItem == 'undefined' || typeof errorString == 'undefined' || typeof minS == 'undefined') {
		alert('validateMultiSelect(inputItem, errorString, minS, maxS): Required parameter missing');
	  return false;
	}
	var itemObject = this[inputItem];
	if(maxS == 999 || maxS == "*" || typeof maxS == 'undefined' || maxS > itemObject.length ) {
		maxS = itemObject.length;
	}
	var count = 0;
	for ( var opt, i = 0; ( opt = itemObject.options[i] ); i++ ) {
		if ( opt.selected ) count ++;
	}
	if ( count < minS || count > maxS ){
		if(addError(itemObject, errorString)){
		  showError(itemObject);
		}
		return false;
	}
	return true;
}

function validateCheckboxes(inputList, errorString, minC, maxC) {
	/* Examines a list of checkbox inputs to make sure that a minimum of minC and optionally a maximum of maxC boxes
	   have been checked */
  if(typeof inputList == 'undefined' || typeof errorString == 'undefined' || typeof minC == 'undefined') {
		alert('validateCheckboxes(inputList, errorString, minC, maxC): Required parameter missing');
	  return false;
	}
	var inputArray = inputList.split(',');
	if(maxC == 999 || maxC == "*" || typeof maxC == 'undefined' || maxC > inputArray.length ) {
		maxC = inputArray.length;
	}
	var count = 0;
	for(var i=0; i < inputArray.length; i++){
	  var itemObject = this[inputArray[i]];
		if(itemObject.checked) count++;
	}
	if(count < minC || count > maxC){
	  var itemObject = this[inputArray[0]];
		if(addError(itemObject, errorString)){
		  showError(itemObject);
			for(var i=0; i < inputArray.length; i++){
	      var itemObject = this[inputArray[i]];
				showErrorRow(itemObject);
			}
		}
		return false;
	}
	return true;
}

function validateRadios(inputItem, errorString, itemIndex) {
	/* Checks a named radio button group to see if a selection has been made. You may also optionally
	   specify an index number of a specific radio button that must be selected. */
  if(typeof inputItem == 'undefined' || typeof errorString == 'undefined') {
		alert('validateRadios(inputItem, errorString, itemIndex): Required parameter missing');
	  return false;
	}
	var itemObject = this[inputItem];
	var count = 0;
	for(var i=0; i < itemObject.length; i++){
		if(itemObject[i].checked){
		  if(typeof itemIndex != 'undefined'){
				if(i == itemIndex){
					count++;
				}
			} else {
			  count++;
			}
		}
	}
	if(count == 0){
		if(addError(itemObject[0], errorString)){
		  showError(itemObject[0]);
		}
		return false;
	}
	return true;
}

function compareFields(inputItem, inputCompare, comparison, errorString) {
	/* Compares the contents of two input fields based on the specified comparison (eg. lt, gt, eq) */
  if(typeof inputItem == 'undefined' || typeof inputCompare == 'undefined' || typeof errorString == 'undefined' || typeof comparison == 'undefined') {
		alert('compareFields(inputItem, inputCompare, comparison, errorString): Required parameter missing');
	  return false;
	}
	var itemObject = this[inputItem];
	var itemValue = itemObject.value;
	var compareObject = this[inputCompare];
	var compareValue = compareObject.value;
	var passedCheck = false;
	if(itemValue == "" && compareValue == "") {
		passedCheck = true;
	} else {
		switch(comparison) {
			case "eq":
			case "equal":
			case "equalto":
			case "=":
			case "==":
			{
				if(itemValue == compareValue) {passedCheck = true;}
				break;
			}
			case "neq":
			case "notequal":
			case "notequalto":
			case "!=":
			case "!==":
			case "<>":
			{
				if(itemValue != compareValue) {passedCheck = true;}
				break;
			}
			case "lt":
			case "lessthan":
			case "<":
			{
				if(itemValue < compareValue) {passedCheck = true;}
				break;
			}
			case "gt":
			case "greaterthan":
			case ">":
			{
				if(itemValue > compareValue) {passedCheck = true;}
				break;
			}
			case "lte":
			case "<=":
			{
				if(itemValue <= compareValue) {passedCheck = true;}
				break;
			}
			case "gte":
			case ">=":
			{
				if(itemValue <= compareValue) {passedCheck = true;}
				break;
			}
			default:
			{
				alert('compareFields(): Unknown comparison string.');
				return false;
			}
		}
	}
	if(!passedCheck){
		if(addError(itemObject, errorString)){
			showError(itemObject);
			showErrorRow(compareObject);
		}
		return false;
	}
	return true;
}

function validateMinRequired(inputList, errorString, minR) {
	/* Examines a list of field inputs to make sure that a minimum of minR fields have been filled */
  if(typeof inputList == 'undefined' || typeof errorString == 'undefined' || typeof minR == 'undefined') {
		alert('validateMinRequired(inputList, errorString, minR): Required parameter missing');
	  return false;
	}
	var inputArray = inputList.split(',');
	var count = 0;
	for(var i=0; i < inputArray.length; i++){
	  var itemObject = this[inputArray[i]];
		if(trim(itemObject.value) != '') count++;
	}
	if(count < minR){
	  var itemObject = this[inputArray[0]];
		if(addError(itemObject, errorString)){
		  showError(itemObject);
			for(var i=0; i < inputArray.length; i++){
	      var itemObject = this[inputArray[i]];
				showErrorRow(itemObject);
			}
		}
		return false;
	}
	return true;
}

function validateMinSelectRequired(selectList, errorString, minR) {
	/* Examines a list of selects to make sure that a minimum of minR selects have been chosen */
  if(typeof selectList == 'undefined' || typeof errorString == 'undefined' || typeof minR == 'undefined') {
		alert('validateMinSelectRequired(selectList, errorString, minR): Required parameter missing');
	  return false;
	}
	var selectArray = selectList.split(',');
	var count = 0;
	for(var i=0; i < selectArray.length; i++){
	  var selectObject = this[selectArray[i]];
		if(selectObject.selectedIndex != 0) count++;
	}
	if(count < minR){
	  var selectObject = this[selectArray[0]];
		if(addError(selectObject, errorString)){
		  showError(selectObject);
			for(var i=0; i < selectArray.length; i++){
	      var selectObject = this[selectArray[i]];
				showErrorRow(selectObject);
			}
		}
		return false;
	}
	return true;
}

function validateDateSelect(daySelectItem, monthSelectItem, yearSelectItem, errorString) {
	/* Checks the contents of a set of date select fields (eg. Day Month Year) for a valid date. */
	/* If the date is optional (ie. if there are more than 12 options for month), and no values  */
	/* have been selected, the check is bypassed. */
	if(typeof daySelectItem == 'undefined' || typeof monthSelectItem == 'undefined' || typeof yearSelectItem == 'undefined' || typeof errorString == 'undefined') {
		alert('validDateSelect(daySelectItem, monthSelectItem, yearSelectItem, errorString): Required parameter missing');
	  return false;
	}
	daySelectObject = this[daySelectItem];
	dayValue = daySelectObject[daySelectObject.selectedIndex].value;
	monthSelectObject = this[monthSelectItem];
	monthValue = monthSelectObject[monthSelectObject.selectedIndex].value;
	yearSelectObject = this[yearSelectItem];
	yearValue = yearSelectObject[yearSelectObject.selectedIndex].value;
	if(monthSelectObject.length > 12 && daySelectObject.selectedIndex == 0 && monthSelectObject.selectedIndex == 0 && yearSelectObject.selectedIndex == 0){
		return true;
	}
	if(!validateDateTime(dayValue + '/' + monthValue + '/' + yearValue)){
		if(addError(daySelectObject, errorString)){
			showError(daySelectObject);
		}
		return false;
	}
	return true;
}

function compareDateSelect(daySelectItem, monthSelectItem, yearSelectItem, comparison, errorString, daySelectCompare, monthSelectCompare, yearSelectCompare){
	/* Compares the contents of two sets of date select fields (eg. Day Month Year) based on the
	   specified comparison (eg. lt, gt, eq). If the second set of date select fields is not specified,
		 the date is compared to the current date instead. */
	if(typeof daySelectItem == 'undefined' || typeof monthSelectItem == 'undefined' || typeof yearSelectItem == 'undefined' ||
		 typeof errorString == 'undefined' || typeof comparison == 'undefined') {
		alert('compareDateSelects(daySelectItem, monthSelectItem, yearSelectItem, comparison, errorString, daySelectCompare, monthSelectCompare, yearSelectCompare): Required parameter missing');
	  return false;
	}
	daySelectObject = this[daySelectItem];
	monthSelectObject = this[monthSelectItem];
	yearSelectObject = this[yearSelectItem];
	dateItem = new Date(yearSelectObject[yearSelectObject.selectedIndex].value, monthSelectObject[monthSelectObject.selectedIndex].value - 1, daySelectObject[daySelectObject.selectedIndex].value);
	if(typeof daySelectCompare != 'undefined' && typeof monthSelectCompare != 'undefined' && typeof yearSelectCompare != 'undefined'){
	  dayCompareObject = this[daySelectCompare];
	  monthCompareObject = this[monthSelectCompare];
	  yearCompareObject = this[yearSelectCompare];
	  dateCompare = new Date(yearCompareObject[yearCompareObject.selectedIndex].value, monthCompareObject[monthCompareObject.selectedIndex].value - 1, dayCompareObject[dayCompareObject.selectedIndex].value);
	} else {
		dateCompare = new Date();
	}
  var passedCheck = false;
	switch(comparison) {
		case "eq":
		case "equal":
		case "equalto":
		case "=":
		case "==":
		{
			if(Date.parse(dateItem) == Date.parse(dateCompare)) {passedCheck = true;}
			break;
		}
		case "neq":
		case "notequal":
		case "notequalto":
		case "!=":
		case "!==":
		case "<>":
		{
			if(Date.parse(dateItem) != Date.parse(dateCompare)) {passedCheck = true;}
			break;
		}
		case "lt":
		case "lessthan":
		case "<":
		{
			if(Date.parse(dateItem) < Date.parse(dateCompare)) {passedCheck = true;}
			break;
		}
		case "gt":
		case "greaterthan":
		case ">":
		{
			if(Date.parse(dateItem) > Date.parse(dateCompare)) {passedCheck = true;}
			break;
		}
		case "lte":
		case "<=":
		{
			if(Date.parse(dateItem) <= Date.parse(dateCompare)) {passedCheck = true;}
			break;
		}
		case "gte":
		case ">=":
		{
			if(Date.parse(dateItem) <= Date.parse(dateCompare)) {passedCheck = true;}
			break;
		}
		default:
		{
			alert('compareDateSelects(): Unknown comparison string.');
			return false;
		}
	}
	if(!passedCheck){
		if(addError(daySelectObject, errorString)){
			showError(daySelectObject);
			if(typeof dayCompareObject != 'undefined'){
			  showErrorRow(dayCompareObject);
			}
		}
		return false;
	}
	return true;
}

function validateAddNew(selectItem, inputItem, addNewValue, errorString) {
	/* Checks an 'add new' select and text input combination to make sure that a value has been entered
	   if the user has chosen to add a new item */
  if(typeof selectItem == 'undefined' || typeof inputItem == 'undefined' || typeof addNewValue == 'undefined' || typeof errorString == 'undefined') {
		alert('validateAddNew(selectItem, inputItem, addNewValue, errorString): Required parameter missing');
	  return false;
	}
	var selectObject = this[selectItem];
	var itemObject = this[inputItem];
	if ( selectObject.options[selectObject.selectedIndex].value == addNewValue && trim(itemObject.value) == "" ) {
		if(addError(selectObject, errorString)){
			showError(selectObject);
		}
		return false;
	}
	return true;
}

function validateUnitSelect(inputItem, selectItem, promptIndex, errorString) {
	/* Checks to see if a specified field has been filled, and if so makes sure that a specified select
	   option has not been selected. Useful for adding a 'units' selection for a numeric field. */
  if(typeof inputItem == 'undefined' || typeof selectItem == 'undefined' || typeof promptIndex == 'undefined' || typeof errorString == 'undefined') {
		alert('validateUnitsSelect(inputItem, selectItem, excludeIndex, errorString): Required parameter missing');
	  return false;
	}
	var itemObject = this[inputItem];
	var selectObject = this[selectItem];
	if ( trim(itemObject.value) != "" && trim(itemObject.value) != '0' && selectObject.selectedIndex == promptIndex) {
		if(addError(selectObject, errorString)){
			showError(selectObject);
		}
		return false;
	}
	return true;
}

function validatePermissionCheckbox(inputItemList, checkboxItem, errorString) {
	/* Checks a comma-delimited list of text input fields to see if any have a value. 
	   If one or more values are found, a checkbox is examined to make sure it is     
	   checked. This is useful for a form where certain terms and conditions apply to 
	   a group of optional fields. */
  if(typeof inputItemList == 'undefined' || typeof checkboxItem == 'undefined' || typeof errorString == 'undefined') {
		alert('validatePermissionCheckbox(inputItemList, checkboxItem, errorString): Required parameter missing');
	  return false;
	}
	var inputFilled = false;
	var inputItemArray = inputItemList.split(',');
	for ( var i = 0; i < inputItemArray.length; i++ ) {
		var itemObject = this[inputItemArray[i]];
		if (trim(itemObject.value) != '') {
			inputFilled = true;
		}
	}
	if (inputFilled) {
		var checkboxObject = this[checkboxItem];
		if (checkboxObject.checked == false) {
			if(addError(checkboxObject, errorString)){
				showError(checkboxObject);
			}
			return false;
		}
	}
	return true;
}

function validatePair(conditionList, validationList, errorString) {
	// Work in progress...
  if(typeof conditionList == 'undefined' || typeof validationList == 'undefined' || typeof errorString == 'undefined') {
		alert('validatePair(conditionList, validationList, errorString): Required parameter missing');
	  return false;
	}
	var conditionArray = conditionList.split(',');
	if(conditionArray.length != 2) {
		alert('validatePair(conditionList, validationList, errorString): Required parameter missing in conditionList');
	  return false;
	}
	var validationArray = validationList.split(',');
	if(validationArray.length != 2) {
		alert('validatePair(conditionList, validationList, errorString): Required parameter missing in validationList');
	  return false;
	}
	if(validateData(conditionArray[1], this[conditionArray[0]])) {
		if(!validateData(validationArray[1], this[validationArray[0]])) {
			if(addError(this[validationArray[0]], errorString)){
				showError(this[validationArray[0]]);
			}
			return false;
		}
	}
	return true;
}

