/***********************************************************************

FILE: RegExpValidate.js

ID: $Id: regexpvalidate.js,v 1.1 2006/05/18 00:21:11 dmz Exp $
 
DESCRIPTION: This file contains a library of validation functions
  using javascript regular expressions.  Library also contains functions
  that reformat fields for display or for storage.
 
  VALIDATION FUNCTIONS:
 
  validateCurrency - checks for valid currency format
  validateTime - checks for valid 12 hour time
  validateState -  checks for valid state abbreviation  
  validateSSN - checks format of social security number
  validateEmail - checks format of email address
  validateUSPhone - checks format of US phone number
  validateNumeric - checks for valid numeric value
  validateInteger - checks for valid integer value
  validateNotEmpty - checks for blank form field
  validateUSZip - checks for valid US zip code
  validateUSDate - checks for valid date in US format
  validateValue - checks a string against supplied pattern
  
  FORMAT FUNCTIONS:
  
  rightTrim - removes trailing spaces from a string
  leftTrim - removes leading spaces from a string
  trimAll - removes leading and trailing spaces from a string
  removeCurrency - removes currency formatting characters (), $ 
  addCurrency - inserts currency formatting characters
  removeCommas - removes comma separators from a number
  addCommas - adds comma separators to a number
  removeCharacters - removes characters from a string that match passed
          pattern
***********************************************************************/
 
function validateCurrency(strValue)
{
/************************************************
DESCRIPTION: Validates that a string contains a 
  valid currency format. 
  
 PARAMETERS:
   strValue - String to be tested for validity
   
RETURNS:
   True if valid, otherwise false.
*************************************************/
  var objRegExp = /(^\$\d{1,3}(,\d{3})*\.\d{2}$)|(^\(\$\d{1,3}(,\d{3})*\.\d{2}\)$)/;
  return objRegExp.test(strValue);
}
 
function validateTime(strValue)
{
/************************************************
DESCRIPTION: Validates that a string contains a 
  valid 12 hour time format. Seconds are optional.
  
 PARAMETERS:
   strValue - String to be tested for validity
   
RETURNS:
   True if valid, otherwise false.
 
REMARKS: Returns True for time formats such as:
  HH:MM or HH:MM:SS or HH:MM:SS.mmm (where the
  .mmm is milliseconds as used in SQL Server 
  datetime datatype.  Also, the .mmm portion will 
  accept 1 to 3 digits after the period)
*************************************************/
  var objRegExp = /^([1-9]|1[0-2]):[0-5]\d(:[0-5]\d(\.\d{1,3})?)?$/;
  return objRegExp.test(strValue);
}
 
function validateState(strValue)
{
/************************************************
DESCRIPTION: Validates that a string contains a 
  valid state abbreviation. 
  
 PARAMETERS:
   strValue - String to be tested for validity
   
RETURNS:
   True if valid, otherwise false.
*************************************************/
 
  var objRegExp = /^(AK|AL|AR|AZ|CA|CO|CT|DC|DE|FL|GA|HI|IA|ID|IL|IN|KS|KY|LA|MA|MD|ME|MI|MN|MO|MS|MT|NB|NC|ND|NH|NJ|NM|NV|NY|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VA|VT|WA|WI|WV|WY)$/i;
  return objRegExp.test(strValue);
}
 
function validateSSN(strValue)
{
/************************************************
DESCRIPTION: Validates that a string contains a 
  valid social security number. 
  
 PARAMETERS:
   strValue - String to be tested for validity
   
RETURNS:
   True if valid, otherwise false.
*************************************************/
  var objRegExp = /^\d{3}\-\d{2}\-\d{4}$/;
 
  //check for valid SSN
  return objRegExp.test(strValue);
}
 
function validateEmail(strValue)
{
/************************************************
DESCRIPTION: Validates that a string contains a 
  valid email pattern. 
  
 PARAMETERS:
   strValue - String to be tested for validity
   
RETURNS:
   True if valid, otherwise false.
   
REMARKS: Accounts for email with country appended
  does not validate that email contains valid URL
  type (.com, .gov, etc.) and optionally,
  a valid country suffix.  Since email has many
  forms this expression only tests for near valid
  address.  Some additional validation may be
  required.
*************************************************/
  var objRegExp = /^[a-z0-9]([a-z0-9_\-\.]*)@([a-z0-9_\-\.]+)(\.[a-z]{2,3}(\.[a-z]{2}){0,2})$/i;
  //check for valid email
  return objRegExp.test(strValue);
}
 
function validateUSPhone(strValue)
{
/************************************************
DESCRIPTION: Validates that a string contains valid
  US phone pattern. 
  Ex. (999) 999-9999 or (999)999-9999
  
PARAMETERS:
   strValue - String to be tested for validity
   
RETURNS:
   True if valid, otherwise false.
*************************************************/
  var objRegExp = /^\([1-9]\d{2}\)\s?\d{3}\-\d{4}$/;
 
  //check for valid us phone with or without space between 
  //area code
  return objRegExp.test(strValue); 
}
 
function  validateNumeric(strValue)
{
/*****************************************************************
DESCRIPTION: Validates that a string contains only valid numbers.
 
PARAMETERS:
   strValue - String to be tested for validity
   
RETURNS:
   True if valid, otherwise false.
******************************************************************/
  var objRegExp = /(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)/; 
 
  //check for numeric characters 
  return objRegExp.test(strValue);
}
 
function validateInteger(strValue)
{
/***************************************************
DESCRIPTION: Validates that a string contains only 
    valid integer number.
    
PARAMETERS:
   strValue - String to be tested for validity
   
RETURNS:
   True if valid, otherwise false.
****************************************************/
  var objRegExp = /(^-?\d\d*$)/;
 
  //check for integer characters
  return objRegExp.test(strValue);
}
 
function validateNotEmpty(strValue)
{
/************************************************
DESCRIPTION: Validates that a string is not all
  blank (whitespace) characters.
    
PARAMETERS:
   strValue - String to be tested for validity
   
RETURNS:
   True if valid, otherwise false.
*************************************************/
   var strTemp = strValue;
   strTemp = trimAll(strTemp);
   return strTemp.length > 0;
}
 
function validateUSZip(strValue)
{
/************************************************
DESCRIPTION: Validates that a string a United
  States zip code in 5 digit format or zip+4
  format. 99999 or 99999-9999
    
PARAMETERS:
   strValue - String to be tested for validity
   
RETURNS:
   True if valid, otherwise false.
 
*************************************************/
  var objRegExp = /(^\d{5}$)|(^\d{5}-\d{4}$)/;
 
  //check for valid US Zipcode
  return objRegExp.test(strValue);
}
 
function validateUSDate(strValue)
{
/************************************************
DESCRIPTION: Validates that a string contains only 
    valid dates with 2 digit month, 2 digit day, 
    4 digit year. Date separator can be ., -, or /.
    Uses combination of regular expressions and 
    string parsing to validate date.
    Ex. mm/dd/yyyy or mm-dd-yyyy or mm.dd.yyyy
    
PARAMETERS:
   strValue - String to be tested for validity
   
RETURNS:
   True if valid, otherwise false.
   
REMARKS:
   Avoids some of the limitations of the Date.parse()
   method such as the date separator character.
*************************************************/
  var objRegExp = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{4}$/
 
  //check to see if in correct format
  if (!objRegExp.test(strValue))
    return false; //doesn't match pattern, bad date
  else
  {
    //split date into month, day, year
    var arrayDate = strValue.split(RegExp.$1);
    var intDay = parseInt(arrayDate[1],10); 
    var intYear = parseInt(arrayDate[2],10);
    var intMonth = parseInt(arrayDate[0],10);
 
    //check for valid month
    if (intMonth > 12 || intMonth < 1)
      return false;
 
    //create a lookup for months not equal to Feb.
    var arrayLookup = 
        {'01' : 31, '03' : 31, '04' : 30, '05' : 31,
        '06' : 30, '07' : 31, '08' : 31, '09' : 30,
        '10' : 31, '11' : 30, '12' : 31};
  
    //check if month value and day value agree
    if (arrayLookup[arrayDate[0]] != null)
      if (intDay <= arrayLookup[arrayDate[0]] && intDay != 0)
        return true; //found in lookup table, good date
  
    //check for February
    var booLeapYear = (intYear % 4 == 0
        && (intYear % 100 != 0 || intYear % 400 == 0));
    if (((booLeapYear && intDay <= 29) || (!booLeapYear && intDay <= 28)) 
        && intDay !=0)
      return true; //Feb. had valid number of days
  }
  return false; //any other values, bad date
}
 
function validateValue(strValue, strMatchPattern)
{
/************************************************
DESCRIPTION: Validates that a string a matches
  a valid regular expression value.
    
PARAMETERS:
   strValue - String to be tested for validity
   strMatchPattern - String containing a valid
      regular expression match pattern.
      
RETURNS:
   True if valid, otherwise false.
*************************************************/
  var objRegExp = new RegExp(strMatchPattern);
 
  //check if string matches pattern
  return objRegExp.test(strValue);
}
 
function rightTrim(strValue)
{
/************************************************
DESCRIPTION: Trims trailing whitespace chars.
    
PARAMETERS:
   strValue - String to be trimmed.  
      
RETURNS:
   Source string with right whitespaces removed.
*************************************************/
  var objRegExp = /^([\w\W]*)(\b\s*)$/;
 
  if (objRegExp.test(strValue))
  {
    //remove trailing a whitespace characters
    strValue = strValue.replace(objRegExp, '$1');
  }
  return strValue;
}
 
function leftTrim(strValue)
{
/************************************************
DESCRIPTION: Trims leading whitespace chars.
    
PARAMETERS:
   strValue - String to be trimmed
   
RETURNS:
   Source string with left whitespaces removed.
*************************************************/
  var objRegExp = /^(\s*)(\b[\w\W]*)$/;
 
  if (objRegExp.test(strValue))
  {
    //remove leading a whitespace characters
    strValue = strValue.replace(objRegExp, '$2');
  }
  return strValue;
}
 
function trimAll(strValue)
{
/************************************************
DESCRIPTION: Removes leading and trailing spaces.
 
PARAMETERS: Source string from which spaces will
  be removed;
 
RETURNS: Source string with whitespaces removed.
*************************************************/ 
  var objRegExp = /^(\s*)$/;
 
  //check for all spaces
  if (objRegExp.test(strValue))
  {
    strValue = strValue.replace(objRegExp, '');
    if (strValue.length == 0)
      return strValue;
  }
    
  //check for leading & trailing spaces
  objRegExp = /^(\s*)([\W\w]*)(\b\s*$)/;
  if (objRegExp.test(strValue))
  {
    //remove leading and trailing whitespace characters
    strValue = strValue.replace(objRegExp, '$2');
  }
  return strValue;
}
 
function removeCurrency(strValue)
{
/************************************************
DESCRIPTION: Removes currency formatting from 
  source string.
  
PARAMETERS: 
  strValue - Source string from which currency formatting
     will be removed;
 
RETURNS: Source string with commas removed.
*************************************************/
  var objRegExp = /\(/;
  var strMinus = '';
 
  //check if negative
  if (objRegExp.test(strValue))
    strMinus = '-';
  
  objRegExp = /\)|\(|[,]/g;
  strValue = strValue.replace(objRegExp, '');
  if (strValue.indexOf('$') >= 0)
    strValue = strValue.substring(1, strValue.length);
  return strMinus + strValue;
}
 
function addCurrency(strValue)
{
/************************************************
DESCRIPTION: Formats a number as currency.
 
PARAMETERS: 
  strValue - Source string to be formatted
 
REMARKS: Assumes number passed is a valid 
  numeric value in the rounded to 2 decimal 
  places.  If not, returns original value.
*************************************************/
  var objRegExp = /-?[0-9]+\.[0-9]{2}$/;
   
  if (objRegExp.test(strValue))
  {
    objRegExp.compile('^-');
    strValue = addCommas(strValue);
    if (objRegExp.test(strValue))
      strValue = '($' + strValue.replace(objRegExp, '') + ')';
    else
      strValue = '$' + strValue;
    return  strValue;
  }
  else
    return strValue;
}
 
function removeCommas(strValue)
{
/************************************************
DESCRIPTION: Removes commas from source string.
 
PARAMETERS: 
  strValue - Source string from which commas will 
    be removed;
 
RETURNS: Source string with commas removed.
*************************************************/
  var objRegExp = /,/g; //search for commas globally
 
  //replace all matches with empty strings
  return strValue.replace(objRegExp, '');
}
 
function addCommas(strValue)
{
/************************************************
DESCRIPTION: Inserts commas into numeric string.
 
PARAMETERS: 
  strValue - source string containing commas.
  
RETURNS: String modified with comma grouping if
  source was all numeric, otherwise source is 
  returned.
  
REMARKS: Used with integers or numbers with
  2 or less decimal places.
*************************************************/
  var objRegExp = new RegExp('(-?[0-9]+)([0-9]{3})'); 
 
  //check for match to search criteria
  while (objRegExp.test(strValue))
  {
    //replace original string with first group match, 
    //a comma, then second group match
    strValue = strValue.replace(objRegExp, '$1,$2');
  }
  return strValue;
}
 
function removeCharacters(strValue, strMatchPattern)
{
/************************************************
DESCRIPTION: Removes characters from a source string
  based upon matches of the supplied pattern.
 
PARAMETERS: 
  strValue - source string containing number.
  
RETURNS: String modified with characters
  matching search pattern removed
  
USAGE:
  strNoSpaces = removeCharacters(' sfdf  dfd', '\s*')
*************************************************/
  var objRegExp = new RegExp(strMatchPattern, 'gi');
 
 //replace passed pattern matches with blanks
  return strValue.replace(objRegExp, '');
}
