/*
FORM VALIDATION SCRIPT
RELEASE / USAGE NOTES
author: john mcgaraghan

version 1.0 released 7.31.02 (alpha)
version 1.1 released 8.04.02 (beta)
version 1.2 released 8.13.02 (stable)
version 2.0 released 3.29.04 (alpha)

Version 2.0 introduces a new "is-ies" based validation method.
basic setup remains the same with additional features described below.
passing of 2nd arg to formVal for email address validation is deprecated 
but still supported.  it may be removed from future releases.

v2.0:
document's <form> declaration tag should have an onSubmit parameter formatted as follows:
    onSubmit="return formVal(this);
if email type validation is desired on a field (e.g. emlField), then the proper "is-ie" 
should be declared in the reqFields array as follows:
var ReqFields=new Array(
  Array("emlField","Email Address","isEmail")
);

v1.2 back support:
document's <form> declaration tag should have an onSubmit parameter formatted as follows:
    onSubmit="return formVal(this, this.emailfield.value);
where "emailfield" is the name of the form input field for an email address
if the second argument is not passed, no validation will be done on email.

Select boxes should have a default "Select One" options at index 0 (with value="").
support for textarea field types is not present at this time.

support for simple/verbose error reporting added 8.13.02
support for checkboxes and radio buttons added 8.13.02
  --checks to see if one of a group of like named radio buttons is selected
  --checks to see if the designated check box is actually checked 

methodology for validating elements overhauled (including variable type validation) 3.29.04 
support for use of typed error labels reporting added 3.29.04 
errOverRide implementation updated (full override allowed) 3.29.04 
reEml (email validation regular expression) updated to one written by Tom Malaher 12.27.04 
*/

// set to true (or override explicitly in pages) for verbose error reporting
verbose=true;

// set to true (or override explicitly in pages) for addition of type-dependent error messages
typelabels=true;

/*
populate an array like this with arrays of 'FieldName','ErrorLabel' pairs in the html 
file that calls this script in this way, you may use this single file to validate 
forms on different pages.  the 'FieldName','ErrorLabel' pairs can be followed by a
list of optional "is-ies" for specific data validation.  in the absence of an optional
"is-ie", only notBlank will be run on the value of the indicated field 

var reqFields=new Array(
  Array ('EmailAddress','Email Address'[,isEmail[,notBlank]]),
  Array ('PostalCode','Zip Code')
);

*/
var errOverRide; // set a value in your html page (after the inclusion of this file) to override the default error messaging
function formVal(f, eml)  {
var err=new Array();
  // loop over required fields
  for(i=0;i<reqFields.length;i++)  {
    // load value from selected form element -- checkboxes and radios return return 'checked' or empty
    var fieldVal=getValue(f,reqFields[i][0]);
    // if the current field has no custom validation requirements declared, add notBlank 
    reqFields[i][2] = (reqFields[i].length<3 ? "notBlank" : reqFields[i][2]);
    // run each designated custom validation requirement against the current form field value
    for(j=2;j<reqFields[i].length;j++) {
      if(eval("!"+reqFields[i][j]+"('"+fieldVal.replace("'","\\'")+"');")) {
        err.push(reqFields[i][1]+(typelabels?" "+errorLabels[reqFields[i][j]]:""));
      }
    }
  }
  // prepare and report errors
  if(err.length>0)  {
    var errText="";
    if(verbose) {
      if(!errOverRide) {
        errBase="You are missing required information.\nPlease provide information for the following fields:";
      } else {
        errBase=errOverRide;
      }
      errText=errBase + "\n  -" + err.join(",\n  -");
    } else {
      errText="There were problems with your form submission.\nPlease check your information and try again";
    }
    alert(errText);
    return false;
  }
  return (eml?emailVal(eml):true);
}

function getValue(f,fn) {
  // return value of selected option if field type is select
  if(eval("f."+fn+".type") && eval("f."+fn+".type.indexOf('elect')>0")) {
    return eval("f."+fn+".options[f."+fn+".options.selectedIndex].value");

  // return 'checked' or '' if field type is checkbox
  } else if(eval("f."+fn+".type") && eval("f."+fn+".type.indexOf('heckbox')>0")) {
    return (eval("!f."+fn+".checked")?"checked":"");

  // return 'checked' or '' if field type is radio
  } else if(eval("f."+fn+"[0]") && eval("f."+fn+"[0].type.indexOf('adio')>0")) {
    var radioElements=eval("f."+fn+".length");
    var radioChecked=false;
    for(n=0;n<radioElements;n++)   {
      if(eval("f."+fn+"["+n+"].checked==true")) {
        return "checked";
        break;
      }
    }
    if(!radioChecked) {
      return "";
    }
    radioChecked=false;

  // return value in input fields
  } else {
    return eval("f."+fn+".value");
  }
}

//email validation for v1.2 support
//reEML = /\S*@.\S*\..\S*/
// TOM MALAHER's Email Validation RegEx
reEML = /^[_A-Za-z0-9-]+[._A-Za-z0-9-]*@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(\.[A-Za-z]{2,5})$/
function emailVal(val) {
  OK = reEML.test(val);
  if (OK != true) {
    alert("Please make sure your email address is in the format yourname@company.com.");
    return false;
  } else {
    return true;
  }
}

/******************************************/
//         THE "IS-IE" FUNCTIONS          //
/******************************************/

function isEmail(val) {
  return reEML.test(val);
}

function isNum(val) {
  return !isNaN(val);
}

function isInt(val) {
  return parseInt(val) == val;
}

//  check to see that input value contains no more than the specified number of numberic and non-numeric characters
function NumsChars(val,numLn,charLn) {
  var numnum=0;                        //  number of numeric characters
  var numchar=0;                       //  number of non-numeric characters
  
}

function isUSPhone(val) {
  var numnum=0;                        //  number of numeric characters
  var numchar=0;                       //  number of non-numeric characters
  if((ln=val.length) < 10) {
    return false;                      //  error out if not at least 10 characters
  }
  for(i=0;i<ln;i++) {                  //  loop over the characters of the input value
    isInt(val[i])?++numnum:++numchar;
    if(numnum > 10 || numchar > 4) {
      return false;
    }
  }
  return numnum < 10;                  //  return
}

function notBlank(val) {
  return val!="";
}

function isVal(val) {

}
function notVal(val) {

}


// error reporting labels specific to the is-ies
var errorLabels = new Array();
errorLabels["isEmail"]="must be an email address";
errorLabels["isNum"]="must be a number";
errorLabels["isInt"]="must be an integer";
errorLabels["isUSPhone"]="must be a US phone number (nnn-nnn-nnnn)";
errorLabels["notBlank"]="is a required field";


