/* Version Date: 7/17/2001 */
/* Copyright (c) 2001 J. Paul Schmidt, MBA. (http://www.Bullschmidt.com) */
/* Permission granted to freely use this file in your projects as long as the copyright */
/* and warranty disclaimers remain and the file is not distributed as your own utility tool. */
/* No warranties are either expressed or implied. */
/* Not responsible for any problems. */

var gboljpsjsIsUnsaved = false;  // Global var used by jpsjsIsUnsaved() and jpsjsSetUnsaved().

function jpsjsAreYouSureDel() {
	// Purpose: Ask user if sure wants to delete.
	// Author:  JPS, 9/2000.
	// Remarks: Used by delete buttons' onclick.
	//					Example: onclick="return jpsjsAreYouSureDel();"

	// Dim var.
	var bolOKToDel;

	// Init.
	bolOKToDel = true;

	// Ask if OK to del.
	if (!confirm('Are you sure you want to delete this record?')) { 
		// Set var.
		bolOKToDel = false;
	}

	// Return val.
	return bolOKToDel;
}

// - - - - -

function jpsjsAskUnsaved() {
	// Purpose: If jpsjsIsUnsaved(), then asks user if sure wants
	//					to leave pg.
	// Author:  JPS, 8/2000, 10/2000.
	// Remarks:  A savable form is considered unsaved after fld changed.
	//					Uses gboljpsjsIsUnsaved global var.
	//					Used in conj. w/ jpsjsIsUnsaved() and jpsjsSetUnsaved().
	//					Example: onclick="return jpsjsAskUnsaved();"

	// Dim var .
	var bolOKToContinue;

	// Init.
	bolOKToContinue = true;

	// If unsaved, ask if OK to continue.
	if (jpsjsIsUnsaved()) {
		if (!confirm('Data has not been saved.\n\nAre you sure you want to continue without saving?')) { 
			// Set var.
			bolOKToContinue = false;
		}
	}

	// Return val.
	return bolOKToContinue;
}

// - - - - -

function jpsjsCNum(pvarFld) {
	// Purpose: Strip non-numeric symbols
	//					(that are still allowed by jpsjsIsNumeric())
	//					and return a number (0 if not numeric).
	// Author:  JPS, 10/2000.
	// Remarks: Used by jpsjsFormat().
	//					Example returns: 23000.2, -23, 23%

	// Dim var.
	var varFld;

	// Set var.
	varFld = pvarFld.toString();

	// Quick exit if not num.
	if (!jpsjsIsNumeric(varFld)) {
		varFld = 0;
		return varFld;
	}

	// Replace any ( w/ - to preserve any negativity.
	// (And later code will remove any ) at end.)
	varFld = varFld.replace(/\(/g, "-");

	// Strip other non-numeric chars (that are still allowed by jpsjsIsNumeric()).
	// (But don't strip - and %)
	// (The g is for global search & replace instead of just doing first one.)
	varFld = varFld.replace(/\$/g, "");
	varFld = varFld.replace(/\,/g, "");
	varFld = varFld.replace(/\+/g, "");
	varFld = varFld.replace(/\)/g, "");

	// Convert to num.
	// (parseFloat stops when next ch is nonnumeric, but hopefully won't be any.)
	varFld = parseFloat(varFld);

	// Return val.
	return varFld;
}

// - - - - -

function jpsjsFormat(pvarFld, pstrFormat) {
	// Purpose: Format.
	// Author:  JPS, 10/2000, 2/2001.
	// Remarks: Used by jpsjsFormatFld.
	// 					Examples for pstrFormat:
	//						type:date;pattern:m/d/yyyy;isprobmsg:true
	//						type:number;pattern:$,0.00;neg:();blank:$0.00;prob:$0.00;isprobmsg:true
	//						type:number;pattern:,0
	//						type:number;pattern:0.0%
	//						type:number;pattern:0.0%notdataentry
	//						type:boolean;true:Yes;false:No
	//						type:string;ucase:all
	//						type:string;ucase:1
	//
	//					Usually  pattern w/ % in it means something like 57 entered
	//					by user acts like .57 which shows as 57% but if %notdataentry
	//					is in the pattern then .57 shows as 57%.
	//					There is similar code in VBScript.
	//					If pvarFld was blank or there was a problem, then if there was a blank: item, then
	//					return that, otherwise return Null.

	// Dim var.
	var strarrayFormat;
	var strFormatType;
	var varFld;
	var vararrayFldItems;
	var intMonth;
	var intDay;
	var intYr;
	var intCurYr;
	var intCurCentury;
	var strMonth;
	var strDay;
	var intItemNum;
	var strItemName;
	var strItemValue;
	var intItemLen;
	var intItemColonPos;
	var strBlank;
	var strProb;
	var bolIsProbMsg;
	var intItemFirstZeroPos;
	var intItemDecimalPos;
	var intItemDecimalPlaces;
	var intDecimalPos;
	var intDecimalPlaces;
	var intNumOfCharsBeforeDecimal;
	var intCommaNum;
	var intNumOfCommasNeeded;
	var intFirstCommaStartAfterPos;
	var intCommaStartAfterPos;
	var bolIsNeg;

	// Set var.
	varFld = pvarFld;

	// Split.
	strarrayFormat = pstrFormat.split(";");

	// Set var.
	intItemLen = strarrayFormat[0].length;
	intItemColonPos = strarrayFormat[0].indexOf(":");
	strFormatType = strarrayFormat[0].substring(intItemColonPos + 1, strarrayFormat[0].length);

	// Init.
	strBlank = varFld;
	strProb = varFld;
	bolIsProbMsg = false;

	// Calc strBlank and strProb.
	// Loop thru format items.
	// Start at 1 since 0 is just the format type.
	for (intItemNum = 1; intItemNum < strarrayFormat.length; intItemNum++) {
		intItemLen = strarrayFormat[intItemNum].length;
		intItemColonPos = strarrayFormat[intItemNum].indexOf(":");
		strItemName = strarrayFormat[intItemNum].substring(0, intItemColonPos)
		strItemValue = strarrayFormat[intItemNum].substring(intItemColonPos + 1, strarrayFormat[intItemNum].length);

		// If there's a "blank" item name, then set var.
		if (strItemName == "blank") strBlank = strItemValue;

		// If there's a "prob" item name, then set var.
		if (strItemName == "prob") strProb = strItemValue;

		// If there's a "isprobmsg" item name, then set var.
		if (strItemName == "isprobmsg") bolIsProbMsg = strItemValue;
	}

	// Quick exit if blank.
	if (varFld.toString() == "") return strBlank;

	// Loop thru format items.
	// Start at 1 since 0 is just the format type.
	for (intItemNum = 1; intItemNum < strarrayFormat.length; intItemNum++) {
		intItemLen = strarrayFormat[intItemNum].length;
		intItemColonPos = strarrayFormat[intItemNum].indexOf(":");
		strItemName = strarrayFormat[intItemNum].substring(0, intItemColonPos)
		strItemValue = strarrayFormat[intItemNum].substring(intItemColonPos + 1, strarrayFormat[intItemNum].length);

		switch (strFormatType) {
			case "date" :
				switch (strItemName) {
					case "pattern" :
						switch (strItemValue) {
							case "m/d/yyyy" :
								vararrayFldItems = varFld.split("/");
								// Quick exit if x not nums in x/x.
								// (Don't check the final x since it's optional x/x/x).
								if (isNaN(vararrayFldItems[0]) || isNaN(vararrayFldItems[1])) {
									// If bolIsProbMsg, then show msg.
									if (bolIsProbMsg) alert("The last entry is not a valid date.");
									return strProb;
								}
								// Remove any leading 0.
								intMonth = vararrayFldItems[0] / 1;
								intDay = vararrayFldItems[1] / 1;
								// Calc cur yr.
								// (Some old versions of JavaScript show yr as yrs since 1900.)
								if (new Date(2000, 0, 1).getYear() == 100) {
									intCurYr = new Date().getYear() + 1900;
								}
								else {
									intCurYr = new Date().getYear();
								}
								// If no final x or it's not a number in x/x/x, make yr the cur yr.
								if (isNaN(vararrayFldItems[2])) {
									intYr = intCurYr;
								}
								else {
									intYr = vararrayFldItems[2] / 1;
								}
								// Convert 1 (such as from 01) -> 2001.
								if (intYr < 100) {
									// Calc century.
									intCurCentury = Math.floor((intCurYr / 100)) * 100;
									intYr = intCurCentury + intYr;
								}
								varFld = intMonth + "/" + intDay + "/" + intYr;
								break;
							case "dd-mmm-yyyy" :
								vararrayFldItems = varFld.split("-");
								// Quick exit if x not num in x-word.
								// (Don't check the final x since it's optional x-word-x).
								if (isNaN(vararrayFldItems[0])) {
									// If bolIsProbMsg, then show msg.
									if (bolIsProbMsg) alert("The last entry is not a valid date.");
									return strProb;
								}
								// Remove any leading 0.
								intDay = vararrayFldItems[0] / 1;
								// Add leading 0.
								if (intDay < 10) {
									strDay = "0" + intDay;
								}
								else {
									strDay = intDay;
								}
								// Capitalize 1st char of mo.
								strMonth = vararrayFldItems[1];
								strMonth = strMonth.substring(0, 1).toUpperCase() + strMonth.substring(1, strMonth.length)	
								// Calc cur yr.
								// (Some old versions of JavaScript show yr as yrs since 1900.)
								if (new Date(2000, 0, 1).getYear() == 100) {
									intCurYr = new Date().getYear() + 1900;
								}
								else {
									intCurYr = new Date().getYear();
								}
								// If no final x or it's not a number in x/x/x, make it cur yr.
								if (isNaN(vararrayFldItems[2])) {
									intYr = intCurYr;
								}
								else {
									intYr = vararrayFldItems[2] / 1;
								}
								// Convert 1 (such as from 01) -> 2001.
								if (intYr < 100) {
									intCurCentury = Math.floor(intCurYr / 100) * 100;
									intYr = intCurCentury + intYr;
								}
								varFld = strDay + "-" + strMonth + "-" + intYr;
								break;
						}
						break;
				}
				break;
			case "number" :
				switch (strItemName) {
					case "pattern" :
						// Quick exit if not a num.
						if (!jpsjsIsNumeric(varFld)) {
							// If bolIsProbMsg, then show msg.
							if (bolIsProbMsg) alert("The last entry is not a valid number.");
							return strProb;
						}
	
						// Set var based on pattern.
						intItemFirstZeroPos = strItemValue.indexOf("0");
						intItemDecimalPos = strItemValue.indexOf(".");
						if (intItemDecimalPos > -1) {
							intItemDecimalPlaces = strItemValue.lastIndexOf("0") - intItemDecimalPos;
						}
						else {
							intItemDecimalPlaces = 0;
						}

						// Strip unneeded chars.
						varFld = jpsjsCNum(varFld);
						varFld = varFld.toString();

						// If % at end, remove it and div by 100.
						if (varFld.lastIndexOf("%") > -1) {
							varFld = varFld.substring(0, varFld.length - 1);
							// Div by 100.
							varFld = varFld / 100;
						}
						// Else if % in pattern but not %notdataentry in pattern, then div by 100.
						else {
							if ((strItemValue.lastIndexOf("%") > -1) && (strItemValue.lastIndexOf("%notdataentry") == -1)) {
							// Div by 100.
							varFld = varFld / 100;
							}
						}

						// Round.
						// (If % in pattern, then x 100.)
						if (strItemValue.lastIndexOf("%") > -1) {
							varFld = jpsjsRound(varFld * 100, intItemDecimalPlaces);
						}
						else {
							varFld = jpsjsRound(varFld, intItemDecimalPlaces);
						}

						// Convert to string again.
						varFld = varFld.toString();

						// Pad 0's after decimal (and a 0 before decimal) if needed.
						// If there's a decimal in pattern.
						if (intItemDecimalPos > -1) {
							intDecimalPos = varFld.lastIndexOf(".");
							// If there's a decimal in fld.
							if (intDecimalPos > -1) {
								// Pad 0's after decimal if needed.
								intDecimalPlaces = varFld.length - intDecimalPos - 1;
								if (intDecimalPlaces < intItemDecimalPlaces) {
									varFld = varFld + jpsjsRepeatTextLen("0", intItemDecimalPlaces - intDecimalPlaces);
								}
								// Pad a 0 before decimal if needed.
								if (intDecimalPos == 0) {
									varFld = "0" + varFld;
								}
							}
							else {
								// Add decimal and pad 0's after decimal.
								varFld = varFld + "." + jpsjsRepeatTextLen("0", intItemDecimalPlaces);
							}
						}

						// If neg, temporarily remove neg sgn and set flag.
						if (varFld < 0) {
							// Remove neg sgn.
							varFld = varFld.substring(1, varFld.length);
							bolIsNeg = true;
						}
						else {
							bolIsNeg = false;
						}

						// Commas.
						if (strItemValue.indexOf(",") > -1) {
							if (intItemDecimalPlaces > 0) {
								intNumOfCharsBeforeDecimal = varFld.length - intItemDecimalPlaces - 1;
							}
							else {
								intNumOfCharsBeforeDecimal = varFld.length;
							}

							intNumOfCommasNeeded = Math.floor((intNumOfCharsBeforeDecimal - 1) / 3);
							if (intNumOfCommasNeeded > 0) {
								// % is JavaScript's MOD.
								intFirstCommaStartAfterPos = intNumOfCharsBeforeDecimal % 3;
								// Adj. 0 to 3 so first comma starts after 3rd char in 555555.
								if (intFirstCommaStartAfterPos == 0) intFirstCommaStartAfterPos = 3;
								
								for (intCommaNum = 1;  intCommaNum <= intNumOfCommasNeeded;  intCommaNum++) {
									// 4 instead of 3 because of the inserted comma.
									intCommaStartAfterPos = intFirstCommaStartAfterPos + ((intCommaNum - 1) * 4);
									varFld = varFld.substring(0, intCommaStartAfterPos) + "," + varFld.substring(intCommaStartAfterPos, varFld.length);
								}
							}	
						}

						// $.
						if (strItemValue.indexOf("$") > -1) {
							varFld = "$" + varFld;
						}

						// -.
						if (bolIsNeg) {
							varFld = "-" + varFld;
						}

						// %.
						if (strItemValue.lastIndexOf("%") > -1) {
							varFld = varFld + "%";
						}

						break;

					case "neg" :
						//()
						if (bolIsNeg) {
							// Remove neg sgn and enclose w/ approp. chars such as ().
							varFld = strItemValue.substring(0, 1) + varFld.substring(1, varFld.length) + strItemValue.substring(strItemValue.length - 1, strItemValue.length);
						}
				}
				break;

			case "boolean" :
				// Quick exit if not a number.
				if (!jpsjsIsNumeric(varFld)) {
					// If bolIsProbMsg, then show msg.
					if (bolIsProbMsg) alert("The last entry is not a valid true or false entry.");
					return strProb;
				}

				// True/False conversions.
				switch (strItemName) {
					case "true" :
						if (varFld) varFld = strItemValue;
						break;
					case "false" :
						if (!varFld) varFld = strItemValue;
						break;
				}
			case "string" :
				// True/False conversions.
				switch (strItemName) {
					case "ucase" :
						if (strItemValue == "all") {
							varFld = varFld.toUpperCase();
							break;
						}
						if (strItemValue == "1") {
							varFld = varFld.substring(0, 1).toUpperCase() + varFld.substring(1, varFld.length);
							break;
						}
				}
		}
	}

	// Return val.
	return varFld;
}

// - - - - -

function jpsjsFormatFld(pstrFldName, pstrFormat) {
	// Purpose: Format fld.
	// Author:  JPS, 10/2000.
	// Remarks: Used by fld's onblur.
	//					Uses jpsjsFormat().

	// Set fld.
	eval("document.frmMain." + pstrFldName).value = jpsjsFormat(eval("document.frmMain." + pstrFldName).value, pstrFormat);
}

// - - - - -

function jpsjsIsNumeric(pvarFld) {
	// Purpose: See if is numeric.
	// Author:  JPS, 3/2000-4/2000, 10/2000.
	// Remarks: Returns true if OK or false if not.
	//					Intended to work roughly the same as IsNumeric() in VBScript.
	//					Only allow 0123456789$,.+-()%
	//					Only allow one:  .+-()
	//					VBScript also would only allow +-( to be first and ) to be
	//					final and not allow + along with -
	//				 	Used by jpsjsCNum(), jpsjsFormat(), and jpsjsValid().

	// Dim var.
	var varFld;
	var strAllowedChars;
	var bolIsNumeric;
	var ch;
	var i;
	var j;

	// Init.
	varFld = pvarFld.toString();
	strAllowedChars = "0123456789$,.+-()%";
	bolIsNumeric = true;

	// Quick exit if blank, -, +, %, or $.
	if ((varFld == "") || (varFld == "-") || (varFld == "+") || (varFld == "%") || (varFld == "$")) {
		return false;
	}

	// Loop.
	for (i = 0;  i < varFld.length;  i++) {
		ch = varFld.charAt(i);
		for (j = 0;  j < strAllowedChars.length;  j++) {
			if (ch == strAllowedChars.charAt(j))
				break;
		}
		// If no break in preceding 3 lines of code then ch is not in string.
		if (j == strAllowedChars.length) {
			bolIsNumeric = false;
			break;
		}
	}
	
	// Only allow one:  .+-()%
	if (varFld.indexOf(".") != varFld.lastIndexOf("."))
		bolIsNumeric = false;
	if (varFld.indexOf("+") != varFld.lastIndexOf("+"))
		bolIsNumeric = false;
	if (varFld.indexOf("-") != varFld.lastIndexOf("-"))
		bolIsNumeric = false;
	if (varFld.indexOf("(") != varFld.lastIndexOf("("))
		bolIsNumeric = false;
	if (varFld.indexOf(")") != varFld.lastIndexOf(")"))
		bolIsNumeric = false;
	if (varFld.indexOf("%") != varFld.lastIndexOf("%"))
		bolIsNumeric = false;

	// Return.
	return bolIsNumeric;
}

// - - - - -

function jpsjsIsUnsaved() {
	// Purpose: Gets status of gboljpsjsIsUnsaved global var.
	// Author: 	JPS, 8/2000.
	// Remarks: A savable form is considered unsaved after fld changed.
	//					Uses gboljpsjsIsUnsaved global var.
	//					Used in conj. w/ jpsjsAskUnsaved() and jpsjsSetUnsaved().

	// Return val.
	return gboljpsjsIsUnsaved;
}

// - - - - -

function jpsjsNumToHexByte(pintValue) {
	// Purpose: Returns a 2-character hexadecimal string representation of the specified byte value (0-255).
	// Author:  JPS, 4/2000.
	// Remarks: Used by jpsjsNumToHexColor and RGBToHex.
	//          Example: 255 --> FF

	var hi = (pintValue >> 4) & 0x0F;
	var lo = pintValue & 0x0F;
	var digit = "0123456789ABCDEF";
	return digit.charAt(hi) + digit.charAt(lo);
}

// - - - - -

function jpsjsRandomColor() {
	// Purpose: Random color.
	// Author:  JPS, 5/2000.
	// Remarks: Uses jpsjsRGBToHex().

	// Dim var.
	var intRed;
	var intGreen;
	var intBlue;

	// Randomize color.
	intRed = jpsjsRandomInt(0, 255);
	intGreen = jpsjsRandomInt(0, 255);
	intBlue = jpsjsRandomInt(0, 255);

	// Return val.
	return jpsjsRGBToHex(intRed, intGreen, intBlue);
}

// - - - - -

function jpsjsRandomColorItem(pstrItemID) {
	// Purpose: Change object color.
	// Author:  JPS, 5/2000.
	// Remarks: Item is usually a DIV.
	//					If object not visible it still doesn't hurt to change the color.
	//					This may be used by onmouseover from divTeaser* in ShowTeaser(), but Netscape doesn't
	//					seem to acknowledge onmouseover for something while page is being loaded.
	//					If user plays w/ this a lot, page loading is somewhat slower (example: constant playing
	//					was 25% longer to load on old PC).
	//					Uses jpsjsRandomColor().

	// If IE.
	// Change color.
	if (navigator.userAgent.indexOf("MSIE") != -1) {
		eval("document.all." + pstrItemID).style.color = jpsjsRandomColor();
	}
	else {
		eval("document." + pstrItemID).color = jpsjsRandomColor();
	}
}

// - - - - -

function jpsjsRandomInt(pintMin, pintMax) {
	// Purpose: Random integer.
	// Author:  JPS, 4/2000.

	// Return val.
	return Math.round(Math.random() * (pintMax - pintMin)) + pintMin;
}

// - - - - -

function jpsjsRefreshPg(pstrFldName) {
	// Purpose: Refresh pg. to update other fld(s) based on selection.
	// Author:  JPS, 9/2000.
	// Remarks: Used by combo's onchange.
	//					Assumes existence of document.frmMain.FocusedFldName hidden fld.

	// Set focused fld for when come back.
	document.frmMain.FocusedFldName.value = pstrFldName;

	// Msg.
	alert("Refreshing page to update other field(s) based on your selection.");

	// Submit pg to itself to refresh other combo based on this combo.
	document.frmMain.submit();
}

// - - - - -

function jpsjsRepeatTextLen(pstrText, pintNumOfChars) {
    // Purpose:	Repeat string.
    // Author:	JPS, 5/2000, 8/2000, 10/2000.
    
    // Dim var.
    var strText;
    var intNumOfTimes;
    var I;
    
    // Init.
    strText = "";
    
    // Set intNumOfTimes to be enough to generate at least the right num of chars.
    intNumOfTimes = Math.ceil(pintNumOfChars / pstrText.toString().length);

    // Make string at least long enough, and maybe longer.
		for (I = 0;  I < intNumOfTimes;  I++) {
    	strText = strText + pstrText;
		}

    // Reduce len of string if needed.
    strText = strText.substring(0, pintNumOfChars);

    // Return val.
    return strText;
}

// - - - - -

function jpsjsRGBToHex(pintRed, pintGreen, pintBlue) {
	// Purpose: Returns the standard HTML color string corresponding to the specified color.
	// Author:  JPS, 4/2000.
	// Remarks: Uses jpsjsNumToHexByte.
	// 	   			Used by jpsjsRandomColor().
	//          Example: 0, 0, 255 --> #0000FF

	// Return val.
	return "#" + jpsjsNumToHexByte(pintRed) + jpsjsNumToHexByte(pintGreen) + jpsjsNumToHexByte(pintBlue);
}

// - - - - -

function jpsjsRound(pvarNum, pintDecimalPlaces) {
	// Purpose: Round.
	// Author:  JPS, 10/2000.
	// Remarks: Used by jpsjsFormat().

	// Dim var.
	var varNum;

	// Set var.
	varNum = pvarNum;

	// Multiply.
	// Example: If using 2 decimal places convert 235.6789 --> 23567.89
	varNum = varNum * Math.pow(10, pintDecimalPlaces);

	// Round to nearest whole number.
	varNum = Math.round(varNum);

	// Divide.
	// Example: If using 2 decimal places convert 23568. --> 235.68
	varNum = varNum / Math.pow(10, pintDecimalPlaces);

	// Return val.
	return varNum;
}

// - - - - -

function jpsjsSetUnsaved(pbolIsUnsaved) {
	// Purpose: Sets status of gboljpsjsIsUnsaved global var.
	// Author:  JPS, 8/2000.
	// Remarks: A savable form is considered unsaved after fld changed.
	//					Uses gboljpsjsIsUnsaved global var.
	//					Used in conj. w/ jpsjsAskUnsaved() and jpsjsIsUnsaved().

	// Set global var.
	gboljpsjsIsUnsaved = pbolIsUnsaved;

	// Return val.
	return gboljpsjsIsUnsaved;
}

// - - - - -

function jpsjsShowList(pstrFldName, pbolIsShowList) {
	// Purpose: Refresh pg. to show combo box.
	// Author:  JPS, 10/2000.
	// Remarks: Used by btnShowList's onclick.
	//					Assumes existence of document.frmMain.FocusedFldName hidden fld.
	//					Assumes existance of document.frmMain.MyFldIsShowList... (Example: CustNumIsShowList).

	// Set MyFldIsShowList fld to true or false.
	eval("document.frmMain." + pstrFldName + "IsShowList").value = pbolIsShowList;

	// Set focused fld for when come back.
	document.frmMain.FocusedFldName.value = pstrFldName;

	// Submit pg to itself to refresh other combo based on this combo.
	document.frmMain.submit();
}

// - - - - -

function jpsjsTrim(pvarFld) {
	// Purpose: Trim fld.
	// Author:  JPS, 10/2000.
	// Remarks: Remove leading and trailing spaces (char 032 or char 160).
	//					Not designed to handle &nbsp;
	
	// Dim var.
	var strFld;
	var intFirstNonSpaceCh;
	var intFinalNonSpaceCh;
	var ch;
	var chCode;
	var i;

	// Init.
	strFld = pvarFld.toString();

	// Quick exit if blank.
	if (strFld == "") {
		return "";
	}

	// Init.
	intFirstNonSpaceCh = -1;

	// Find pos of 1st non-space ch.
	// Loop.
	for (i = 0;  i < strFld.length;  i++) {
		chCode = strFld.charCodeAt(i);
		// If not space char 32 or 160.
		if (chCode != 32 && chCode != 160) {
			intFirstNonSpaceCh = i;
			break;
		}
	}

	// Quick exit if no non-space ch's.
	if (intFirstNonSpaceCh == -1) {
		return "";
	}

	// Find pos of final non-space ch.
	// Loop.
	for (i = strFld.length - 1;  i >= 0;  i--) {
		chCode = strFld.charCodeAt(i);
		// If not space char 32 or 160.
		if (chCode != 32 && chCode != 160) {
			intFinalNonSpaceCh = i;
			break;
		}
	}

	// Extract non-space ch's.
	strFld = strFld.substring(intFirstNonSpaceCh, intFinalNonSpaceCh + 1);

	// Return val.
	return strFld;
}

// - - - - -

function jpsjsValid(pvarFld, pstrFldLabel, pstrType, pbolRequired) {
	// Purpose: Validate fld.
	// Author:  JPS, 3/2000, 8/2000, 10/2000, 12/2000, 3/2001.
	// Remarks: Returns validation msg if a problem.
	//					Includes \n (JavaScript alert box new line) after each message in case
	//					want to later concatenate into one alert box msg.
	//					Return is past tense to be consistent w/ VBScript where an invalid item might later
	//					get reshown as blank depending on how the fld is formatted.
	//					Date not yet developed.
	//					There is similar code in VBScript.

	// Dim var.
	var strValidMsg;

	// Init.
	strValidMsg = "";

	// If required and is blank.
	if (pbolRequired && pvarFld == "") {
		strValidMsg = pstrFldLabel + " cannot be blank.\n";
	}
	// If not required and is blank.
	else if (!pbolRequired && pvarFld == "") {
		// Do nothing.
		}
	else {
		// Select type.
		if (pstrType == "number") {
			if (!jpsjsIsNumeric(pvarFld))
				strValidMsg = pstrFldLabel + " is not a valid number.\n";
		}
		else if (pstrType == "date") {
			// Yet to be developed.
		}
		else if (pstrType == "email") {
			// Example: x@x.x
			if (pvarFld.indexOf("@") < 1 || pvarFld.indexOf(".") < 3)
				strValidMsg = pstrFldLabel + " is not a valid e-mail address.\n";
		}
		else if (pstrType == "string") {
			// Do nothing.
		}
	}

	// Return val.
	return strValidMsg;
}

// - - - - -

function jpsjsYetToBeDev() {
	// Purpose: Yet to be developed msg and stop.
	// Author:  JPS, 9/2000.
	// Remarks: Used by buttons' onclick.
	//					Example: onclick="return jpsjsYetToBeDev();"

	// Msg.
	alert("Yet to be developed.");

	// Return val.
	return false;
}
