/* File validate.js - library of simple validation functions
	This library uses Regular Expressions for pattern matching.
	See isValidEmail() for example.
	---------------------------------------------------------------
	February 25, 2001
	- Another minor change to isCheckedRadio	
	  works more reliably in both NS & IE
	---------------------------------------------------------------
	November 16, 2000
	  - drop .select method due to inconsistencies between
	    IE and NS (IE does not overwrite selection properly)
	  - fixed isCheckedRadio() - now works in both IE and NS  
	November 14, 2000
	 - updated stripWhiteSpace() [uses regular expressions]
	 - updated isNotBlank (calls stripWhiteSpace() before test)
	
   August 8, 2000
    - better documentation for isSelected()
	  - disabled obj.select in isSelected() - broke in IE
    - minor additions to documentation
    - identified functions not suitable for wrap-around routines
    - identified functions suitable only for wrap-around routines
    July 22, 2000
   Added stripNonDigits()
   Added isValidPostal() Codes
   --------------------------------------------------------------
   Usage: in the <HEAD> section of your HTML document
   <SCRIPT LANGUAGE="JavaScript" SRC="validate.js">
     document.write("warning - unable to locate included 'js' file")
   </SCRIPT>
   --------------------------------------------------------------
   WARNING - WARNING - WARNING - WARNING - WARNING 
   It is essential that all validation functions
  	return 'false' if the test fails  (yields undesirable results)
  	return 'true'  if the test passes (yields the desired results)
   ===================================================================
   This library is used updated versions of the validation functions
   that rely on receiving objects, and uses the properties of the objects
   such as .value, .name, form 
   ... description ends and the useful part of the file begins ... 	
*/
<!-- the following will be invisible to browsers that do not support JavaScript

//==============================================================
// Function: isNotBlank
// Purpose:  to check the the input is NOT blank
// general purpose function to see if an input value has been entered at all
// 	returns false if the input IS blank
// 	usage: <INPUT NAME="someField" VALUE="someValue" onChange="isNotBlank(this)">
//	this function superceds isBlank() included at the end of this file
//	for reference (better logic and consistent language)
//	 - desired result returns true
//	 - undesired result returns false
// general purpose function to see if an input value has been entered at all
function isNotBlank(obj) {
    var str 	= obj.value ; // value to be 'tested' 
    var name 	= obj.name  ; // name of the field	
    var errMsg	= "Please enter something for " +name + ".\n Required entry"
    // remove WhiteSpace characters
    str = stripWhiteSpace(str);
    if (str == "" || str == null) {
        alert(errMsg) ; // tell the user what is wrong
        obj.focus()   ; // focus on the field with the problem
        //obj.select()  ; // select the contents of the field with the problem
        return false  ; // tell wrap around function that this value fails
    }
    return true       ; // tell wrap around function that this value passes
}
//==============================================================
// Function: isNumRange
// Purpose: to check that input is within the not blank, and is numeric
//          and withing a specified range
// Usage: <INPUT NAME="someField" VALUE="someValue" onChange="isNumRange(this,0,300)">
//	this assumes that minimum acceptable is 0 and maximum acceptable is 300
function isNumRange(obj, min, max){
    var str 	= obj.value ; // value to be 'tested' 
    var name 	= obj.name  ; // name of the field	
    var errMsg	= "Please enter a number between " + min + " and "+ max
    	errMsg +="\nfor " + name + ". (Required entry)" ;
    	errMsg +="\nYou entered \"" + str +"\"." ;
// check for blank field
        if (str==""){
          alert(errMsg) ; // tell the user what is wrong
          obj.focus()   ; // focus on the field with the problem
 //        obj.select()  ; // select the contents of the field with the problem
          return false  ; // tell wrap around function that this value fails
        }
// check for non-digits
        for (var i=0; i < str.length; i++){  
        var ch = str.charAt(i)
        if (ch < "0" || ch > "9"){       
       	 alert(errMsg) ; // tell the user what is wrong
          obj.focus()   ; // focus on the field with the problem
//          obj.select()  ; // select the contents of the field with the problem
          return false  ; // tell wrap around function that this value fails
         }
        }
// check if within range 
	var val = parseInt(str, 10)
	if ((val < min) || (val > max)) {
          alert(errMsg) ; // tell the user what is wrong
          obj.focus()   ; // focus on the field with the problem
//          obj.select()  ; // select the contents of the field with the problem
          return false  ; // tell wrap around function that this value fails
	 }
    return true         ; // tell wrap around function that this value passes
}

//=========================================================
// Function: isValidEmail(obj)
// Description : Checks if given email address has valid syntax
// usage: <INPUT TYPE="TEXT" NAME="e-mail" onChange="isValidEmail(this)" >
// note: Validation assumptions 
//   E-mail address has an "@" symbol in it. 
//     and at least one alphanumeric character before the "@" symbol. 
//     and either a two-letter country code or a .com, .net, .edu, .mil, .gov or .org suffix 

function isValidEmail (obj){
    var str 	= obj.value ; // value to be 'tested' 
    var name 	= obj.name  ; // name of the field	
    var errMsg	= "Please enter your valid email address." 
    	  errMsg +="\nfor " + name + ". (Required entry)" ;
    	  errMsg +="\nYou entered \"" + str +"\"." ;    	  
   var newString = str.match(/\b(^(\S+@).+((\.com)|(\.net)|(\.edu)|(\.mil)|(\.gov)|(\.org)|(\..{2,2}))$)\b/gi);
   if (!newString){  
   	alert(errMsg) ; // tell the user what is wrong
   	obj.focus()   ; // focus on the field with the problem
//		obj.select()  ; // select the contents of the field with the problem
		return false  ; // tell wrap around function that this value fails
   }
    return true     ; // tell wrap around function that this value passes
}

// === documentation for new version of isValidEmail =====
/*	comments to explain the new version - 
	in a production environment you can remove all
   of the comments as the functional part follows 
	The next 2 lines using a regular expression  
	replace the 9 that follow them
------- new code using a regular expression ------------
   var newString = str.match(/\b(^(\S+@).+((\.com)|(\.net)|(\.edu)|(\.mil)|(\.gov)|(\.org)|(\..{2,2}))$)\b/gi);
   if (!newString){  
------- this (down to the next dotted line -------------
	var atSign  	= str.indexOf('@') 	//locate position of '@' sign
	var dot 		  	= str.lastIndexOf('.')	// locate position of dot
	var blank    	= str.indexOf(' ')  	// locate position of blanks (shouldn't be any)
	var length   	= str.length - 1    	// define array is from 0 to length-1
if ((atSign < 1)      ||   // '@' must not be first character
    (dot <= atSign+1) ||   // must be at least one valid character between '@' and '.'
    (dot == length)   ||   // is the dot the last character (not valid if true)
    (blank  != -1)         // No empty spaces permitted
   ){
--------------------------------------------------------   
Notes about the regular expression:
/\b(^(\S+@).+((\.com)|(\.net)|(\.edu)|(\.mil)|(\.gov)|(\.org)|(\..{2,2}))$)\b/gi
/	=begin regular expression
\b =word boundary 
^	=beginning of the string
\S	=no spaces
+@	=contains an @ sign
(\.com)|(\.net)|(\.edu) = list of endings acceptable done with $)\b
/gi=global, case insensitive
see:
http://developer.netscape.com:80/viewsource/angus_strings.html 
http://developer.netscape.com:80/docs/manuals/communicator/jsguide/regexp.htm
*/

//=========================================================
// Function: isValidPhone(obj)
// Description : verifies that obj.value is a telephone
// number (ten digits - with or without parentheses and dashes)
// usage: <INPUT TYPE="TEXT" NAME="Telephone" onChange="isValidPhone(this)" >
// note: updated July 2000 
// strips all non numerics and then tests for 10 digits
function isValidPhone(obj) {
    var re = /^\d{10}$/   ; // must be 10 digits
    var str 	= obj.value ; // value to be 'tested'
    var name 	= obj.name  ; // name of the field	
    var errMsg	= "Please enter your Telephone Number." 
    	  errMsg +="\nin  " + name + ". (Required entry)" ;
    	  errMsg +="\nYou entered \"" + str +"\"." ;    	  
    	  errMsg +="\ntry a pattern like " ;
    	  errMsg +="\n999 999 9999 (10 digits - includes area code)";  
    str = str.replace(/[^0-9]/g,"") ; // remove all non digits before testing
    RegExp.input =str ; // aka RegExp.input
    var newString = str.match(re);
    if (!newString){ 	; // if not OK then the test fails
      alert(errMsg) 	; // tell the user what is wrong
	   	obj.focus()   	; // focus on the field with the problem
	//	obj.select()  	; // select the contents of the field with the problem
			return false  	; // tell wrap around function that this value fails
	   }
			obj.value = str ;//  write the value back (digits only)      
	    return true     ; // tell wrap around function that this value passes
	}

//=========================================================
// Function: isSelectedRange(obj,min,max)
// Description : Checks if number of items selected is within a range 
// usage: <SELECT NAME="Fruit" onChange="isSelectedRange(this,1,3)" >
// obj.length is the number options
// obj.options.[i].selected is the state of option[i] in obj
function isSelectedRange(obj,min,max){
	var name 	= obj.name  ; // name of the field	
	var errMsg	= "Please select between " + min + " and " + max + " items" 
    	 errMsg += "\nfor  " + name + "." ;
    	 	var selectedCount=0
   for (var i=0; i < obj.options.length; i++) {
      if (obj.options[i].selected==true)
         selectedCount++
   }
   	// alert(selectedCount + " items selected")
   	if (selectedCount < min || selectedCount > max )
	{
   	errMsg += "\nYou have selected " + selectedCount + " item(s)." ;
   	alert(errMsg) ; // tell the user what is wrong
   	obj.focus()   ; // focus on the field with the problem
	//obj.select()  ; // select the contents of the field with the problem
		return false  ; // tell wrap around function that this value fails
   }
    return true     ; // tell wrap around function that this value passes
}

//=========================================================
// Function: isSelected(obj) <- this is buggy - use the function above
// usage: <SELECT NAME="Fruit" onChange="isSelectedRange(this,1,2)" >
// Description : Checks if number of items selected is within a range 
// usage: <SELECT NAME="Fruit" onChange="isSelected(this)" >
// this one is tricky as we have to cycle through all the options
// checking to see if something is selected, 
// and then if it is, we can read the value and if that is null
// then we know that the default selection (which should have
// a null ("") value is selected i.e. our user has made no
// selection.
// note: you must include the 'value=' parameter inside the option tag
// 	in order for this function to work.
// e.g.
/*
	<SELECT NAME="Time" >
		<OPTION value="">-Select a Time-
 	 	<OPTION value="5:00 pm">5:00 pm</OPTION>
 	 	<OPTION value="5:30 pm">5:30 pm</OPTION>
 	 	<OPTION value="6:00 pm">6:00 pm</OPTION>
 	 	<OPTION value="6:30 pm">6:30 pm</OPTION>
 	 	<OPTION value="7:00 pm">7:00 pm</OPTION>
 	 	<OPTION value="7:30 pm">7:30 pm</OPTION>
 	 	<OPTION value="8:00 pm">8:00 pm</OPTION>
 	 	<OPTION value="8:30 pm">8:30 pm</OPTION>
 	 	<OPTION value="9:00 pm">9:00 pm</OPTION>
	</SELECT>
*/
// obj.length is the number of options
// obj.options.[i].selected is the state of option[i] in obj
function isSelected(obj){
	var name 	= obj.name  ; // name of the field	
	var testValue = false  ; // flag
	var errMsg	= "Please select something from the list for" 
    	 errMsg += "\n  " + name + "." ;
    	 	var selectedCount=0
   for (var i=0; i < obj.options.length; i++) {
      if (obj[i].selected){
           if(obj[i].value != ""){
         		testValue=true   			}
   		}	
   }
   	// alert(selectedCount + " items selected")
   	if (testValue==false){
   	  	errMsg += "\nYou have selected " + selectedCount + " item(s)." ;
   		alert(errMsg) ; // tell the user what is wrong
   		obj.focus()   ; // focus on the field with the problem
		//obj.select()  ; // select the contents of the field with the problem
			return false  ; // tell wrap around function that this value fails
   }
    return true     ; // tell wrap around function that this value passes
}

//=========================================================
// Function: isPasswordOk(obj)
// Description : Uses JavaScript prompt to verify original password entry
// usage: <INPUT TYPE="PASSWORD" NAME="Password" onChange="isPasswordOk(this)" >
// note: this function is really just an example
//       : the prompt box cannot hide the input (ie password style)
//       : so in reality - you would not use this for passwords
//       : but could still use it for something like email
//       : where you want the use to double check their input
//       : for a field.
// note: you cannot use this in a wrap-around function (ie in an onSubmit routine)
function isPasswordOk(obj){
var str = obj.value
	var errMsg	= "Your confirmation did not match!" ;
    	 errMsg += "\nPlease try again." ;

var checkWord = ""
checkWord = prompt("Please re-enter your password",checkWord);
if (str !=checkWord){
   	alert(errMsg) ; // tell the user what is wrong
   	obj.focus()   ; // focus on the field with the problem
		obj.select()  ; // select the contents of the field with the problem
		return false  ; // tell wrap around function that this value fails
   }
    return true     ; // tell wrap around function that this value passes
}

//=========================================================
// Function: isCheckedBox
//	Purpose:	Is the checkbox checked?
// Intended for use in a wrap-up routine only - not appropriate
// for a field level check.
//  this can be included in a function called by onSubmit
function isCheckedBox(obj){
	var str 	= obj.value ; // value to be 'tested' 
	var name 	= obj.name  ; // name of the field	
	var checked= obj.checked; // status (t/f) of checked property
	var errMsg	= "Please pick one of the options" 
		errMsg +="\nfor " + name + ". (Required entry)" ;

	if (obj.checked == false){
		alert(errMsg)
   	obj.focus()   ; // focus on the field with the problem
//		obj.select()  ; // select the contents of the field with the problem

		return false
  		}
	return true
	alert("isChecked = "+checked)
}

//=========================================================
// Function: isCheckedRadio
//	Purpose:	Is one of the radio buttons checked?
// Intended for use in a wrap-up routine only - not appropriate
// for a field level check.
//  this can be included in a function called by onSubmit
function isCheckedRadio(obj){
	var str 	= obj.value ; // value to be 'tested' 
	var checked= ""      ; // initialize
	var name = obj[0].name ; // get the name (this is an array)
	var errMsg	= "Please pick one of the options for " 
		errMsg +="\n" + name + ". (Required entry)" ;
	var i=""	
	for (var i = 0 ; i < obj.length ; i++) {
	 //alert ( "i = " + i + " obj[i].checked = " + obj[i].checked + " value= " + obj[i].value)
      if (obj[i].checked =="1" || obj[i].checked==true) {
         checked =obj[i].value  ; 
         }
	}	
	if (checked == ""){
		alert(errMsg)
   	obj[0].focus()   ; // focus on the field with the problem
		obj[0].select()  ; // select the contents of the field with the problem
		return false
  		}
	return true
	alert("isChecked = "+checked)
}

//=========================================================
// Function: isValidPostal(obj)
// Description : Checks if given postal code has valid syntax
// usage: <INPUT TYPE="TEXT" NAME="e-mail" onChange="isValidPostal(this)" >
// note: Validation assumptions 
//    Canadian Postal Codes are A9A 9A9 
//    US Postal Codes are 5 digits or 9 digits
//    

function isValidPostal(obj){
    var str 	= obj.value ; // value to be 'tested' 
    var name 	= obj.name  ; // name of the field	
    var upStr = str.toUpperCase() ; // convert to uppercase
    var errMsg	= "Please enter your valid Postal Code." 
    	  errMsg +="\nfor " + name + ". (Required entry)" ;
    	  errMsg +="\nYou entered \"" + upStr +"\"." ;   
    	  errMsg +="\nTry Letter Digit Letter Space Digit Letter Digit"
    	  errMsg +="\ne.g. V1A 2K9  (Canadian Example)" 
    	  errMsg +="\n or 5 digits or 9 digits (US version)"

    obj.value = upStr; // replace contents with Uppercase version
    newString = upStr.match( ( /(\b(^[A-Z]\d[A-Z]\s\d[A-Z]\d))|(\d(5))|(\d(9) )/g ) );
   if (!newString){  
   	alert(errMsg) ; // tell the user what is wrong
    obj.focus()   ; // focus on the field with the problem
		//obj.select()  ; // select the contents of the field with the problem
		return false  ; // tell wrap around function that this value fails
   }
    return true     ; // tell wrap around function that this value passes
}
/*	The regular expression looks for 
	(one capital letter at the beginning of the expression ^[A-Z]
	followed by one digit \d, 
	followed by one capital letter [A-Z],
	followed by space \s,
	followed by one digit \d, 
	followed by one capital letter [A-Z]
	followed by one digit \d, 
	followed by four digits \d{4}. 
	)
or	|
	5 digits (\d(5))
or |
	9 digits (\d(9))
*/	

//=========================================================
// Function: stripNonDigits(str)
// Description : removes non numeric characters from a string 
// usage: strMyString = stripNonDigits(strMyString)
// typical use - called within telephone validation isValidPhone
// note: The function replaces all occurrences of any character 
// that's not 0-9 with a null string using the 
// negated character set ([^0-9]), and the 
// global metacharacter (g): 
//

function stripNonDigits(str) {
	return str.replace(/[^0-9]/g,'')
}
//=========================================================
// Function: stripWhiteSpace(str)
// Description : removes whitespace characters from a string 
// usage: strMyString = stripWhiteSpace(strMyString)
// typical use - called within telephone validation isValidPhone
// note: The function replaces all occurrences of any character 
// Matches any whitespace character including
// space, tab, form-feed, etc. Equivalent to [ \f\n\r\t\v] .and the 
// global metacharacter (g): 
//

function stripWhiteSpace(str) {
	return str.replace(/[\s]/g,'')
}



// diagnostic function
function dumpProps(obj) {
   var result = ""
   for (var i in obj) {
      result += obj[i] + "." + i + " = " + obj[i].value+ "<BR>"
   }
   result += "<HR>"
   return result
}


//==================================================
//============= Superceded Functions ===============
// these are included to continue to support older pages
// that rely on theses - older  - versions of the functions
//==================================================
// Function: isBlank
// Purpose:  to check the the input is NOT blank
// 	returns false if the input IS blank
// 	usage: <INPUT NAME="someField" VALUE="someValue" onChange="isBlank(this.value)">
function isBlank(str)
{
// check for blank field
        if (str=="")  
        {
        alert("Please enter a city in the box")
        return false
        }
        return true
}
//==============================================================
// Function: isNumRange
// Purpose: to check that input is within the not blank, and is numeric
//          and withing a specified range
// Usage: <INPUT NAME="someField" VALUE="someValue" onChange="isNumRange(this.value)">
function isNumRangeOld(str, min, max)
{
// check for blank field
        if (str=="")  
        {
        alert("Please enter a number between " + min + " and " + max +" in the box")
        return false
        }
// check for non-digits
        for (var i=0; i < str.length; i++)  
        {
        var ch = str.charAt(i)
                if (ch < "0" || ch > "9")       
                {
                        alert("Only digits 0-9 are allowed")
                        return false
                }
        }
// check if within range 
	var val = parseInt(str, 10)
	if ((val < min) || (val > max))  
	{
		alert("You entered " + val + ". Valid scores are from " + min + " to " + max +". Please try again")
		return false
	}
		return true
}

//=== end of functions used in Form examples ==============
//=== some other validation functions you might find useful
//=========================================================

// whitespace characters
var whitespace = " \t\n\r ";

// Removes all characters which appear in string bag from string s.
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++)
    {   
        // Check that current character isn't whitespace.
        var c = s.charAt(i);
        if (bag.indexOf(c) == -1) returnString += c;
    }
    return returnString;
}

//=========================================================
// Function: stripWhiteSpace
// Removes all whitespace characters from s.
// Global variable whitespace (see above)
// defines which characters are considered whitespace.
function stripWhitespace (s)
 {   return stripCharsInBag (s, whitespace)
 }
//=========================================================
// Example
function isValidInput(str)
{
// check for blank field
	if (str=="")  
	{
	alert("Please enter a value in the field")
	return false
	}
	return true
}

//==============================================================
// Function: promptEntry
// Purpose:  to display a prompt on the status bar
// Usage: <INPUT NAME="someField" ... onFocus="promptEntry('enter your age in years')">
function promptEntry (s)
{   window.status =  s
}

//=========================================================
// Function: isValidPhoneOld(obj)
// Description : verifies that obj.value is a telephone
// number (ten digits - with or without parentheses and dashes)
// usage: <INPUT TYPE="TEXT" NAME="Telephone" onChange="isValidPhone(this)" >
// 
function isValidPhoneOld(obj) {
	 var re = /\(?\d{3}\)?([-\/\.\s])\d{3}([-\/\.\s])\d{4}/
    var str 	= obj.value ; // value to be 'tested'
    RegExp.input =str      ; // aka RegExp.input
    var name 	= obj.name  ; // name of the field	
    var errMsg	= "Please enter your Telephone Number." 
    	  errMsg +="\nin  " + name + ". (Required entry)" ;
    	  errMsg +="\nYou entered \"" + str +"\"." ;    	  
    	  errMsg +="\ntry a pattern like " ;
    	  errMsg +="\n(999) 999-9999 or 999.999.9999";   
   var newString = str.match(re);
   // OK = re.exec()			; // assign outcome exec method to OK
   if (!newString){      		; // if not OK then the test fails
      	alert(errMsg) 	; // tell the user what is wrong
	   	obj.focus()   	; // focus on the field with the problem
			obj.select()  	; // select the contents of the field with the problem
			return false  	; // tell wrap around function that this value fails
	   }
	    return true     ; // tell wrap around function that this value passes
	}

/*	The regular expression looks for 
	zero or one open parenthesis \(?, 
	followed by three digits \d{3}, 
	followed by zero or one close parenthesis \)?, 
	followed by one dash, forward slash, decimal point or space ([-\/\.\s])
	followed by three digits \d{3}, 
	followed by one dash, forward slash, decimal point or space ([-\/\.\s])
	followed by four digits \d{4}. 
*/	



// end hiding from older browsers   -->
