// JavaScript Common Functions for Input Control and common validation (e.g. dates)
// See exec-sum_form.asp in AcquiTrak for a solid example of use
// Adapted/Enhanced: Sam 12/2001
// Sources: Credited

//Credit to inside.com search page on the orginal.... VERY clever.
//Function to validate Date field; optionally PERMIT an empty as valid
//See acquitrak exec-sum_input.asp SubmitForm() JS for one example of use
function isValidDate(dateStr,blnAcceptEmpty) {
	
	if (blnAcceptEmpty & (dateStr=='')) {
		//Empty is OK, and it is empty
		return true;
	} else {
		//Otherwise, reject it right away if it is empty...
		if (dateStr=='') return false;
	}
	 				
	var month, day, year, isLeap;

	// Checks for the following valid date formats:
	// MM/DD/YY   MM/DD/YYYY   MM-DD-YY   MM-DD-YYYY
	// Also separates date into month, day, and year variables

	var datePat = /^(\d{1,2})(\/|-)(\d{1,2})\2(\d{2}|\d{4})$/;

	// To require a 4 digit year entry, use this line instead:
	// var datePat = /^(\d{1,2})(\/|-)(\d{1,2})\2(\d{4})$/;

	var matchArray = dateStr.match(datePat); // is the format ok?
	
	if (matchArray == null) {
		//alert("Date is not in a valid format.")
		return false;
	}
	month = matchArray[1]; // parse date into variables
	day = matchArray[3];
	year = matchArray[4];
	if (month < 1 || month > 12) { // check month range
		//alert("Month must be between 1 and 12.");
		return false;
	}
	if (day < 1 || day > 31) {
		//alert("Day must be between 1 and 31.");
		return false;
	}
	if ((month==4 || month==6 || month==9 || month==11) && day==31) {
		//alert("Month "+month+" doesn't have 31 days!")
		return false
	}
	if (month == 2) { // check for february 29th
		var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
		if (day>29 || (day==29 && !isleap)) {
			//alert("February " + year + " doesn't have " + day + " days!");
			return false;
		}
	}
	return true;  // date is valid
}

// trim function
function trim(strText) { 
    // this will get rid of leading spaces 
    while (strText.substring(0,1) == ' ') 
        strText = strText.substring(1, strText.length);

    // this will get rid of trailing spaces 
    while (strText.substring(strText.length-1,strText.length) == ' ')
        strText = strText.substring(0, strText.length-1);

   return strText;
}



// keyTrapDateMMDDYYYYOnly()
// example of use from acquitrak exec-sum_input.asp
//<td bgcolor="White" width="25%"><input type="text" size=25 name="ExpectedCloseDate" onKeyPress="return(keyTrapDateMMDDYYYYOnly(this,event));" value="<%=dExpectedCloseDate%>"></td>
function keyTrapDateMMDDYYYYOnly(fld, e) {
		
	// Cut this one off -- bail on <Enter> key
	if (e.keyCode == 13) return true;
	
	// Very simple, yet helpful date input controller	
	var sValidChars, sTestKey;
	sValidChars = '0123456789/';
	sTestKey = String.fromCharCode(e.keyCode );  
	if (sValidChars.indexOf(sTestKey) == -1 ) return false;
}

//Seems bizarre, but we actually have a need for this
//when someone is selecting a file from a client-side dialog and we NEVER want to permit
//them to change it.
function keyTrapAcceptNoKeys(fld,e){
	// Cut this one off -- bail on <Enter> key
	if (e.keyCode == 13) return true;
	return false;
}

// keyTrapNumsOnly()
// for use in onkeypress form events to make certain that whatever is 
// permitted can be handled by all of these number-related routines
function keyTrapNumsOnly(fld, e) {
		
	// Cut this one off -- bail on <Enter> key
	if (e.keyCode == 13) return true;
		
	// Otherwise test to see if it is something that formatAnyNumber
	// is equipped to correctly handle
	
	var sValidChars, sTestKey;
	
	sValidChars = '0123456789';
		
	sTestKey = String.fromCharCode(e.keyCode );  
	
	if (sValidChars.indexOf(sTestKey) == -1 ) return false;
}

function keyTrapNumsFloat(fld, e) {
		
	// Cut this one off -- bail on <Enter> key
	if (e.keyCode == 13) return true;
		
	// Otherwise test to see if it is something that formatAnyNumber
	// is equipped to correctly handle
	
	var sValidChars, sTestKey;
	
	sValidChars = '0123456789.';
		
	sTestKey = String.fromCharCode(e.keyCode );  
	
	if (sValidChars.indexOf(sTestKey) == -1 ) return false;
}

// keyTrapNumsOnly()
// for use in onkeypress form events to make certain that whatever is 
// permitted can be handled by all of these number-related routines
function keyTrapCurrencyOnly(fld, e) {
		
	// Cut this one off -- bail on <Enter> key
	if (e.keyCode == 13) return true;
		
	// Otherwise test to see if it is something that formatAnyNumber
	// is equipped to correctly handle
	
	var sValidChars, sTestKey;
	
	sValidChars = '0123456789.';
		
	sTestKey = String.fromCharCode(e.keyCode );  
	
	if (sValidChars.indexOf(sTestKey) == -1 ) return false;
}

// keyTrapPhoneOnly()
// for use in onkeypress form events to make certain that whatever is 
// permitted can be handled by all of these number-related routines
function keyTrapPhoneOnly(fld, e) {
		
	// Cut this one off -- bail on <Enter> key
	if (e.keyCode == 13) return true;
		
	// Otherwise test to see if it is something that formatAnyNumber
	// is equipped to correctly handle
	
	var sValidChars, sTestKey;
	
	sValidChars = '0123456789-()/.';
		
	sTestKey = String.fromCharCode(e.keyCode);  
	
	if (sValidChars.indexOf(sTestKey) == -1 ) return false;
}

function keyTrapZipOnly(fld, e) {
		
	// Cut this one off -- bail on <Enter> key
	if (e.keyCode == 13) return true;
		
	// Otherwise test to see if it is something that formatAnyNumber
	// is equipped to correctly handle
	
	var sValidChars, sTestKey;
	
	sValidChars = '0123456789-';
		
	sTestKey = String.fromCharCode(e.keyCode );  
	
	if (sValidChars.indexOf(sTestKey) == -1 ) return false;
}


// *****************************************************************************************
// function formatAnyNumber(num,dec_mult,cursymbol,commasymbol,decsymbol,rightsymbol) 
// Highly adapted generic number formatter; original credit to
// http://javascript.internet.com/forms/currency-format.html
// 
// Accepts: num as original number
//          num_decimals is the number of decimal places desired
//          cursymbol as the left-hand side currency symbol to render, if any
//          commasymbol as the string to insert every third place
//          decsymbol as the decimal symbol (e.g. US = ".", UK = ",")
//          rightsymbol as anything you'd like to have trailing the result (e.g. %)
// Author:  Sam Horton, Target Software, Inc.
//          info@targetsoftware.com
// *****************************************************************************************
function formatAnyNumber(num,num_decimals,cursymbol,commasymbol,decsymbol,rightsymbol) {

	// Clear out any $ or % on the way in
	num = num.toString().replace(/\$|\,/g,'');
	num = num.toString().replace(/\%|\,/g,'');

	// If it isn't a number, make it 0; not harsh if numbers are expected and input well-controlled
	if(isNaN(num))num = "0";

	// Determine sign of the number, use later
	sign = (num == (num = Math.abs(num)));
	
	//Raise 10^num_decimals for computation/rounding
	var dec_mult = Math.pow(10,num_decimals);
		
	// Round the result to proper number of decimal places
	num = Math.floor(num*dec_mult+0.50000000001);
	
	// Prepare to append anything to the right of the decimal place
	right_of_dec = num%dec_mult;
	num = Math.floor(num/dec_mult).toString();
	if(right_of_dec<(dec_mult/10)) right_of_dec = "0" + right_of_dec;
	
	
	// adds commasymbol every third
	for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++)
		num = num.substring(0,num.length-(4*i+3))+ commasymbol +
		num.substring(num.length-(4*i+3));
	
	// Special case - If no decimals are desired, don't append right_of_dec
	// You could also safely ignore decsymbol, but we're leaving it here for now...
	if (dec_mult == 1) return (((sign)?'':'-') + cursymbol + num + decsymbol + rightsymbol);
	
	// For everything else, append right_of_dec
	if (dec_mult > 1) return (((sign)?'':'-') + cursymbol + num + decsymbol + right_of_dec + rightsymbol);
}
// *****************************************************************************************


// *****************************************************************************************
// When performing math/saving records, you'll need a clean number
// This routine ASSUMES that num is a valid number to begin with, 
// and in particular one that formatAnyNumber will handle.
// We're also assuming that rounding to 6 places is good enough
// *****************************************************************************************

function any2num(num){
	
	var num_decimals = "6";
	var cursymbol = "";
	var commasymbol = "";
	var decsymbol = ".";
	var rightsymbol = "";
	var workingnum;
		
	//Pass through, strip, return ONLY the numeric result
	workingnum = formatAnyNumber(num,num_decimals,cursymbol,commasymbol,decsymbol,rightsymbol);
	
	workingnum = (workingnum/10*10);
	
	return workingnum;
}

//Same as any2num()
function blank2Zero(num){

	var num_decimals = "6";
	var cursymbol = "";
	var commasymbol = "";
	var decsymbol = ".";
	var rightsymbol = "";
	var workingnum;
		
	//Pass through, strip, return ONLY the numeric result
	workingnum = formatAnyNumber(num,num_decimals,cursymbol,commasymbol,decsymbol,rightsymbol);
	
	workingnum = (workingnum/10*10);
	
	return workingnum;
}

// *****************************************************************************************
// Authored a few handlers for typical cases used to shorten what you need to 
// put into your web page and reduce complexity
// *****************************************************************************************

// genNum0Dec returns xxxx
function genNum0Dec(num) {
	var num_decimals = "0";
	var cursymbol = "";
	var commasymbol = "";
	var decsymbol = "";
	var rightsymbol = "";
	return formatAnyNumber(num,num_decimals,cursymbol,commasymbol,decsymbol,rightsymbol);
}

// dollarNum2Dec returns $x,xxx.00
function dollarNum2Dec(num) {
	var num_decimals = "2";
	var cursymbol = "$";
	var commasymbol = ",";
	var decsymbol = ".";
	var rightsymbol = "";
	return formatAnyNumber(num,num_decimals,cursymbol,commasymbol,decsymbol,rightsymbol);
}

// dollarNum0Dec returns $x,xxx.00
function dollarNum0Dec(num) {
	var num_decimals = "0";
	var cursymbol = "$";
	var commasymbol = ",";
	var decsymbol = "";
	var rightsymbol = "";
	return formatAnyNumber(num,num_decimals,cursymbol,commasymbol,decsymbol,rightsymbol);
}

// commaNum0Dec returns x,xxx
function commaNum0Dec(num) {
	var num_decimals = "0";
	var cursymbol = "";
	var commasymbol = ",";
	var decsymbol = "";
	var rightsymbol = "";
	return formatAnyNumber(num,num_decimals,cursymbol,commasymbol,decsymbol,rightsymbol);
}

// commaNum2Dec returns x,xxx.xx
function commaNum2Dec(num) {
	var num_decimals = "2";
	var cursymbol = "";
	var commasymbol = ",";
	var decsymbol = ".";
	var rightsymbol = "";
	return formatAnyNumber(num,num_decimals,cursymbol,commasymbol,decsymbol,rightsymbol);
}


// percenNum2Dec returns x.xx%
function percenNum2Dec(num) {
	var num_decimals = "2";
	var cursymbol = "";
	var commasymbol = "";
	var decsymbol = ".";
	var rightsymbol = "%";
	return formatAnyNumber(num,num_decimals,cursymbol,commasymbol,decsymbol,rightsymbol);
}

// percenNum2Dec returns x.xx%
function percenNum1Dec(num) {
	var num_decimals = "1";
	var cursymbol = "";
	var commasymbol = "";
	var decsymbol = ".";
	var rightsymbol = "%";
	return formatAnyNumber(num,num_decimals,cursymbol,commasymbol,decsymbol,rightsymbol);
}

// Functions for limiting # of chars. for a TEXTAREA field.
// Add these attributes to the tag:
//		onclick="TextArea_doclick(this, <length>)" onkeyup="TextArea_dokeyup(this, <length>);"
//  the length is an optional param.
function TextArea_doclick(oTextarea, iMaxLength) {
	if ((typeof oTextarea == 'object') && 
		(oTextarea.type == 'textarea')) {
		
		// If the maxlength isn't passed in, look for it in two
		// other places.  If there's a "maxlength" attribute in the
		// HTML tag, use it, otherwise use the product of rows *
		// columns.
		if (arguments.length < 2) {
			iMaxLength = (oTextarea.maxlength) ? 
					oTextarea.maxlength :
					oTextarea.rows * oTextarea.cols ;
		}				
		char = eval(oTextarea.value.length)
		var dif = eval(char - iMaxLength)
		var value = oTextarea.value.substr(0,char-dif);
		oTextarea.value = value;
	}
}

function TextArea_dokeyup(oTextarea, iMaxLength) {
	// If the maxlength isn't passed in, look for it in two
	// other places.  If there's a "maxlength" attribute in the
	// HTML tag, use it, otherwise use the product of rows *
	// columns.
	if ((typeof oTextarea == 'object') && 
		(oTextarea.type == 'textarea')) {
		if (arguments.length < 2) {		
			iMaxLength = (oTextarea.maxlength) ? 
					oTextarea.maxlength :
					oTextarea.rows * oTextarea.cols ;
		}
		total = eval(iMaxLength)
		char = eval(oTextarea.value.length)
		left = eval(total - char)
		if (left <= "-1")
		{
			var dif = eval(char - iMaxLength)
			var value = oTextarea.value.substr(0,char-dif);
			oTextarea.value = value;
		}
	}
}


















