﻿/* -------------------------------------------------------------------------- */
/* [FormValidation.js]: Generic client-side form validator                    */
/*                                                                            */
/* Version 1.1                                                                */
/*   - 2 February 2000 (Bryan Krofchok)                                       */
/*                                                                            */
/* Version 1.2                                                                */
/*   - 1 May 2000 (Bryan Krofchok)                                            */
/*                                                                            */
/* Version 1.3                                                                */
/*   - 23 October 2000 (Natalia Collins)                                      */
/*       * Documentation updated                                              */
/*                                                                            */
/* Version 1.4                                                                */
/*   - 8 February 2001 (Steve Mathias, Bryan Krofchok, Natalia Collins)       */
/*       * Various miscellaneous enhancements                                 */
/*                                                                            */
/* Version Civica cv1.0                                                       */
/*   - 1 April 2005 (Stuart Gregg)																			      */
/*       * Modified to work with civica form format                           */
/*                                                                            */
/* Version cv1.2                                                              */
/*   - 28 January 2007 (Stuart Gregg)																		      */
/*       * Checks for named elements in the validate function                 */
/*                                                                            */
/* Copyright (c) 2000-2001 EurekaDIGITAL                                      */
/*                                                                            */
/* Usage: See the comment block for the main validate() function.             */
/* -------------------------------------------------------------------------- */


/* --------------------------- Global "Constants" --------------------------- */

var validatedElementPrefix = '[0-9]{3}~';

var minPasswordLength = 6;


/* ---------------------------- Global Variables ---------------------------- */

var scrollPage = false; 
                           
/* ------------------------ Main Validation Function ------------------------ */

function validate(form) {
  return validate(form, null);
}

function validate(form, specializedValidationFunction)
{

  validateAll(form);
    
  var identifierPattern = new RegExp(validatedElementPrefix + '.*');

  // Loop through each form element, applying validation tests as appropriate
  for (var i = 0; i < form.elements.length; i++) {
    var inputElement = form.elements[i];

		if( inputElement.name )
		{ 
		
			// Validated elements must have the proper variable name prefix
			fieldIdentifier = inputElement.name.match(identifierPattern);
			
			if( fieldIdentifier == null ) continue;
			
			// Trim any extraneous whitespace from the input element's value
			trimField(inputElement);
	        
			// Validate the field based on its type
			var fieldType = getFieldType(inputElement);
			if (fieldType != null)
				for (var validatedType in validators)
					if (fieldType.indexOf(validatedType) >= 0 && !validators[validatedType](inputElement)) return false;
		}
  }

  // If present, run the specialized validation function
  if (specializedValidationFunction != null)
  {
    return eval(specializedValidationFunction + '(form);');
  }

  // The form data has passed all validation tests...
  return true;
}

function validateAll(form)
{
    var inputElement;
    var fieldLabel;
    var labels;
    var labelInput;
    fieldLabel = '';
    labels = document.getElementsByTagName("label");
    if (labels.length > 0)
    {
        for (var i=0; i<labels.length; i++)
        {
            if(labels[i].id.indexOf('Required') > 0)
            {
                for (var j = 0; j < form.elements.length; j++) 
                {
                    var inputElement = form.elements[j];
	                if( inputElement.name )
	                    if( inputElement.name == labels[i].id)
	                        if(inputElement.type!='radio')
	                            labelInput = inputElement;
               } 
               if (labelInput != null)
                    validateLabel(labelInput,labels[i]);
               else
               {
                    for (var j = 0; j < form.elements.length; j++) 
                    {
                        var inputElement = form.elements[j];
	                    if( inputElement.name )
	                    {
                            if( inputElement.name.indexOf(labels[i].id) >= 0)

	                            if(inputElement.checked)
                                    labelInput = inputElement;
                        }
                   } 
                   if (labelInput == null)
                        labels[i].className = 'LabelError';
                   else
                        labels[i].className = '';
                   
               }
               labelInput =  null;
            }
        }
    }
    return fieldLabel;


  // The form data has passed all validation tests...
  return true;
}

function validateLabel(inputElement,label)
{

  if (isBlank(inputElement)) 
    label.className = 'LabelError';
  else
    label.className = '';
}

/* ---------------------------- Variable Parsers ---------------------------- */

function getFieldIdentifier(inputElement)
{
  var identifierPattern = new RegExp('^' + validatedElementPrefix + '([^~]+)');
  var fieldIdentifier = inputElement.name.match(identifierPattern);
  return (fieldIdentifier != null ? fieldIdentifier[1] : null);
}

function getFieldLabel(inputElement)
{
  var fieldLabel;
  fieldLabel = getFieldLabel1(inputElement);
  if (fieldLabel == '')
  {
      // Start with the element's field identifier
      fieldLabel = getFieldIdentifier(inputElement);
      if (fieldLabel == null) return null;

      // Unescape special characters
      fieldLabel = fieldLabel.replace(/XAX/g, "'");
      fieldLabel = fieldLabel.replace(/XHX/g, "-");
      fieldLabel = fieldLabel.replace(/XSX/g, "/");
      
      // Insert spaces before capitalized letters preceeded by a lower-case letters
      fieldLabel = fieldLabel.replace(/([a-z])([A-Z])/g, '$1 $2');

      // Replace _ with space
      fieldLabel = fieldLabel.replace(/_/, ' ');

      // Insert spaces after capitalized acronyms
      fieldLabel = fieldLabel.replace(/([A-Z][A-Z]+)([A-Z][a-z])/g, '$1 $2');

      // Replace "known" identifiers
      fieldLabel = fieldLabel.replace(/Email/, 'E-mail');
      fieldLabel = fieldLabel.replace(/State Province/, 'State/Province');
      fieldLabel = fieldLabel.replace(/Zip Postal Code/, 'Zip/Postal Code');
  }
  return fieldLabel;
}

function getFieldLabel1(inputElement){
    var fieldLabel;
    var labels;
    fieldLabel = '';
    labels = document.getElementsByTagName("label");
    if (labels.length > 0)
    {
        for (var i=0; i<labels.length; i++)
        {
            if(labels[i].id == inputElement.name)
            {
                fieldLabel = labels[i].innerHTML;
                fieldLabel = StripHtml(fieldLabel);
            }
        }
    }
    return fieldLabel;
}

function getFieldType(inputElement)
{
  var fieldType = inputElement.name.match(/~~([^~~]+)$/);
  return (fieldType != null ? fieldType[1] : null);
}


/* ------------------ Form Input Element Utility Functions ------------------ */

function trimField(inputElement)
{
  var elementType = inputElement.type;
  if ((elementType == 'text' || elementType == 'textarea')
      && inputElement.value != null)
    inputElement.value = trim(inputElement.value);
}

function isBlank(inputElement)
{
  var elementType = inputElement.type;
  if (elementType == 'text' || elementType == 'textarea' || elementType == 'password' || elementType == 'file')
    return (inputElement.value == null || inputElement.value == '');
  else if (elementType == 'select-one') {
    if (inputElement.selectedIndex < 0) return true;
    optionText = inputElement.options[inputElement.selectedIndex].text;
    optionValue = inputElement.options[inputElement.selectedIndex].value;
    return (optionText == null
            || optionText == ''
            || optionText.indexOf('---') >= 0
            || optionValue == null
            || optionValue == ''
            || optionValue.indexOf('---') >= 0);
  }
  return false;
}

function selectElementAvoidSeparator(selectElement)
{
  if (selectElement.options[selectElement.selectedIndex].text.indexOf('---') >= 0) {
    for (var i = 0; i < selectElement.options.length; i++) {
      if (selectElement.options[i].defaultSelected) {
        selectElement.selectedIndex = i;
        return;
      }
    }
    selectElement.selectedIndex = 0;
  }
}

/* -------------------------- Validation Functions -------------------------- */

var validators = new Object();

validators['Required'] = function(inputElement)
{

  if (isBlank(inputElement)) {
    var elementType = inputElement.type;
    var fieldIdentifier = getFieldIdentifier(inputElement);
    var fieldLabel = getFieldLabel(inputElement);
    var errorMessage = '';
    if (elementType == 'text' || elementType == 'textarea' || elementType == 'file')
      errorMessage = 'The ' + fieldLabel + ' field is required and cannot be blank.\n' +
        'Please enter a values, then re-submit the form...';
    else if (elementType == 'select-one')
      errorMessage = 'Please select ' + fieldLabel +
        ', then\nre-submit the form...';
    else if (elementType == 'password') {
      if (fieldIdentifier.match(/Confirm/)) {
        fieldLabel = fieldLabel.replace(/(Confirm | Confirm)/, '');
        errorMessage = 'For confirmation, please enter your ' + fieldLabel + ' twice...';
      }
      else
        errorMessage = 'Please enter ' + getPrefixArticle(fieldLabel) + fieldLabel + '...';
    }
    showValidationError(inputElement, errorMessage);

    return false;
  }
  return true;
};

validators['Alphanumeric'] = function(inputElement)
{
  if (!isBlank(inputElement) && !isAlphanumeric(inputElement.value)) {
    showValidationError(inputElement, 'The ' + getFieldLabel(inputElement) +
      ' field can contain only letters and digits, and no spaces.\nPlease ' +
      'check the value, then re-submit the form...');
    return false;
  }
  return true;
};

validators['Alphabetic'] = function(inputElement)
{
  var alphabeticPattern = /^[A-Za-z]+$/;

  if (!isBlank(inputElement) && !inputElement.value.match(alphabeticPattern)) {
    showValidationError(inputElement, 'The ' + getFieldLabel(inputElement) +
      ' field can contain only letters, and no digits or spaces.\nPlease ' +
      'check the value, then re-submit the form...');
    return false;
  }
  return true;
};

validators['Date'] = function(inputElement)
{
  var datePattern = /^[0-9]?[0-9]\/[0-9]?[0-9]\/[0-9][0-9][0-9][0-9]$/;

  if (!isBlank(inputElement) && !inputElement.value.match(datePattern)) {
    showValidationError(inputElement, 'The ' + getFieldLabel(inputElement) +
      ' field can only be input in mm/dd/yyyy format.\nPlease ' +
      'check the value, then re-submit the form...');
    return false;
  }
  return true;
};

validators['Time'] = function(inputElement)
{
  var timePattern = /^[0-1]?[0-9]:[0-5][0-9] ?[AaPp][Mm]$/;

  if (!isBlank(inputElement) && !inputElement.value.match(timePattern)) {
    showValidationError(inputElement, 'The ' + getFieldLabel(inputElement) +
      ' field can only be input in 9:00AM format.\nPlease ' +
      'check the value, then re-submit the form...');
    return false;
  }
  return true;
};

validators['Numeric'] = function(inputElement)
{
  var numericPattern = /^[0-9]+$/;

  if (!isBlank(inputElement) && !inputElement.value.match(numericPattern)) {
    showValidationError(inputElement, 'The ' + getFieldLabel(inputElement) +
      ' field can contain only digits, and no letters or spaces.\nPlease ' +
      'check the value, then re-submit the form...');
    return false;
  }
  return true;
};

validators['Password'] = function(inputElement)
{
  if (inputElement.type == 'password') {

    /* Ordinary password field... */
    if (!getFieldIdentifier(inputElement).match(/Confirm/)) {
      if (!isBlank(inputElement)) { /* don't check blank password fields */
        if (!isAlphanumeric(inputElement.value)) {
          showValidationError(inputElement, 'Passwords can contain only ' +
            'letters and numbers, and no spaces...');
          inputElement.value = '';
          return false;
        }
        else if (inputElement.value.length < minPasswordLength) {
          showValidationError(inputElement, 'Passwords must have at least ' +
            minPasswordLength + ' characters...');
          inputElement.value = '';
          return false;
        }
      }
    }

    /* Password confirmation field... */
    else {

      // Obtain the paired password element, and check for password match
      var pairedInputElement = (inputElement.form)[inputElement.name.replace(/Confirm/, '')];
      if (pairedInputElement != null
          && pairedInputElement.type == 'password'
          && !isBlank(pairedInputElement)) {
        if (inputElement.value != pairedInputElement.value) {
          showValidationError(pairedInputElement, 'The ' + getFieldLabel(pairedInputElement) +
            ' field and confirmation do not match.\nPlease re-enter the password...');
          inputElement.value = pairedInputElement.value = '';
          return false;
        }
      }
    }
  }
  return true;
};

validators['ZipPostalCode'] = function(inputElement)
{
  var zipPattern = /^((\d\d\d\d\d((-\d\d\d\d)?))|([A-Z]\d[A-Z] \d[A-Z]\d))$/;

  if (!isBlank(inputElement) && !inputElement.value.match(zipPattern)) {
    showValidationError(inputElement, 'The ' + getFieldLabel(inputElement) +
      ' field must contain a five-digit ZIP code,\n' +
      'ZIP+4 code (99999-9999), or Canadian postal code (A9A 9A9).\n' +
      'Please check the value, then re-submit the form...');
    return false;
  }
  return true;
}

validators['PhoneNumber'] = function(inputElement)
{
  var phonePattern = /^[0-9 ()\/.x-]*$/;

  if (!inputElement.value.match(phonePattern)) {
    showValidationError(inputElement, 'The ' + getFieldLabel(inputElement) +
      ' field can contain only digits and common\n\"phone number\" characters ' +
      '[ ( ) - / . x ]. Please check\nthe value, then re-submit the form...');
    return false;
  }
  return true;
}

validators['EmailAddress'] = function(inputElement)
{
  var emailPattern = /^([^@. ]+\.)*[^@. ]+@([^@. ]+\.)+[^@. ]+$/;

  if (!isBlank(inputElement) && !inputElement.value.match(emailPattern)) {
    showValidationError(inputElement, 'Invalid E-mail address. Please check ' +
      'the format,\nthen re-submit the form...');
    return false;
  }
  return true;
}

validators['URL'] = function(inputElement)
{
  var urlPattern = /^(http:\/\/|https:\/\/|mailto:)([^. ]+\.)+[^. ]+$/;

  var url = inputElement.value;

  if(!getFieldIdentifier(inputElement).match(/LinkText/)) {
    if (!isBlank(inputElement) && !url.match(urlPattern)) {
      showValidationError(inputElement, 'Invalid URL' +
        (url.indexOf('http://') != 0 && url.indexOf('https://') != 0 && url.indexOf('mailto:') != 0 ?
          ' (must begin with \'http://\' or \'https://\' or \'mailto:\')' : '') +
          '. Please check the format,\nthen re-submit the form...');
      return false;
    }
  } else {
    // Obtain the paired URL element
    var pairedInputElement = (inputElement.form)[inputElement.name.replace(/LinkText/, '')];
    if (pairedInputElement != null && !isBlank(pairedInputElement)) {
      if (isBlank(inputElement)) {
        errorMessage = 'The ' + getFieldLabel(inputElement) +
          ' field cannot be blank.\nPlease enter ' + getFieldLabel(inputElement) + ' and re-submit the form...';
        inputElement.focus();
        alert(errorMessage);
        scrollBy(0,-42);
        return false;
      }
    }
  }
  return true;
}

function showValidationError(inputElement, errorMessage)
{
  inputElement.focus();
  alert(errorMessage);
  if (scrollPage) scrollBy(0,-20);
}



/* String Utility Functions */

function isAlphanumeric(str)
{
  return str.match(/^[A-Za-z0-9]+$/);
}

function trim(str)
{
  if (str != null) {
    str = str.replace(/(\r\n)/g, '\n');
    str = str.replace(/[\f\r]+/g, '\n');  /* test for \v fails in IE */
    str = str.replace(/[\t]+/g, ' ');
    str = str.replace(/ [ ]+/g, ' ');
    str = str.replace(/^ /, '');
    str = str.replace(/ \n/g, '\n');
    str = str.replace(/\n /g, '\n');
    str = str.replace(/ $/, '');
    str = str.replace(/\n\n[\n]+/g, '\n\n');
    str = str.replace(/^\n\n/, '');
    str = str.replace(/^\n/, '');
    str = str.replace(/\n\n$/, '');
    str = str.replace(/\n$/, '');
  }
  return str;
}

function getPrefixArticle(str)
{
  return (str.match(/^[AEIOU]/) ? 'an ' : 'a ');
}

function ValidateAndSubmit( form )
{
	if( validate(form, null) ) form.submit();
}
