Vermont Validation js

From PikaDocs

External javascript file /js/validation.js as used in Vermont

  • Update 2007/2/9 now can show ambiguous field names as more friendly names - see translation code near line 54
  • Update 2006/10/5 to prevent entry of negative hours
  • Update 2006/9/7 to have warnHoursPerSlip and maxHoursPerSlip
  • Update 2006/8/9 to validate textarea fields elig_notes and estimate_notes
  • previous versions - 2006/2/15, 2006/3/3

-Andrew Cameron




// Declare some Global variables here
var dtCh= "/";
var warnHoursPerSlip = 7.5;                      // warn if over # of hours on any one activity record
var maxHoursPerSlip = 99.99;                      // cannot enter more hours than this per activity record
var minActYear; var maxActYear;
var maxDOBYear; var minDOBYear;
var minAge = 1;
var maxAge = 120;
var lengthElig_Notes = 150;           // the size of the character field elig_notes in your cases table 
var lengthEstimate_Notes = 254;           // the size of the character field estimate_notes in your cases table 

// Initialize other global variables
function pk_initVars ()
{
var today = new Date();
minActYear = (today.getFullYear()-1);           // lowest year value for activity record
maxActYear = (minActYear + 2);              // highest year value for activity record
maxDOBYear = today.getFullYear();           // highest year value for DOB
minDOBYear = (today.getFullYear() - 120);              // lowest year value for DOB
// oldest case in our system is 1982 so don't allow open date earlier than that
minOpenYear = 1982;
maxOpenYear = today.getFullYear();
minCloseYear = minOpenYear;
maxCloseYear = maxOpenYear;
}


function pk_validate(obForm,szFields)
    {
      /* Comprehensive submit-time validation function for Pika 
         Calls other functions to validate specific types of data 
         First parameter is form name
         Second parameter is list of required fields in a string comma separated. 
         E.G.:   onSubmit="return pk_validate(ea,'act_date,user_id,hours,funding');"
      */
    
    validForm = true;
    // if we were passed any required fields
    // make sure all required fields are filled in
    if (szFields&&szFields!='') {                // if the variable is null or if the list is blank, there are no required fields
        var fields = szFields.split(",")
        var szMissing= new Array();
        for (x=0;x<fields.length;x++) {
            if (obForm.elements[fields[x]].value.length==0) {
                szMissing[szMissing.length]=new String(fields[x]);
            }
        }
        
        // New Addition Andrew 2007/2/9
        // translate ambiguous field names into user-recognized field names
        for (i=0;i<szMissing.length;i++) {
          if (szMissing[i]=='category')
            szMissing[i]='Type of Activity';
        }
        
        if (szMissing.length) {       
            alert("The field"+((szMissing.length>1)?"s ":" ")+szMissing.join(",")+" must be filled in first");
            validForm = false;
        } else {                      // all required fields have a value in them
            validForm = true;       // so, the form is valid so far
        }
      } else {               // we were not passed any fields to be required
          validForm = true;     // so, the form is valid so far
      }
        
    // Now validate the data in all fields to make sure it is appropriate
    
    // first initialize some global variables
       
    pk_initVars(); 
    
    // if the field ssn exists on the form
    // then call the validation function for SSN, and AND the result of that function (true/false) with the 
    // existing value of validForm (also true/false, set up above based on required fields)
    // at the end of the entire pk_validate function we'll have a true or false value to return to the form.
    if (obForm.ssn)
      validForm = (pk_SSNValidation(obForm.ssn.value)&&validForm);
    
    // validate other fields using the same process
    
    // some functions want the object passed, like pk_checkTime()
    // some want the value passed like pk_isDate()
    //alert (validForm);
    if (obForm.act_time)
      validForm = (pk_checkTime(obForm.act_time)&&validForm);
    if (obForm.hours)
      validForm = (pk_checkHours(obForm.hours.value)&&validForm);
    if (obForm.act_date)
      validForm = (pk_isDate(obForm.act_date.value,minActYear,maxActYear)&&validForm);
    if (obForm.birth_date)
      validForm = (pk_isDate(obForm.birth_date.value,minDOBYear,maxDOBYear)&&validForm);
    if (obForm.open_date)
      validForm = (pk_isDate(obForm.open_date.value,minOpenYear,maxOpenYear)&&validForm);
    if (obForm.close_date)
      validForm = (pk_isDate(obForm.close_date.value,minCloseYear,maxCloseYear)&&validForm);
    if (obForm.email)
      validForm = (pk_checkEmail(obForm.email.value)&&validForm);
    if (obForm.client_age)
      validForm = (pk_checkAge(obForm.client_age.value)&&validForm);
    if (obForm.elig_notes)
      validForm = (pk_checkElig_Notes(obForm.elig_notes.value)&&validForm);
    if (obForm.estimate_notes)
      validForm = (pk_checkEstimate_Notes(obForm.estimate_notes.value)&&validForm);
    
    // zip code validation? The contacts table in Pika permits 15 chars for zip code. 
    // have to handle the 5+4 zip codes
    
    return validForm;
    }


function pk_checkElig_Notes (val) {             // see if the elig_notes field has more than allowed characters
  if (val.length==0)            // don't validate an empty field
    return true;
  // first call a function to fix the newlines for MySQL type counting
  val = pk_fixnewlines_textarea (val);
  // now check the field length
  if (val.length > lengthElig_Notes)
    {
      alert('Sorry, the Eligibility Notes field only allows ' + lengthElig_Notes + 
            ' characters, and it currently has ' + val.length + 
            ' characters. Please remove ' + (val.length - lengthElig_Notes) + ' characters.' +
            ' A Return or Enter counts as 2 characters.');
      return false; 
   }
 else
   return true; 
}


function pk_checkEstimate_Notes (val) {             // see if the estimate_notes field has more than allowed characters
  if (val.length==0)            // don't validate an empty field
    return true;
  val = pk_fixnewlines_textarea (val);
  if (val.length > lengthEstimate_Notes)
    {
      alert('Sorry, the Matter Comments or Estimate Notes field only allows ' + lengthEstimate_Notes + 
            ' characters, and it currently has ' + val.length + 
            ' characters. Please remove ' + (val.length - lengthEstimate_Notes) + ' characters.' +
            ' A Return or Enter counts as 2 characters.');
      return false; 
   }
 else
   return true; 
}


function pk_fixnewlines_textarea (val) {             
  // Adjust newlines so can do correct character counting for MySQL. MySQL counts a newline as 2 characters.
  if (val.indexOf('\r\n')!=-1)
    ; // this is IE on windows. Puts both characters for a newline, just what MySQL does. No need to alter
  else if (val.indexOf('\r')!=-1)
    val = val.replace ( /\r/g, "\r\n" );        // this is IE on a Mac. Need to add the line feed
  else if (val.indexOf('\n')!=-1)
    val = val.replace ( /\n/g, "\r\n" );        // this is Firefox on any platform. Need to add carriage return
  else 
    ;                                           // no newlines in the textarea
  return val;
}


function pk_checkAge (val) {
    if (val.length==0)            // don't validate an empty field
        return true;
    if (val<minAge) {
        alert("Age is too low");
        return false;
      }
      if (val>maxAge) {
        alert("Age is too high");
        return false;
      }
}


/**
 * DHTML email validation script. Courtesy of SmartWebby.com (http://www.smartwebby.com/dhtml/)
 */
// re-titled by Andrew and also changed error message a bit
function pk_checkEmail(str) {
        if (str.length==0)  // if the field is empty don't try to validate it any more.
            return true;

		var at="@"
		var dot="."
		var lat=str.indexOf(at)
		var lstr=str.length
		var ldot=str.indexOf(dot)
		if (str.indexOf(at)==-1){
		   alert("Please correct the Email address")
		   return false
		}

		if (str.indexOf(at)==-1 || str.indexOf(at)==0 || str.indexOf(at)==lstr){
		   alert("Please correct the Email address")
		   return false
		}

		if (str.indexOf(dot)==-1 || str.indexOf(dot)==0 || str.indexOf(dot)==lstr){
		    alert("Please correct the Email address")
		    return false
		}

		 if (str.indexOf(at,(lat+1))!=-1){
		    alert("Please correct the Email address")
		    return false
		 }

		 if (str.substring(lat-1,lat)==dot || str.substring(lat+1,lat+2)==dot){
		    alert("Please correct the Email address")
		    return false
		 }

		 if (str.indexOf(dot,(lat+2))==-1){
		    alert("Please correct the Email address")
		    return false
		 }
		
		 if (str.indexOf(" ")!=-1){
		    alert("Please correct the Email address")
		    return false
		 }

 		 return true					
	}

/*
function pk_checkActDate(act_date){
	if (isDate(act_date.value)==false){
        return false;
	}
    return true
 }
*/

function pk_checkHours(hours)
{
  if (!hours)           // if there is no value, the field is blank, so don't try to validate it
    return true;
  // code here prevents entering more than maxHoursPerSlip
  if (hours > maxHoursPerSlip) {
    alert("You are not allowed to enter more than "+maxHoursPerSlip+" hours of time per entry. If you need to enter more time, please enter more than 1 time slip.");
    return false;
  }
  // per feedback from advocates, add a new part to just warn the user but still allow that many hours
  // Andrew Cameron 2006/6/5
  if (hours > warnHoursPerSlip) {
    var answer = confirm ("You entered more than "+warnHoursPerSlip+" hours of time. This could be a typo. Click OK if you are sure. Click Cancel if it was a mistake. ")
    if (answer)
        return true;
    else
        return false;
  }
  // Andrew Cameron 2006/10/5 don't allow negative hours
  if (hours < 0) {
    alert("Negative hours are not permitted");
    return false;
  }
  return true;      // otherwise the hours must have been OK
  // TODO: need to add some logic here to only allow numbers and one decimal point, no characters
}


function pk_SSNValidation(ssn) {
if (ssn.length==0)  // if the field is empty don't try to validate it any more.
    return true;

var matchArr = ssn.match(/^(\d{3})-?\d{2}-?\d{4}$/);
var numDashes = ssn.split('-').length - 1;
if (matchArr == null || numDashes == 1) {
    alert('Invalid SSN. Must be 9 digits or in the form NNN-NN-NNNN.');
    return false;
}
else if (parseInt(matchArr[1],10)==0) {
        alert("Invalid SSN: SSN's can't start with 000.");
        return false;
}
else 
    return true;
}  // end SSNValidation


String.prototype.trim = function () {
    return this.replace(/^\s*/, "").replace(/\s*$/, "");

 }



/**
 * Mark added for basic date validation Activity screens etc.
 * DHTML date validation script. Courtesy of SmartWebby.com (http://www.smartwebby.com/dhtml/)
 */

function isInteger(s){
	var i;
    for (i = 0; i < s.length; i++){   
        // Check that current character is number.
        var c = s.charAt(i);
        if (((c < "0") || (c > "9"))) return false;
    }
    // All characters are numbers.
    return true;
}

function stripCharsInBag(s, bag){
	var i;
    var returnString = "";
    // Search through string's characters one by one.
    // If character is not in bag, append to returnString.
    for (i = 0; i < s.length; i++){   
        var c = s.charAt(i);
        if (bag.indexOf(c) == -1) returnString += c;
    }
    return returnString;
}

function daysInFebruary (year){
	// February has 29 days in any year evenly divisible by four,
    // EXCEPT for centurial years which are not also divisible by 400.
    return (((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28 );
}

function DaysArray(n) {
	for (var i = 1; i <= n; i++) {
		this[i] = 31
		if (i==4 || i==6 || i==9 || i==11) {this[i] = 30}
		if (i==2) {this[i] = 29}
   } 
   return this
}


function pk_isDate(dtStr,minYear,maxYear){
    if (dtStr.length==0)  // if the field is empty don't try to validate it any more.
        return true;
    var daysInMonth = DaysArray(12)
	var pos1=dtStr.indexOf(dtCh)
	var pos2=dtStr.indexOf(dtCh,pos1+1)
	var strMonth=dtStr.substring(0,pos1)
	var strDay=dtStr.substring(pos1+1,pos2)
	var strYear=dtStr.substring(pos2+1)
	strYr=strYear
	if (strDay.charAt(0)=="0" && strDay.length>1) strDay=strDay.substring(1)
	if (strMonth.charAt(0)=="0" && strMonth.length>1) strMonth=strMonth.substring(1)
	for (var i = 1; i <= 3; i++) {
		if (strYr.charAt(0)=="0" && strYr.length>1) strYr=strYr.substring(1)
	}
	month=parseInt(strMonth)
	day=parseInt(strDay)
	year=parseInt(strYr)
	if (pos1==-1 || pos2==-1){
		alert("The date format should be : mm/dd/yyyy")
		return false
	}
	if (strMonth.length<1 || month<1 || month>12){
		alert("Please enter a valid month")
		return false
	}
	if (strDay.length<1 || day<1 || day>31 || (month==2 && day>daysInFebruary(year)) || day > daysInMonth[month]){
		alert("Please enter a valid day")
		return false
	}
	if (strYear.length != 4 || year==0 || year<minYear || year>maxYear){
		alert("Please enter a valid 4 digit year between "+minYear+" and "+maxYear)
		return false
	}
	if (dtStr.indexOf(dtCh,pos2+1)!=-1 || isInteger(stripCharsInBag(dtStr, dtCh))==false){
		alert("Please enter a valid date")
		return false
	}
return true
}


function pk_checkTime(time)
{ 
var errorMsg = "";
// regular expression to match required time format  
//re = /^(\d{1,2}):(\d{2})(:00)?( )([ap]m)?$/;
  re = /^(\d{1,2}):(\d{2})( [apAP][mM])?$/;

if (time.value.length==0)  // if the field is empty don't try to validate it any more.
    return true;

if(time.value != '') { 
    if(regs = time.value.match(re)) { 
        if(regs[3]) {
        // 12-hour time format with am/pm 
            if(regs[1] < 1 || regs[1] > 12) {
                errorMsg = "Invalid value for hours: " + regs[1];
            }
        } else {  // 24-hour time format 
            if(regs[1] > 23) { 
                errorMsg = "Invalid value for hours: " + regs[1];
            } 
        }
        
        if(!errorMsg && regs[2] > 59) {
            errorMsg = "Invalid value for minutes: " + regs[2];
        } 
    } else {
        errorMsg = "Invalid time format: " + time.value;
    }
} 

if(errorMsg != "") { 
    alert(errorMsg);  
    return false; } 
return true;

} // end pk_checkTime function