//***********************************************************************
//***********************************************************************
// Copyright Travant Solutions, Inc. 2000-2002
//
// The use, disclosure, reproduction, modification, transfer, or  
// transmittal of  this work for any purpose in any form or by any 
// means without the written  permission of Travant Solutions is 
// strictly prohibited.
//
// Confidential, Unpublished Property of Travant Solutions, Inc.
// Use and distribution limited solely to authorized personnel.
//
// All Rights Reserved.
//
// Notice:  This file was created by Travant Solutions, Inc.  Contact
// by e-mail at info@travantsolutions.com
//
// Filename:		formValidationFunctions.js
// Description:	
//
// Notes:		
//
//***********************************************************************
//***********************************************************************%>

//  tsiRequired  (true/false)
//  tsiDisplayName (string) The name to use in the validation message
//  tsiInteger (true/false)
//  tsiNumeric (true/false)
//  tsiMin (numeric)
//  tsiMax (numeric)
//  tsiCurrency (true/false)
//  tsiDate (true/false)
//  tsi4DigitYear(true/false)
//  tsiEMail (true/false)
//  tsiPhone (true/false)
//  tsiZip (true/false)

//
// Available Functions
// displayErrorMessage(szMsg) 
// getDaysInMonth(eDate) 
// isBlank(szText)
// isFutureDate(szDate)
// isLeapYear(eDate) 
// IsValidCurrency(szText)
// IsValidDate(szText, b4DigitYear) 
// IsValidDateRange(eFromDate, eToDate) 
// isValidEMail(szEmail) 
// IsValidInteger(szText)
// IsValidNumber(szText) 
// IsValidNumericRange(eFrom, eTo) 
// isValidPhone(szPhone) 
// isValidZip(szZip) 
// make4DigitYear(szText) 
// Trim(szString) 




/* Executes when a form is submitted.  Executes the 
* preStdValidation (user defined), then the system
* validations, then finally postStdValidation (user 
* defined).  If any valdiation fails, the method will
* return false which will cancel the form submission */
function formOnSubmit(form)
{
	var bReturn = false;
    if (preStdValidation(form))
    	if (validateForm(form))
        	if (postStdValidation(form))
            	bReturn= true;

	return bReturn;
  }

function validateForm(form)
{
	var e;
    var eToFocus;
    var eHid;
    var nValue;

    var szRequiredErrors = "";
    var szNumericErrors = "";
    var szDateErrors = "";
    var szErrorMessage = "";
	var szGeneralErrors = "";
    var szDateFormat = "";
    var szTrimmedString = "";
	
    var bSearchForm;
    var bIsValid;



    //  First we need to see if we have
    //  any specified date formats.
    szDateFormat = "mm/dd/yy";

    // Loop through the elements of the form, looking for all
    // all text and textarea elements that have the "required"
    // property defined, and are empty. Display an error message
    // identifying the fields that have errors.
    for (var i=0; i<form.length; i++) {

		e = form.elements[i];

        if (e.disabled) {
			continue;
        }

        if (e.type == "text") {
             // if the field is not empty, trim string
            if ((e.value != null) && (e.value != "") && !isBlank(e.value)) {
                szTrimmedString = Trim(e.value);
                e.value = szTrimmedString;
            }
        } // End If (e.type == "text")

        if ((e.type == "text") || (e.type == "textarea") || (e.type == "password") || (e.type == "hidden")) {

            if (e.tsiRequired) {
                // first check if the field is empty
                if ((e.value == null) || (e.value == "") || isBlank(e.value)) {
                    if (!szRequiredErrors && !szNumericErrors)
                        eToFocus = e;

                    szRequiredErrors += "\n          " + e.tsiDisplayName;
                    continue;
                }
            } // End if (e.tsiRequired)

			// Validate numeric fields if they are not blank and not an asterisk.
            if ((e.value.length > 0) && (e.tsiInteger || e.tsiNumeric || (e.tsiMin != null) || (e.tsiMax != null) || (e.parsequals != null))) {
            	if (e.tsiInteger)
                	bIsValid = IsValidInteger(e.value);
                else
                    bIsValid = IsValidNumber(e.value);

                if (!bIsValid) {
                	if (!szRequiredErrors && !szNumericErrors && !szDateErrors)
                        eToFocus = e;

	                szNumericErrors += " - The field " + e.tsiDisplayName + " must be a number"
                    szNumericErrors += ".\n";
                } else {
                    nValue = parseFloat(e.value);
                    if (isNaN(nValue) ||
                        ((e.tsiMin != null) && (nValue < e.tsiMin)) ||
                        ((e.tsiMax != null) && (nValue > e.tsiMax)))
                    {
                        if (!szRequiredErrors && !szNumericErrors && !szDateErrors)
                            eToFocus = e;

                        szNumericErrors += " - The field " + e.tsiDisplayName + " must be a number";

                        if (e.tsiMin != null)
                            szNumericErrors += " that is greater than or equal to " + e.tsiMin;

                        if ((e.tsiMax != null) && (e.tsiMin != null))
                            szNumericErrors += " and less than or equal to " + e.tsiMax;
                        else if (e.tsiMax != null)
                            szNumericErrors += " that is less than or equal to " + e.tsiMax;

                        szNumericErrors += ".\n";
                    }
                } // End Else (!bIsValid)

                if ((e.parsequals != null) && (nValue != e.parsequals)) {
                  	if (!szRequiredErrors && !szNumericErrors && !szDateErrors)
						eToFocus = e;
							
				    szNumericErrors += " - The field " + e.tsiDisplayName;
				    if (e.parsequals != null)
						szNumericErrors += " must equal to " + e.parsequals;

				    szNumericErrors += ".\n";
			    } // End If ((e.parsequals != null) && (nValue != e.parsequals))
            } // End If (e.value.length > 0) && (e.tsiInteger || e.tsiNumeric || (e.tsiMin != null) || (e.tsiMax != null) || (e.parsequals != null)))

		
            if ((e.value.length > 0) && e.tsiCurrency) {
                bIsValid = IsValidCurrency(e.value);

                if (!bIsValid) {
                    if (!szRequiredErrors && !szNumericErrors && !szDateErrors)
                        eToFocus = e;
                    szNumericErrors += " - The field " + e.tsiDisplayName + " must be a valid currency amount.\n";
                }
            }  // End If e.tsiCurrency

            if ((e.value.length > 0) && e.tsiDate) {
            	if (e.tsi4DigitYear) {
                    b4DigitYear = true;
                    szDateFormat = "mm/dd/yyyy";
                } else {
                    b4DigitYear = false;
                    szDateFormat = "mm/dd/yy";
                }

                if (!IsValidDate(e.value, b4DigitYear)) {
                    if (!szRequiredErrors && !szNumericErrors && !szDateErrors)
                        eToFocus = e;

                    if (e.tsiDisplayName == null)
                        szDateErrors += " - The Date field must be a valid date in the format " + szDateFormat + ".\n";
                    else
                        szDateErrors += " - The field " + e.tsiDisplayName + " must be a valid date in the format " + szDateFormat + ".\n";
                } // End if (!IsValidDate(e.value, b4DigitYear))

                e.value = make4DigitYear(e.value);
      		} // End If e.tsiDate
				
            if ((e.value.length > 0) && e.tsiEMail) {
				if (!isValidEMail(e.value)) {
					szGeneralErrors += " - The field " + e.tsiDisplayName + " must be a valid Internet e-mail address.\n";				
				}
			} // End If e.tsiEMail				


            if ((e.value.length > 0) && e.tsiPhone) {
				if (!isValidPhone(e.value)) {
					szGeneralErrors += " - The field " + e.tsiDisplayName + " must be a valid phone number.\n";				
				}
			} // End If e.tsiPhone				

            if ((e.value.length > 0) && e.tsiZip) {
				if (!isValidZip(e.value)) {
					szGeneralErrors += " - The field " + e.tsiDisplayName + " must be a valid U.S. zip code.\n";				
				}
			} // End If e.tsiEMail				
			
			
        } // End if ((e.type == "text") || (e.type == "textarea") || (e.type == "password") || (e.type == "hidden"))
    } // End for (var i=0; i<form.length; i++)
	
	
    // If there were any errors, display a message,
    // and return false, to prevent the form from
    // being submitted. Ohterwise return true.
    if (szRequiredErrors || szNumericErrors || szDateErrors || szGeneralErrors) {

		szErrorMessage = "";
        if (szRequiredErrors) {
			szErrorMessage += " - The following required field(s) are empty:" +
                              szRequiredErrors + "\n";
            
			if ((szNumericErrors) ||
                (szDateErrors))
                szErrorMessage += "\n";
        }

        if (szNumericErrors){
			szErrorMessage += szNumericErrors;
            if (szDateErrors || szGeneralErrors)
                szErrorMessage += "\n";
        }

        if (szDateErrors) {
            szErrorMessage += szDateErrors;
            if (szGeneralErrors)
                szErrorMessage += "\n";
		}
		
		if (szGeneralErrors) {
            szErrorMessage += szGeneralErrors;
		}
			
        //alert(szErrorMessage);
        displayErrorMessage(szErrorMessage);

         if ((eToFocus != null) &&
             (eToFocus.type != "hidden"))
         {
         	eToFocus.focus();
            eToFocus.select();
         }
            
		return false;
 	} else {
        return true;
    } // if (szRequiredErrors || szNumericErrors || szDateErrors)
} // End function validateForm(form)

	
// 
// This function returns true if a string 
// contains only whitespace characters.
//
function isBlank(szText) {
	var ch;
	
    for(var i=0; i<szText.length; i++) {
		ch = szText.charAt(i);
        if ((ch != ' ') && (ch != '\n') && (ch != '\t'))
        	return false;
    }
    
	return true;
} // End function isBlank(szText)

//
// This function validates both two digit
// and four digit years.  It also checks
// for leap year
//
function IsValidDate(szText, b4DigitYear) {

    var szDate, aDateElements, szDay, szMonth, szYear, aDaysInMonth
    szDate = new String(szText);

	// If we don't find a date separator
	// then it is an invalid date.
    iSlash1 = szDate.indexOf("/");
    if (iSlash1 == -1) {
        return false;
    }

    if (iSlash1 == szDate.length) {
        return false;
    }

	// If we don't find a second date 
	// separator then it is an invalid date.
    iSlash2 = szDate.indexOf("/", iSlash1 + 1);
    if (iSlash2 == -1)  {
        return false;
    }

    szMonth = szDate.substring(0, iSlash1);
    szDay = szDate.substring(iSlash1+1,iSlash2);
    szYear = szDate.substring(iSlash2+1);

	// Validate the day of month
    iDay = parseFloat(szDay);
    if (isNaN(szDay) || isNaN(iDay)) {
        return false;
    }

	// Validate the month of year
    iMonth = parseFloat(szMonth);
    if (isNaN(szMonth)|| isNaN(iMonth)) {
        return false;
    }

    if ((iMonth < 1) || (iMonth > 12)) {
        return false;
    }
	
	// Validate the year
    iYear = parseFloat(szYear);

	if (isNaN(szYear) || isNaN(iYear)) {
        return false;
    }

	if (b4DigitYear) {
 		if (szYear.length < 4) {
		  	return false;
  		}
	}

	// Now make sure the year fits
	// into our "window" of valid years
	today = new Date();
	minYear = today.getYear() - 150;
 	maxYear = today.getYear() + 20;

	inputDate = new Date(szText);	
 	if ((inputDate.getFullYear() < minYear) ||
    	(inputDate.getFullYear() > maxYear)) {
    	return false;
 	}

	if (szYear.length == 3 ) {
 		return false;
	}

   	if (iYear < 0) {
        return false;
    }

	   
    if (Math.round(iYear/4) == iYear/4) {
      	//it's leap year....
      	aDaysInMonth = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];            
    }else{
    	//non leap year...
      	aDaysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    }                      
   
    
    if ((iDay < 1) ||
        (iDay > aDaysInMonth[iMonth-1])) {
        return false;
    }

	// If we made it this far, all is well
    return true;
	
} // function IsValidDate(szText, b4DigitYear)

    
// 
// Determines if the value is a valid
// number.  This includes commas, negative
// sign, and decimal point.
//
function IsValidNumber(szText) {
    var iIndex;
    var szValues = "0123456789,.-";
    var bValid = true;
	var iDecimalCount = 0;

	// Iterate through each character
	// in the value.
    for(iIndex=0; (iIndex <= szText.length-1) && (bValid); iIndex++) {
        
		// If we don't find our character in our 
		// valid characters values, it is invalid.
		if (szValues.indexOf(szText.charAt(iIndex)) == -1) {
            bValid = false;

		// Is the current char a decimal?
        } else if ( szText.charAt(iIndex) == '.' ) {
            iDecimalCount = iDecimalCount + 1;

            // Number must have only one decimal
            if (iDecimalCount > 1) {
                bValid = false;
            }
			
		// Is the current char a negative sign?	
        } else if ( szText.charAt(iIndex) == '-' ) {
            // Number must have only one dash and when present it
            // must be first character
            if (iIndex > 0)
                bValid = false;
        }
	} // End For

    return bValid;
}

// 
// Determines if the value is a valid
// currency.  This includes commas, negative
// sign, dollar sign, and decimal point.
//
function IsValidCurrency(szText)
{
    var iIndex;
    var szValues = "0123456789,.-$";
    var bValid = true;
    var bFoundDecimal = false;
    var iDecimalCount = 0;
    var iAfterDecimalCount = 0;
    var iDollarSignCount = 0;
    var iPosofRightMostDollarSign = 0;

    for(iIndex=0; (iIndex <= szText.length-1) && (bValid); iIndex++) {

		if ( szText.charAt(iIndex) == '$' ) {
        	iDollarSignCount = iDollarSignCount + 1;
            iPosofRightMostDollarSign = iIndex;

        // Number must have only one dash and when present it
        //  must be first character (or the second iff the first
        //  is the dollar sign)
        } else if ( szText.charAt(iIndex) == '-' ) {
			if (iIndex > 0) {
                if ( (iIndex != 1) || (szText.charAt(0) != '$'))
                        bValid = false;
            }
        }

        if ( bFoundDecimal == true ) {
            iAfterDecimalCount = iAfterDecimalCount + 1;
        }

        if ( szText.charAt(iIndex) == '.' ) {
            iDecimalCount = iDecimalCount + 1;
            bFoundDecimal = true;
        }

        if (szValues.indexOf(szText.charAt(iIndex)) == -1) {
            bValid = false;
        }
    } // end-for


    // Only one decimal makes sense
    if (iDecimalCount > 1) {
        bValid = false;
    }

    // Only one dollarsign makes sense
    if (iDollarSignCount > 1) {
        bValid = false;
    }

    // Dollar sign must be in position 0
    if (iPosofRightMostDollarSign > 0) {
        bValid = false;
    }

	// If we don't have two places after
	// the decimal, then this is invalid
	// We allow 0 decimal points for backwards
	// compatibility.
	if (iAfterDecimalCount > 2) {
		bValid = false;
	}
	
	return bValid;
}

//
// Determine if the value is a valid
// integer - no decimals
//
function IsValidInteger(szText) {

    // If it is a valid number and it contains no decimal point,
    //  then it is a valid integer
    if ( (IsValidNumber(szText)) && (szText.indexOf(".") == -1) )
        return true;
    else
        return false;
}

// 
// Remove all whitespaces from before
// and after the value.
//
function Trim(szString) {
    var szTrimCharacter = ' ';
    var szNewString = "";

    // Make a copy of the string to work with
    szNewString = szString;

    // Remove the leading characters
    while (szNewString.charAt(0) == szTrimCharacter) {
        szNewString = szNewString.substring(1,szNewString.length);
    }

    // Remove the trailing characters
    while (szNewString.charAt(szNewString.length - 1) == szTrimCharacter) {
        szNewString = szNewString.substring(0,szNewString.length - 1);
    }

    return szNewString;
}


// 
// Displays an error message
//
function displayErrorMessage(szMsg) {
  	szHeader  = "_____________________________________________________\n\n";
    szHeader += "Please correct the following error(s):\n";
    szHeader += "_____________________________________________________\n\n";
	alert(szHeader + szMsg);
}

// 
// Take a date value and if it has
// a two-digit year, return a 
// four-digit year.
//
function make4DigitYear(szText) {

 	var szDate, aDateElements, szDay, szMonth, szYear,
    szDate = new String(szText);

    iSlash1 = szDate.indexOf("/");
    iSlash2 = szDate.indexOf("/", iSlash1 + 1);

    szMonth = szDate.substring(0, iSlash1);
    szDay = szDate.substring(iSlash1+1,iSlash2);
    szYear = szDate.substring(iSlash2+1);

    if (szYear.length == 2) {
		iYear = parseFloat(szYear);
      	if (iYear > 90) {
       		iYear = iYear + 1900;
       	} else {
       		iYear = iYear + 2000;
       	}
       	szYear = iYear;
    }

    return szMonth + "/" + szDay + "/" + szYear;
}


//
// Determine if a date range is valid.  The
// from date must be before or equal to the
// end date
//
function IsValidDateRange(eFromDate, eToDate) {

	fromValue = Trim(eFromDate.value);
	toValue = Trim(eToDate.value);

	if ((fromValue.length > 0) &&
	    (toValue.length > 0)) {

		var dtFromDate = new Date(make4DigitYear(fromValue));
		var dtToDate = new Date(make4DigitYear(toValue));

		if (dtFromDate > dtToDate) {
			return "An invalid date range has been specified for the " + eFromDate.tsiDisplayName + " and " + eToDate.tsiDisplayName + " fields.\n";
		}
	}

	return "";
}

//
// Determine if a numeric range is valid.
// The from number must be less than or
// equal to the to value.
//
function IsValidNumericRange(eFrom, eTo) {

	var fromValue = 0.0;
	var toValue = 0.0;
	
	fromValue = parseFloat(eFrom.value);
	toValue = parseFloat(eTo.value);
	
	if (fromValue > toValue) {
		return "An invalid range has been specified for the " + eFrom.tsiDisplayName + " and " + eTo.tsiDisplayName + " fields.\n";
	}

	return "";
}

// 
// Return the number of days in
// month of the specified date.
//
function getDaysInMonth(eDate) {

    var aDaysInMonth = new Array(12);
    aDaysInMonth[0] = 31;
    aDaysInMonth[1] = 28;
    aDaysInMonth[2] = 31;
    aDaysInMonth[3] = 30;
    aDaysInMonth[4] = 31;
    aDaysInMonth[5] = 30;
    aDaysInMonth[6] = 31;
    aDaysInMonth[7] = 31;
    aDaysInMonth[8] = 30;
    aDaysInMonth[9] = 31;
    aDaysInMonth[10] = 30;
    aDaysInMonth[11] = 31;

    var myDate = new Date(eDate.value);
    var month = myDate.getMonth();


    // If this is February
    if ((month == 1) &&
        isLeapYear(eDate))
        daysInMonth = 29;
    else 
        daysInMonth = aDaysInMonth[month];

    return daysInMonth;
}

//
// Determine if the specified
// date is in a leap year.
//
function isLeapYear(eDate) {

    date = new Date(eDate.value);
    year = date.getYear();

    if (year % 100 == 0) {
        if (year % 400 == 0) { 
            return true;    
        }
    } else {
        if ((year % 4) == 0) { 
            return true; 
        }
    }
    
    return false;
}

//
// Compares today's date with the entered date.
// Returns true if the entered date is greater than today's date.
// The passed date should be a valid date in the format ("mm/dd/yyyy")
//
function isFutureDate(szDate)
{
    var current_date = new Date;    
        
    var passedDate = new Date(szDate.substring(6,10),
                              szDate.substring(0,2)-1,
                              szDate.substring(3,5));
                                           
    if (passedDate > current_date)
    	return true;
    else
    	return false;
    
}

//
// Determines if the value is a
// valid Internet e-mail address.
//
function isValidEMail(szEmail) {

	iAtSignCount = 0;
	iPosofAtSign=0;
	iPosofRightMostDot=0;
  	bSpaceFound = false;
  
  	szEmail = Trim(szEmail);
	for(iIndex=0; iIndex <= szEmail.length-1; iIndex++)
	{
		if (szEmail.charAt(iIndex) == '@' )
		{
			iAtSignCount = iAtSignCount + 1;
			iPosofAtSign = iIndex;
		}

		if (szEmail.charAt(iIndex) == '.' )
		{
			iPosofRightMostDot = iIndex;
		}
		
		if (szEmail.charAt(iIndex) == ' ')
		{
		    bSpaceFound = true;
		}
	} // End For

	// If we don''t have a single '@' character or if
	// the "." is not to the right of the '@' then this is
	// not a valid SMTP e-mail address.
	if ((iAtSignCount != 1) ||
	    (iPosofAtSign > iPosofRightMostDot) ||
		(bSpaceFound)) {
		return false;
	}

	return true;
}


//
// Determines if the specified
// phone number is valid.  Do not
// pass in an area code.
function isValidPhone(szPhone) {

	if (szPhone.length == 0) {
		return true;
	}

	if (szPhone.length == 8) {
		szDelimiter = szPhone.charAt(3);
		if ((szDelimiter != "-") &&
			(szDelimiter != ".")) {
			return false;
		}
	
		szExchange = szPhone.substring(0,3);
		szNumber = szPhone.substring(4,8);
	} else if (szPhone.length == 7) {

		szExchange = szPhone.substring(0,3);
		szNumber = szPhone.substring(3,7);

	} else {
		return false;
	}

	
	if (IsValidInteger(szExchange) == false) {
		return false;
	}

	if (IsValidInteger(szNumber) == false) {
		return false;
	}

	if (szExchange == "555") {
		return false;
	}
	
	return true;
}

//
// Checks for both 5 and 9 digit
// zip codes.
//
function isValidZip(szZip) {

	if (szZip.length == 5) {
	
		if (!IsValidInteger(szZip)) {
			return false;
		}
		
	} else if (szZip.length == 10) {
		if (szZip.charAt(5) != "-") {
			return false;
		}

		if (!IsValidInteger(szZip.substring(0,4))) {
			return false;
		}

		if (!IsValidInteger(szZip.substring(6,10))) {
			return false;
		}
		
	} else {
		return false;
	}
	
	// If we made it this far, then
	// everything is fine.
	return true;
}
























