﻿// Validation procedures for a HTML (DOM) Form object's HTML elementsvar badWords = new Array('');
var scriptKeywords = new Array(''); 
// new Array('<script>','onabort=','onblur=','onchange=','onclick=','ondblclick=','onerror=','onfocus=','onkeydown=','onkeypress=','onkeyup=','onload=','onmousedown=','onmouseout=','onmouseover=','onmouseup=','onreset=','onresize=','onsubmit=','onunload=','<blink>','<style ','<applet ');
var htmlMarkup = new Array(''); 
// new Array('<a ','</a>','<font ','</font>','<b>','</b>','<i>','</i>','<strong>','</strong>','<i>','</i>','<u>','</u>','<p>','</p>','<ul>','</ul>','<hr>','<h1>','<h2>','<h3>','<h4>','<h5>','</h1>','</h2>','</h3>','</h4>','</h5>','<sub>','</sub>','<super>','</super>','<body>','</body>','<head>','</head>','<html>','</html>','<img ','<form>','</form>','<table>','</table>','<blockquote>','<center>','<div>','<pre>','<map ','<area ','<title>','<strike>','<big>','<small>','<cite>','<input ','<select ','<textarea ','<sub>','<marquee>','<form>','</marquee>','</form>');
// A utility function that returns true if a string contains only 
// whitespace characters.
function isBlank(s) {
    var undefined;
	if((s == undefined) || (s == null) || (s == '') || (s.length == 0)) { return true; }    for(var i = 0; i < s.length; i++){
        var c = s.charAt(i);
        if ((c != ' ') && (c != '\n') && (c != '\t')) return false;
    }
    return true;
} 

function isDefined(eval){
    var undefined;
    if(typeof(eval) != 'undefined' && eval != undefined && eval != null){
        return true;
    }
    else{
        return false;
    }
}

// Removes excess spaces from beginning and end of string
// JavaScript 1.2 compliant code
function trim(val){
	if(isDefined(val.replace) && isDefined(val) && (val.length > 0))
		return val.replace(/^\s*(\b.*\b|)\s*$/, "$1");
		// return val.replace(/<BR>*$/gi, "$+ ");
	else
		return val;
}

function noAllUpperCase(htmlFormInputObj){
// common code procedure - used to check that user has not typed
// in HTML input control using all CAPS.  
	if(isDefined(htmlFormInputObj)) {
		if(isDefined(htmlFormInputObj.value)){
			if(!isBlank(htmlFormInputObj.value)){
				var val = trim(htmlFormInputObj.value);
				if(val == val.toUpperCase())
					htmlFormInputObj.value = val.toLowerCase();	
			}
		}
	}	
}

function isAllLowerCase(eval){
	if(isBlank(eval))
		return false;
	else{
		if(eval == eval.toLowerCase())
			return true;
		else
			return false;
	}
}

function hasBadWord(val) {
	if(isBlank(val)) { return ''; }
	var strVal = val.toLowerCase();
	// for each bad word	
	for(var i = 0; i < badWords.length; i++){
		if(strVal.indexOf(' ' + badWords[i] + ' ') != -1){ 
			return badWords[i];
		}
	} 
	return '';
} 
function hasHTMLmarkup(val) {
	if(isBlank(val)) { return ''; }
	strValue = val.toLowerCase();
	// for each html element
	for(var i = 0; i < htmlMarkup.length; i++){
		if(strValue.indexOf(htmlMarkup[i]) != -1){ 
			return htmlMarkup[i];
		}
	} 
    return '';
} 

function hasScriptItem(val) {
	if(isBlank(val)) { return ''; }
	strValue = val.toLowerCase();
	// for script item
	for(var i = 0; i < scriptKeywords.length; i++)	{
		if(strValue.indexOf(scriptKeywords[i]) != -1){ 
			return scriptKeywords[i];
		}
	} 
	return '';
} 

function blnIsCapital(sChar) {
	// Returns true if character is a capital letter
	if(RegExp){
		// Browser is JavaScript 1.2 compliant
		// Use faster implementation
		return (sChar.search(/[ABCDEFGHIJKLMNOPQRSTUVWXYZ]/) != -1);
	}
	else {
		// use older javascript implementation
		if(sChar == 'A') { return true; }
		else if (sChar == 'B') { return true; }
		else if (sChar == 'C') { return true; }
		else if (sChar == 'D') { return true; }
		else if (sChar == 'E') { return true; }
		else if (sChar == 'F') { return true; }
		else if (sChar == 'G') { return true; }
		else if (sChar == 'H') { return true; }
		else if (sChar == 'I') { return true; }
		else if (sChar == 'J') { return true; }
		else if (sChar == 'K') { return true; }
		else if (sChar == 'L') { return true; }
		else if (sChar == 'M') { return true; }
		else if (sChar == 'N') { return true; }
		else if (sChar == 'O') { return true; }
		else if (sChar == 'P') { return true; }
		else if (sChar == 'Q') { return true; }
		else if (sChar == 'R') { return true; }
		else if (sChar == 'S') { return true; }
		else if (sChar == 'T') { return true; }
		else if (sChar == 'U') { return true; }
		else if (sChar == 'V') { return true; }
		else if (sChar == 'W') { return true; }
		else if (sChar == 'X') { return true; }
		else if (sChar == 'Y') { return true; }
		else if (sChar == 'Z') { return true; }
		else { return false; }
	}
} 

// Returns a user friendly description of the html elment name, s
// returns a newly formatted string which removes control prefix 
// and parses out hungarian (mixed case) notation into distinct words// Be sure to use user friendly HTML Form element names, // e.g. "txtEmailAddress" returns "Email Address"
function strDisplayName(s) {		// s - the form element name
	var sTrunc = '';
	// remove control name prefix
	var sPrefix = s.substring(0, 3); 
	
	if(isDefined(RegExp)){
		// Browser is JavaScript 1.2 compliant
		// Use faster implementation
		switch(s.substring(0, 3)){
			case 'txt':
			case 'lst':
			case 'cbo':
			case 'ddl':
			case 'btn':
			case 'lbl':
			case 'opt':
			case 'grd':
			case 'cmd':			case 'btn':
				sTrunc = s.substring(3);
				break;
			default:
				sTrunc = s;
		}
	}
	else{
		// Use earlier & slower Javascript 1.1/1.0 based implementation
		if(sPrefix == 'txt') { sTrunc = s.substring(3);}
		else if(sPrefix == 'lst') { sTrunc = s.substring(3);}
		else if(sPrefix == 'cbo') { sTrunc = s.substring(3);}
		else if(sPrefix == 'ddl') { sTrunc = s.substring(3);}
		else if(sPrefix == 'btn') { sTrunc = s.substring(3);}		else if(sPrefix == 'lbl') { sTrunc = s.substring(3);}
		else if(sPrefix == 'opt') { sTrunc = s.substring(3);}
		else if(sPrefix == 'grd') { sTrunc = s.substring(3);}
		else if(sPrefix == 'cmd') { sTrunc = s.substring(3);}
		else { sTrunc = s;}
	}
	
	// parse hungarian notation to words
	var sEval = '', sNew = '';
	for(var i = 0; i < sTrunc.length; i++){
		sEval  = sTrunc.charAt(i);
		if (blnIsCapital(sEval)){ 
		    sNew += ' ' + sEval; 
		}
		else{	
			if(sEval != '_')
				sNew += sEval;	
			else
				sNew += ' '; // replace underscore with blank space	 
		}
	}
	return sNew;
} 

// Returns true if form element is a text entry type inputfunction isTextEntryInput(e) {
	// e - form element
	// common code procedure	var sType = e.type;
		sType = sType.toLowerCase();
		if ((sType == 'text') || 
        (sType == 'textarea') || 
        (sType == 'password'))  {
        return true;
    }
    else
		return false;    } 

// Returns true if the element is to accept only numeric entries
function isNumberInputField(e) {
    var undefined;
	if(e == null) 		return false;
	else if(e.isNumber && (e.isNumber != undefined) && (e.isNumber != null) && (e.isNumber == true))
		return true;
	else if(e.min  && (e.min != undefined) && (e.min != null))
		return true;
	else if(e.max  && (e.max != undefined) && (e.max != null))
		return true;
	else
		return false;		} 


// Returns true if form element is a list selection typefunction isSelectList(e) {
	// e - form element
	var sType = e.type;
		sType = sType.toLowerCase();
	if ((sType == 'select-one') || 
        (sType == 'select-multiple')){
        return true;
    }
    else
		return false;    }

function setErrorFocus(f) {
	// set focus to the first form element
	// which contains a validation error    for(var i = 0; i < f.length; i++) {
        var e = f.elements[i];
                if(e.isError == true) {
			if(e.focus) {				e.focus();
				break;			}	        
        }    }}

function isValidEmail(strValue) {
	if(isBlank(strValue))
		return true;
		
	var iAtSymbolPos = -1; 
	var iDotPos = -1;

	// Check for absolute minimun length (minimum #@#.#)
	if(strValue.length < 5) 
		return false;

	// Check for @ symbol - note indexOf is zero based!
	iAtSymbolPos = strValue.indexOf('@');	

	if(iAtSymbolPos < 1)  
		return false;

	if(iAtSymbolPos > (strValue.length - 3)) 
		return false;
				
	// Check for at least one '.' after @ symbol
	iDotPos = strValue.indexOf('.',iAtSymbolPos + 1);
	
	if(iDotPos < 1 || (iDotPos == (strValue.length - 1)))
		return false;

	// See if email contains "untrimmed" whitespace characters...
	var iWhitespacePos = strValue.indexOf(' ');
	if(iWhitespacePos != -1 && (iWhitespacePos > 0 && iWhitespacePos < strValue.length - 1))
		return false;
		
	if(RegExp.test) {	
		// is js 1.2 compliant
		var reg = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
		return reg.test(strValue);
	}
	else
		return true;
}


function isValidTime(value) {
	if(isBlank(value))
		return true;
   var hasMeridian = false;
   var re = /^\d{1,2}[:]\d{2}([:]\d{2})?( [aApP][mM]?)?$/;
   if (!re.test(value)) { return false; }
   if (value.toLowerCase().indexOf("p") != -1) { hasMeridian = true; }
   if (value.toLowerCase().indexOf("a") != -1) { hasMeridian = true; }
   var values = value.split(':');
   if ( (parseFloat(values[0]) < 0) || (parseFloat(values[0]) > 23) ) { return false; }
   if (hasMeridian) {
      if ( (parseFloat(values[0]) < 1) || (parseFloat(values[0]) > 12) ) { return false; }
   }
   if ( (parseFloat(values[1]) < 0) || (parseFloat(values[1]) > 59) ) { return false; }
   if (values.length > 2) {
      if ( (parseFloat(values[2]) < 0) || (parseFloat(values[2]) > 59) ) { return false; }
   }
   return true;
}

function getPhoneNumberFormat(){
	// Common code procedure treated as a global constant
	// The specified format value must be entered
	return '###-###-####';
}

function isValidPhoneNumber(phoneNo) { 
	// valid format: ###-###-####
	// must be consistent with getPhoneNumberFormat()
	if(isBlank(phoneNo))
		return true;  
    // other validation work will check to see if it is required
	
	// JavaScript 1.0 compliant implementation
	if(phoneNo.length != getPhoneNumberFormat().length)
		return false;
	else if(phoneNo.charAt(3) != '-' || phoneNo.charAt(7) != '-')
		return false;
	else if(isNaN(phoneNo.substring(0,2)) || isNaN(phoneNo.substring(4,6)) || isNaN(phoneNo.substring(8,11)))
		return false;
	else	
		return true;			
}

// This is the function that performs form verification. If it is invoked
// from the onSubmit() event handler. The onSubmit() event handler should // return whatever value this function returns.
function isValidForm(f) {	// f - the DOM form object
    var msg;
    var empty_fields = '';
    var errors = '';
    var undefined;

    // Loop through the elements of the form, looking for all 
    // text, textarea, and select (select-one, select-multiple) elements that 
    // have the following properties set:
    //		"optional" - if set to false, then an entry is required
    //		"maxLength" - character count max for text input field element    //		"minLength" - character count minimum for text input field element    //		"isNumber" - checks to see if it is a numeric value entered    //		"min"	   - checks if numeric field value is below the minimum value specified
    //		"max"	   - checks if numeric field value is above the maximum value specified	//		"isEmailAddress" - for a text input that accepts email addresses
	//		"isPhone"  - for a text input that accepts phone numbers (###-###-####)	//		"isTime"   - for a text input that accepts time values (hh:mm AM/PM)	//
    // All of these properties are optional. For those elements you are interested in validating    // set the respective property equal to true.
    //     // A list of all errors is displayed in an alert dialog box.  
    // Returns true, if no validation errors occur, otheriwse false is returned.
            
    // For each form element...    for(var i = 0; i < f.length; i++) {
        var e = f.elements[i];
                e.isError = false;                // Required entry check        if((e.optional != undefined) && (e.optional != null) && (e.optional == false) && isBlank(e.value)) {			empty_fields += '\n          ' + strDisplayName(e.name);			e.isError = true;
			continue;        }        else if(isBlank(e.value)){            continue;        }        // End: Required entry check                if(isTextEntryInput(e)){             // Is texbox/password/text-area element
            // Not blank - now perform a Character count check
            if((e.maxLength != undefined) && (e.maxLength != null)) {				// see if the character count is within the prescribed limit				var eval = e.value;
				if((eval != null) && (eval.length > e.maxLength)) {
					errors += '\n- ' + 
                              strDisplayName(e.name) + 
                              ' must be less than ' + (e.maxLength + 1) + ' characters in length.';
					e.isError = true;                              					continue;
				}             }
            
            if((e.minLength != undefined) && (e.minLength != null)) {				// see if the character count meets the desired minimum				var eval = e.value;
				if((eval != null) && (eval.length < e.minLength)) {
					errors += '\n- ' + 
                              strDisplayName(e.name) + 
                              ' must be at least ' + e.minLength + ' characters in length.';
					e.isError = true;                              					continue;
				}             }
			// End: Character count check						
			// Valid number check
			if(isNumberInputField(e)) {			    var val = parseFloat(e.value);			    // Is it a number?			    if (isNaN(val)) {
				    errors += '\n- ' + strDisplayName(e.name) + 
                              ' must be a number';				    e.isError = true;                    continue;                              
			    }				
			    if((e.min != undefined) && (e.min != null) && (val < e.min)){				    errors += '\n- ' + strDisplayName(e.name) + 
                              ' must be a number that is greater than ' + e.min;
                    e.isError = true;                    continue;          			    }							    if((e.max != undefined) && (e.max != null) && (val > e.max)){				    errors += '\n- ' + strDisplayName(e.name) + 
                              ' must be a number that is less than ' + e.max;
                    e.isError = true;                    continue;          			    }
			}
			// End: Valid number check
            
                        // Valid email address format check
            if((e.isEmailAddress != undefined) && (e.isEmailAddress != null) && (e.isEmailAddress == true)) {
			    if(!isValidEmail(e.value)) {				    errors += '\n- ' + 
                              strDisplayName(e.name) + 
                              ' is an invalid email address.';				    e.isError = true;                    continue;                              
			    }
            }
            // End: Valid email address format check
                                    // Valid time entry check
            if((e.isTime != undefined) && (e.isTime != null) && (e.isTime == true)) {
           		if(!isValidTime(e.value)) {					errors += '\n- ' + 
                              strDisplayName(e.name) + 
                              ' is an invalid time.';					e.isError = true;                    continue;                              
				}            
            }
            // End: Valid time entry check
                        // Valid phone entry check
            if((e.isPhone != undefined) && (e.isPhone != null) && (e.isPhone == true)) {
				if(!isValidPhoneNumber(e.value)) {					errors += '\n- ' + 
                              strDisplayName(e.name) + 
                              ' must be in a ' + getPhoneNumberFormat() + ' format.';					e.isError = true;                    continue;                              
				}            
            }
            // End: Valid phone entry check
                    }  
        // is texbox/password/text-area element
        
        if (isSelectList(e) && (e.optional != undefined) && !e.optional && e.length > 0) {
			// Validate entry has been made in list box or combo box
			if (e.selectedIndex == -1 || isBlank(e.options[e.selectedIndex].text))
				empty_fields += '\n          ' + strDisplayName(e.name);				e.isError = true;				continue;
        }        
    }  
    // for each form element

    // Now, if there were any errors, display the messages, and
    // return false to prevent the form from being submitted. 
    // Otherwise return true.
    if (isBlank(empty_fields) && isBlank(errors)) return true;

    msg  = '______________________________________________________\n\n'
    msg += 'The form was not submitted because of the following error(s).\n';
    msg += 'Please correct these error(s) and re-submit.\n';
    msg += '______________________________________________________\n';

    if (empty_fields) {
        msg += '- The following required field(s) are empty:' 
                + empty_fields + '\n';
        // if (errors) msg += '\n';
    }
    msg += errors;
    alert(msg);	setErrorFocus(f);    
    
    return false;
}