﻿//----------------------------------------------------------------------// T O D L I B . J S// Copyright (c) 2001-2003 Tom Ogden// CREATED: 2001-09-21// DESCRIPTION: Library of JavaScript functions for web sites. // SECTIONS: //      UTILITY FUNCTIONS//      FILTERING & VALIDATION FUNCTIONS//      COOKIE FUNCTIONS//      SHOPPING CART FUNCTIONS//      OBSOLETE FUNCTIONS// 2003-06-12: Organized and formatted.//----------------------------------------------------------------------// AJAX FUNCTIONS//----------------------------------------------------------------------// FUNCTION: runRequest// INPUT: src, task// OUTPUT: revise and alert// DESCRIPTION: Replace the text object with data from the URL. // CREATED: 2008-06-23//----------------------------------------------------------------------function runRequest ( src, id ) { 	var XMLHttpRequestObject = false;	if ( window.XMLHttpRequest ) {		XMLHttpRequestObject = new XMLHttpRequest ( );	} else if ( window.ActiveXObject ) {		XMLHttpRequestObject = new ActiveXObject ( "Microsoft.XMLHTTP" );	}			if ( XMLHttpRequestObject ) {		XMLHttpRequestObject.open ( "GET", src );				XMLHttpRequestObject.onreadystatechange = function ( ) {			if ( XMLHttpRequestObject.readyState == 4 				&& XMLHttpRequestObject.status == 200 			) {				var myblock = document.getElementById ( id );						myblock.innerText = XMLHttpRequestObject.responseText;			}		}		XMLHttpRequestObject.send ( null );	}}//----------------------------------------------------------------------// FUNCTION: href2block// INPUT: href, blockID// OUTPUT: // DESCRIPTION: Load data from href into an ID block object. // CREATED: 2008-12-18//----------------------------------------------------------------------function href2block ( href, blockID ) { 	var XMLHttpRequestObject = false;	if ( window.XMLHttpRequest ) {		XMLHttpRequestObject = new XMLHttpRequest ( );	} else if ( window.ActiveXObject ) {		XMLHttpRequestObject = new ActiveXObject ( "Microsoft.XMLHTTP" );	}			if ( XMLHttpRequestObject ) {		XMLHttpRequestObject.open ( "GET", href );				XMLHttpRequestObject.onreadystatechange = function ( ) {			if ( XMLHttpRequestObject.readyState == 4 				&& XMLHttpRequestObject.status == 200 			) {				var myblock = document.getElementById ( blockID );						myblock.innerHTML = XMLHttpRequestObject.responseText;			}		}		XMLHttpRequestObject.send ( null );	}	}//----------------------------------------------------------------------// FUNCTION: setModalBlock// INPUT: href, blockID// OUTPUT: // DESCRIPTION: Load data from href into an ID block object. // CREATED: 2008-12-18//----------------------------------------------------------------------function setModalBlock ( href ) { 	// Load the block. 	var blockID = "mBlock";	href2block ( href, blockID )	// Expose the mask.	var mask = document.getElementById ( "mask" );	mask.style.height = window.innerHeight;		mask.style.visibility = "visible";	// Expose the modal block, centered horizontally. 	var block = document.getElementById ( blockID );		var bwidth = 400; //arbitrary until we can calculate block width. 	var leftpos = ( window.innerWidth - bwidth ) / 2; 	if ( leftpos < 0 ) leftpos = 0; 	block.style.left = leftpos;	block.style.visibility = "visible";}//----------------------------------------------------------------------// FUNCTION: closeModalBlock// INPUT: href, blockID// OUTPUT: // DESCRIPTION: Close the open ID block object. // CREATED: 2008-12-18//----------------------------------------------------------------------function closeModalBlock ( blockID ) { 	// Load the block. 	// href2block ( href, blockID )	// Hide the modal block.	var block = document.getElementById ( blockID );		block.style.visibility = "hidden";	// Hide the mask.	var mask = document.getElementById ( "mask" );		mask.style.visibility = "hidden";}//----------------------------------------------------------------------// FUNCTION: keyPressHandler// INPUT: event// OUTPUT: // DESCRIPTION: Handle the key that is pressed. // CREATED: 2008-12-18//---------------------------------------------------------------------- function keyPressHandler ( event ) {      var escOrd = 27;      if ( event.keyCode == escOrd )         closeModalBlock ( "mBlock" );   } //----------------------------------------------------------------------// FUNCTION: ajax_updateValue// INPUT: textID, o, id, entry, v// OUTPUT: alert// DESCRIPTION: Change VALUE of an entry. Intervene with confirmation // before calling do_method.php.// CREATED: 2008-06-23//----------------------------------------------------------------------function ajax_updateValue ( textID, o, id, entry, arg ) { 			var now = new Date ( );	if ( arg == "now" ) arg = now.toLocaleTimeString ( );	var q = "Update field '" + entry + "' to '" + arg + "'?";	if ( newarg = prompt ( q, arg ) ) {		var phpScript  = "/bin/ajax/do_entry.php";			phpScript += "?o=" + o;			phpScript += "&id=" + id;			phpScript += "&e=" + entry;			phpScript += "&arg=" + newarg;					runRequest ( phpScript, textID );	}	}//----------------------------------------------------------------------// FUNCTION: ajax_updateBoolean// INPUT: textID, o, id, entry, v// OUTPUT: alert// DESCRIPTION: Change VALUE of an entry. Intervene with confirmation // before calling do_method.php.// CREATED: 2008-06-23//----------------------------------------------------------------------function ajax_updateBoolean ( textID, o, id, entry, arg ) { 			var now = new Date ( );	var newarg = 0;	if ( arg == 0 ) {		newarg = 1; 	}			var phpScript  = "/bin/ajax/do_entry.php";		phpScript += "?o=" + o;		phpScript += "&id=" + id;		phpScript += "&e=" + entry;		phpScript += "&arg=" + newarg;			runRequest ( phpScript, textID );}//----------------------------------------------------------------------// FUNCTION: valueUpdate// INPUT: textID, o, id, m, arg// OUTPUT: revise and alert// DESCRIPTION: Run the method to replace the text. // CREATED: 2008-03-04//----------------------------------------------------------------------function valueUpdate ( textID, o, id, m, arg ) { 	if ( XMLHttpRequestObject ) {	var phpScript  = "/bin/ajax/do_method.php";		phpScript += "?o=" + o;		phpScript += "&id=" + id;		phpScript += "&m=" + m;		phpScript += "&arg=" + arg;		XMLHttpRequestObject.open ( "GET", phpScript );		XMLHttpRequestObject.onreadystatechange = function ( ) {			if ( XMLHttpRequestObject.readState == 4 				&& XMLHttpRequestObject.status == 200 			) {				chtxtID ( txtID, XMLHttpRequestObject.responseText );			}		}		XMLHttpRequestObject.send ( null );	}}//----------------------------------------------------------------------// FUNCTION: filterDistinct// INPUT: field, table// OUTPUT: revise and alert// DESCRIPTION: Call script query for match, empty value if match found. // CREATED: 2008-01-15//----------------------------------------------------------------------function filterDistinct ( input, table ) { 	if ( myInput.value.length > 0 ) {		if ( XMLHttpRequestObject ) {		var phpScript  = "/bin/ajax/do_distinct.php";			phpScript += "?field=" + input.name + "&table=" + table;			phpScript += "&value=" + input.value;			XMLHttpRequestObject.open ( "GET", phpScript );			XMLHttpRequestObject.onreadystatechange = function ( ) {				if ( XMLHttpRequestObject.readState == 4 					&& XMLHttpRequestObject.status == 200 				) {					if ( XMLHttpRequestObject.responseText > 0 ) {						alert ( "Field value '" + input.value + "' is already taken." );						input.value = "";						input.select ( );						return ( false );					} else {						return( true );					}				}			}			XMLHttpRequestObject.send ( null );		}	} else {		 return( true );	}}//----------------------------------------------------------------------// FUNCTION: chpicID// INPUT: imgID, filename// OUTPUT: // DESCRIPTION: Load new picture into <img> object from picture library. // CREATED: 2007-12-04//----------------------------------------------------------------------function chpicID ( imgID, newfilename ) {	var img = document.getElementById ( imgID );	var partsArray = img.src.split ( "/" );	var filename = partsArray.pop ( );			partsArray.push ( newfilename );			img.src = partsArray.join ( "/" );}//----------------------------------------------------------------------// FUNCTION: chtxtID// INPUT: txtID, newtxt// OUTPUT: // DESCRIPTION: Load new string text into an ID text object. // CREATED: 2008-01-14//----------------------------------------------------------------------function chtxtID ( txtID, newtxt ) {	var myblock = document.getElementById ( txtID );			myblock.innerText = newtxt;}//----------------------------------------------------------------------// FUNCTION: chblockID// INPUT: newData, blockID// OUTPUT: // DESCRIPTION: Load new string data into an ID block object. // CREATED: 2008-12-18//----------------------------------------------------------------------function chblockID ( newData, blockID ) {	alert ( "Entering function..." );	var myblock = document.getElementById ( blockID );			myblock.innerHTML = newData;}//----------------------------------------------------------------------// UTILITY FUNCTIONS//----------------------------------------------------------------------// FUNCTION: test// INPUT: // OUTPUT: alert string// DESCRIPTION: Test this library for globally crippling syntax errors.// CREATED: //----------------------------------------------------------------------function test () {	alert("Library toDlib is active.");}//----------------------------------------------------------------------// FUNCTION: isEmpty// INPUT: inputStr// OUTPUT: true or false// DESCRIPTION: Test value for empty string or null.// CREATED: 2003-07-07//----------------------------------------------------------------------function isEmpty ( inputStr ) {	if ( inputStr == null || inputStr == "" ) {		return ( true );	}	return ( false );}//----------------------------------------------------------------------// FUNCTION: setImage// INPUT: myImage, newImage// OUTPUT: changes image// DESCRIPTION: Create a rollover.// CREATED: //----------------------------------------------------------------------function setImage(myImage,newImage) {	myImage.src = newImage.src;}//----------------------------------------------------------------------// FUNCTION: sequenceImages// INPUT: imageArray, imageIndex, imageName (all globals)// OUTPUT: changes images// DESCRIPTION: Used by 'rotateImages' to change images using global // variables of conventional names. Go through 'setImage'.// CREATED: 2004-01-28//----------------------------------------------------------------------function sequenceImages ( ) {	setImage ( document.imageName, imageArray[imageIndex] );	imageIndex++;	if ( imageIndex >= imageArray.length ) imageIndex = 0;}//----------------------------------------------------------------------// FUNCTION: rotateImages// INPUT: delay// OUTPUT: Sets an Interval to change images// DESCRIPTION: Rotate an array of images through an IMG tag. // CREATED: 2004-01-27//----------------------------------------------------------------------function rotateImages ( delay ) {	var intervalID = setInterval ( "sequenceImages ( )", delay );}// DEPROCATE 2008-01-27: imageCollection variable is not found and causes// error, which is repeated in an infinite loop. //----------------------------------------------------------------------// FUNCTION: sequenceImagesRand// INPUT: imageArray, imageIndex, imageName (all globals)// OUTPUT: changes images// DESCRIPTION: Rotate images on random sets of pictures, with given interval.// CREATED: 2005-10-26//----------------------------------------------------------------------// function sequenceImagesRand ( ) {// 	var arrayIndex = Math.floor ( Math.random ( ) * ( imageCollection.length + 1 ) );// 	var imgIndex = imageIndex[arrayIndex];// 		// 	setImage ( document.images["imageName"+arrayIndex], imageCollection[arrayIndex][imgIndex] );// 	imgIndex++;// 	if ( imgIndex >= imageCollection[arrayIndex].length ) imgIndex = 0;// 	imageIndex[arrayIndex] = imgIndex;// }// DEPROCATE 2008-01-27: Calls sequenceimagesRand which causes// error, which is repeated in an infinite loop. //----------------------------------------------------------------------// FUNCTION: rotateImagesRand// INPUT: delay// OUTPUT: Sets an Interval to change images// DESCRIPTION: Call randomSequenceImages to randomly select arrays // of images to rotate// CREATED: 2005-10-25//----------------------------------------------------------------------// function rotateImagesRand ( delay ) {// 	delay = Math.floor ( Math.random ( ) * delay ) + 1;// 	var intervalID = setInterval ( "sequenceImagesRand ( )", delay );// }//----------------------------------------------------------------------// FUNCTION: str2hex// INPUT: myStr// OUTPUT: hexStr// DESCRIPTION: Encrypt any text string to a collection of hex codes.// CREATED: 2003-06-11// 2007-08-10: Force numbers to string type. //----------------------------------------------------------------------function str2hex ( myStr ) {	var hexStr = "";	var thisCharCode = "";	myStr = "" + myStr; // Ensure numbers are converted to string type	for ( i = 0; i < myStr.length; i++ ) {		thisCharCode = myStr.charCodeAt ( i );		hexStr += thisCharCode.toString ( 16 );		}		return hexStr.toUpperCase ( );}//----------------------------------------------------------------------// FUNCTION: hex2str// INPUT: myHex// OUTPUT: newStr// DESCRIPTION: Decrypt a block of hex codes to the original string.// CREATED: 2003-06-11// 2008-12-01: Change variable 'i' to 'hexi' to prevent affecting enclosing functions. //----------------------------------------------------------------------function hex2str ( myHex ) {	var newStr = "";	var hexChar = "";	var charCode;	var isEven = false;	for ( hexi = 0; hexi < myHex.length; hexi++ ) {		if ( isEven ) {			isEven = false;			hexChar += myHex.charAt ( hexi );			charCode = parseInt ( hexChar, 16 );			newStr += String.fromCharCode ( charCode );		} else {			isEven = true;			hexChar = myHex.charAt ( hexi );		}	}		return newStr;}//----------------------------------------------------------------------// FUNCTION: strContains// INPUT: str, substr// OUTPUT: boolean// DESCRIPTION: Determine if substring is contained in string.// Always case-sensitive turned on. // CREATED: 2008-11-29 from PHP function of same name. //----------------------------------------------------------------------function strContains ( str, substr ) {	var result = str.indexOf ( substr, 0 );		// Not found is -1. Found is position, which COULD be zero. 	if ( result > -1 ) {		return ( true );	} else {		return ( false );	}}	//----------------------------------------------------------------------// FUNCTION: listPlugins// INPUT: // OUTPUT: // DESCRIPTION: List all plugins installed in this browser. // DOES NOT WORK IN IE. // CREATED: 2008-11-29//----------------------------------------------------------------------function listPlugins ( ) {	if (navigator.plugins != null && navigator.plugins.length > 0) { 		for ( var i = 0; i < navigator.plugins.length; i++ ) {			document.write ( i + ": " + navigator.plugins[i].name + "<br />" );		}	} else {		document.write ( "No navigator plugins found.<br />" );	}		return ( i );}//----------------------------------------------------------------------// FUNCTION: hasPlugin// INPUT: name// OUTPUT: boolean// DESCRIPTION: Check browser arrays for a given plugin.// DOES NOT WORK IN IE. // CREATED: 2008-11-29//----------------------------------------------------------------------function hasPlugin ( name ) {	if (navigator.plugins != null && navigator.plugins.length > 0) { 		for ( var i = 0; i < navigator.plugins.length; i++ ) {			if ( strContains ( navigator.plugins[i].name, name ) ) {				return ( true );			}		}	}		return ( false );}//----------------------------------------------------------------------// FUNCTION: hasPluginIE// INPUT: name// OUTPUT: boolean// DESCRIPTION: Check IE for an exact plugin. Name must be completely accurate. // Made especially for IE. // CREATED: 2008-11-29//----------------------------------------------------------------------function hasPluginIE ( name ) {	var version;	var axo;	var e;	try {		axo = new ActiveXObject ( name );		version = axo.GetVariable ( "$version" );	} catch ( e ) {	}	if ( version ) {		return ( true );	} else {		return ( false );	}}//----------------------------------------------------------------------// FUNCTION: compare// INPUT: v0, v1// OUTPUT: result// DESCRIPTION: Compare 2 values and return integer for a sorting array. // CREATED: 2005-01-11//----------------------------------------------------------------------function compare ( v0, v1 ) {	if ( v0 == v1 ) return ( 0 );	if ( v0 > v1 ) return ( 1 );	if ( v0 < v1 ) return ( -1 );}//----------------------------------------------------------------------// FUNCTION: delImage// INPUT: src, object, name// OUTPUT: alert// DESCRIPTION: Obtain approval, then forward to record delete script.// CREATED: 2002-10-20//----------------------------------------------------------------------function delImage ( dirPath, object, name ) { 	var q  = "Are you sure you want to permanently \r";		q += "delete the image for " + object + " \r";		q += "'" + name + "'?";				if ( confirm ( q ) ) {		setMarker ( "p" );		var newLoc = "do_del.php?o=image&d=" + dirPath;		window.location = newLoc;	}}//----------------------------------------------------------------------// FUNCTION: delRecord// INPUT: object, id, name// OUTPUT: alert// DESCRIPTION: Obtain approval, then forward to record delete script.// CREATED: 2002-10-20//----------------------------------------------------------------------function delRecord ( object, id, name ) { 	var q = "Are you sure you want to permanently delete " + object + " '" + name + "'?";				if ( confirm ( q ) ) {		setMarker ( "" );		var newLoc = "do_del.php?id=" + id + "&o=" + object;		window.location = newLoc;	}}//----------------------------------------------------------------------// FUNCTION: canRecord// INPUT: object, id, name// OUTPUT: alert// DESCRIPTION: Change status to zero/false and back, depending on current status.// CREATED: 2003-06-24//----------------------------------------------------------------------function canRecord ( object, id ) { 			//-- var q = "Are you sure you want to change the status of this " + object + "?";	//--if ( confirm ( q ) ) {		var newLoc = "do_can.php?id=" + id + "&o=" + object;		setMarker ( "" );		window.location = newLoc;	//--}}//----------------------------------------------------------------------// FUNCTION: confirmChanges// INPUT: URI, alertStr// OUTPUT: // DESCRIPTION: Send changes to do_execute, but ask for approval first.// CREATED: 2005-06-30//----------------------------------------------------------------------function confirmChanges ( URI, alertStr ) { 	var approval = false;		if ( URI.length ) {		approval = confirm ( alertStr );	} else {		approval = true;		}		if ( approval ) {		var newLoc = "do_execute.php" + URI;		setMarker ( "" );		window.location = newLoc;	} else {		window.history[0];	}}//----------------------------------------------------------------------// FUNCTION: updateField// INPUT: o, id, entry, v// OUTPUT: alert// DESCRIPTION: Change contents of a field. Intervene with confirmation // before calling do_updateField.php.// CREATED: 2005-04-12// 2005-10-17: Change from 'confirm' to 'promp' to enable user ammendment.//----------------------------------------------------------------------function updateField ( o, id, entry, v ) { 			var now = new Date ( );	if ( v == "now" ) v = now.toLocaleTimeString ( );	var q = "Update field '" + entry + "' to '" + v + "'?";	if ( answ = prompt ( q, v ) ) {		var newLoc = "do_updateField.php?";		newLoc += "o=" + o;		newLoc += "&id=" + id;		newLoc += "&entry=" + entry;		newLoc += "&value=" + answ;		setMarker ( "" );		window.location.href = newLoc;	}}//----------------------------------------------------------------------// FUNCTION: submitChild// INPUT: myForm// OUTPUT: // DESCRIPTION: Pack form data into a valuePod string and insert into // parentEntry's form field.// CREATED: 2006-11-07//----------------------------------------------------------------------function submitChild ( myForm, parentEntry, id ) {	var serialArray = new Array ( );	for ( j = 0; j < myForm.elements.length; j++ ) {		serialArray[j] = str2hex ( myForm.elements[j].name );		serialArray[j] += ":" + str2hex ( myForm.elements[j].value );	}	var vPod = id + ";" + serialArray.join ( ";" );	window.close();	opener.focus();	var parentForm = opener.document.forms[0];	parentForm.elements[parentEntry].value = vPod;	parentForm.action = opener.location.href;	parentForm.submit ( );}//----------------------------------------------------------------------// FUNCTION: prependField// INPUT: o, id, entry, v// OUTPUT: alert// DESCRIPTION: Push a string into the front of a field. Intervene with // confirmation before calling do_prependField.php.// CREATED: 2006-09-23//----------------------------------------------------------------------function prependField ( o, id, entry, v ) { 			var now = new Date ( );	if ( v == "now" ) v = now.toLocaleTimeString ( );	var q = "Update field '" + entry + "' to '" + v + "'?";	if ( answ = prompt ( q, v ) ) {		var newLoc = "do_prependField.php?";		newLoc += "o=" + o;		newLoc += "&id=" + id;		newLoc += "&entry=" + entry;		newLoc += "&value=" + answ;		setMarker ( "" );		window.location = newLoc;	}}//----------------------------------------------------------------------// FUNCTION: reSearch// INPUT: argArrayStr// OUTPUT: location.search// DESCRIPTION: Revisit the current page while updating the search string.// CREATED: 2003-07-10//----------------------------------------------------------------------function reSearch ( argArrayStr ) { 			var searchStr = "";	var argArray = argArrayStr.split ( ";" );	for ( i = 0; i < argArray.length; i++ ) {		var myArg = argArray[i].split ( "," );		if ( i == 0 ) {			searchStr += "?";		} else {			searchStr += "&";		}		searchStr += myArg[0] + "=" + myArg[1];	}		window.location.search = searchStr;}//----------------------------------------------------------------------// FUNCTION: this2value// INPUT: myControl, otherControl// OUTPUT: // DESCRIPTION: Translate the checked state of a checkbox to the value of// another control, using the value of the checkbox; also set value to value.// CREATED: 2003-08-02// 2003-09-23: Broadened to other controls, file input in particular.//----------------------------------------------------------------------function this2value ( myControl, otherControl ) { 	if ( myControl.type == "checkbox" ) {		if ( myControl.checked ) {			otherControl.value = myControl.value;		} else {			if ( myControl.value == "1" ) {				otherControl.value = 0;			} else {				otherControl.value = "";			}		}	} else {		otherControl.value = myControl.value;	}	}//----------------------------------------------------------------------// FUNCTION: this2IDvalue// INPUT: myControl, otherControlID// OUTPUT: // DESCRIPTION: Translate the checked state of a checkbox to the value of// another control, using the value of the checkbox; also set value to value.// Adapted from this2value, but uses AJAX ID call. // CREATED: 2007-12-05//----------------------------------------------------------------------function this2IDvalue ( myControl, otherControlID ) { 	var otherControl = document.getElementById ( otherControlID );	if ( myControl.type == "checkbox" ) {		if ( myControl.checked ) {			otherControl.value = myControl.value;		} else {			if ( myControl.value == "1" ) {				otherControl.value = 0;			} else {				otherControl.value = "";			}		}	} else {		otherControl.value = myControl.value;	}	}//----------------------------------------------------------------------// FUNCTION: checklist2IDvalue// INPUT: myControl, otherControlID// OUTPUT: // DESCRIPTION: Translate the checked state of a checkbox to the value of// another control, using the value of the checkbox; also set value to value.// Adapted from this2value, but uses AJAX ID call. // CREATED: 2007-12-05//----------------------------------------------------------------------function checklist2IDvalue ( seriesName, seriesCount, otherControlID ) { 	var newValArray = new Array ( );		// Walk thru controls and collect values	for ( i = 0; i < seriesCount; i++ ) {			var myControl = document.getElementById ( seriesName + "_" + i );		if ( myControl.type == "checkbox" ) {			if ( myControl.checked ) {				newValArray.push ( myControl.value );			}		}	}	// Merge values into a string	var otherControl = document.getElementById ( otherControlID );	otherControl.value = newValArray.join ( "," );}//----------------------------------------------------------------------// FILTERING & VALIDATION FUNCTIONS//----------------------------------------------------------------------// FUNCTION: parseOutAlpha// INPUT: myStr// OUTPUT: newValue// DESCRIPTION: Remove all alpha chars from number. Allow one decimal.// CREATED: 2003-06-06//----------------------------------------------------------------------function parseOutAlpha ( myStr ) {	var strlen = myStr.length + 3;	var charNum = 0;	var newStr = "";	var FOUNDdot = false;	for ( var i = 0; !isNaN ( charNum = myStr.charCodeAt ( i ) ); i++ ) {		if ( charNum >= 48 && charNum <= 57  ) {			newStr += String.fromCharCode ( charNum );		} else if ( charNum == 46 && !FOUNDdot ) {			FOUNDdot = true;			newStr += String.fromCharCode ( charNum );		}	}	newValue = parseFloat ( newStr );	return newValue;}//----------------------------------------------------------------------// FUNCTION: softSubmit// INPUT: myForm, myAction// OUTPUT: // DESCRIPTION: Submit form to alternate action, cancel checkForm.// Action may resubmit to same form or to alternate check script.// CREATED: 2003-07-11//----------------------------------------------------------------------function softSubmit ( myForm, myAction ) {	myForm.action = myAction + "?s=0";	myForm.onSubmit  = "";	myForm.submit ( );}//----------------------------------------------------------------------// FUNCTION: filterInt// INPUT: myInput, min, max// OUTPUT: revise and alert// DESCRIPTION: Gives alert if value is out of range and corrects it.// CREATED: 2003-06-06//----------------------------------------------------------------------function filterInt ( myInput, min, max, label ) { 	var newValue = parseInt ( parseOutAlpha ( myInput.value ) );	if ( isNaN ( newValue ) ) newValue = 0;	if ( newValue < min ) {		myInput.value = min;		alert ( label + " must be at least " + min + "." );		myInput.select ( );	} else if ( newValue > max ) {		myInput.value = max;		alert ( "Sorry, but " + newValue + " is too high.\n" + label + " cannot be greater than " + max + "." );		myInput.select ( );	} else {		myInput.value = newValue;	}}//----------------------------------------------------------------------// FUNCTION: filterUBI// INPUT: myInput// OUTPUT: revise and alert// DESCRIPTION: Gives alert if value is not a legal UBI and removes it.// CREATED: 2005-03-26//----------------------------------------------------------------------function filterUBI ( myInput ) { 	var myStr = myInput.value;	var strlen = myStr.length;	var charNum = 0;	var newStr = "";	for ( var i = 0; !isNaN ( charNum = myStr.charCodeAt ( i ) ); i++ ) {		if ( charNum >= 48 && charNum <= 57  ) {			newStr += String.fromCharCode ( charNum );		}	}	if ( !isNaN ( newStr ) ) {		if ( newStr.length == 9 ) {			myInput.value = newStr.substr ( 0, 3 ) + " " + newStr.substr ( 3, 3 ) + " " + newStr.substr ( 6, 3 );			return;		}	}	alert ( "Sorry, but '" + myStr + "' was not a valid entry.\n UBI must have 9 digits and no letters." );	myInput.value = "";	myInput.select ( );}//----------------------------------------------------------------------// FUNCTION: filterUC// INPUT: myInput// OUTPUT: ( changed string value )// DESCRIPTION: Changes contents to upper case.// CREATED: 2003-07-24//----------------------------------------------------------------------function filterUC ( myInput ) { 	myInput.value = myInput.value.toUpperCase ( );}//----------------------------------------------------------------------// FUNCTION: filterDate// INPUT: myInput// OUTPUT: ( changed string value, alert )// DESCRIPTION: Adds slashes when missing and alerts the user. This is// quite limited, as the intelligence needed can be great.// CREATED: 2003-12-13//----------------------------------------------------------------------function filterDate ( myInput ) { 	if ( myInput.value.length > 0 ) {		var myStr = myInput.value;		var newStr = "";		var partsArray = myStr.split ( "/" );		if ( partsArray.length == 1 ) {			var partsArray = myStr.split ( "-" );			if ( partsArray.length == 1 ) {				if ( myStr.length == 6 ) {					newStr  = myStr.substr ( 0, 2 ) + "/";					newStr += myStr.substr ( 2, 2 ) + "/";					newStr += myStr.substr ( 4, 2 );					myInput.value = newStr;					alert ( "The date you entered has been corrected. Please confirm that it is correct." );				} else if ( myStr.length == 8 ) {					newStr  = myStr.substr ( 0, 2 ) + "/";					newStr += myStr.substr ( 2, 2 ) + "/";					newStr += myStr.substr ( 4, 4 );					myInput.value = newStr;					alert ( "The date you entered has been corrected. Please confirm that it is correct." );				} else if ( myStr.length < 8 ) {					alert ( "The date you entered is not in a recognized format." );				}			}		}		return ( false );	} else {		return ( true );	}	}//----------------------------------------------------------------------// FUNCTION: filterEmail// INPUT: myInput// OUTPUT: revise and alert// DESCRIPTION: Gives alert if value is not a valid address.// CREATED: 2003-06-06//----------------------------------------------------------------------function filterEmail ( myInput ) { 	if ( myInput.value.length > 0 ) {		var myAddress = myInput.value.replace ( /</, "" );		myAddress = myAddress.replace ( />/, "" );		myAddress = myAddress.replace ( /\"/, "" );		myAddress = myAddress.replace ( /\'/, "" );		myAddress = myAddress.replace ( /\?/, "" );		myAddress = myAddress.replace ( /&/, "" );		myAddress = myAddress.replace ( / /, "" );		myAddress = myAddress.replace ( /\t/, "" );		myInput.value = myAddress;				var partsArray = myAddress.split ( "@" );		if ( partsArray.length == 2 ) {			if ( partsArray[0].length > 0 ) {				var part2 = partsArray[1];				domainArray = part2.split ( "." );				if ( domainArray.length == 2 ) {					if ( domainArray[0].length > 0 ) {						var tld = domainArray[1];						if ( tld.length >= 2 && tld.length <= 4 ) {							return ( true );						}					}				}			}		}				alert ( "E-mail address is not valid." );		myInput.select ( );		return ( false );	} else {		return ( true );	}}//----------------------------------------------------------------------// FUNCTION: filterCreditCard// INPUT: myInput// OUTPUT: revise and alert// DESCRIPTION: Gives alert if value is not a valid address.// CREATED: 2006-11-09//----------------------------------------------------------------------function filterCreditCard ( myInput ) { 	if ( myInput.value.length > 0 ) {		var ccnLength = 16;		var newCCN = "";				// CLEAN OUT NON-DIGITS		var ccNumber = parseOutAlpha ( myInput.value ) + ""; // Add empty string to convert to string type.		ccNumber = ccNumber.replace ( /\./, "" );		if ( ccNumber.length > ccnLength ) 			ccNumber = ccNumber.substr ( 0, ccnLength );		// RE-INSERT SPACES FOR DISPLAY		for ( k = 0; k < ccNumber.length; k++ ) {			if ( ( k > 0 ) && ( k % 4 == 0 ) ) newCCN += " ";						var chr = ccNumber.charAt ( k );			newCCN += chr;		}				// FEED BACK INTO FIELD		myInput.value = newCCN;				// INSPECT AND RESPOND		if ( ccNumber.length < ccnLength ) {			alert ( "Credit card number is not valid." );			myInput.select ( );			return ( false );		} else {			return ( true );		}	} else {		return ( true ); // empty, but not wrong	}}//----------------------------------------------------------------------// FUNCTION: nameFromPath// INPUT: path// OUTPUT: name// DESCRIPTION: Parses a filepath for a filename using filterFilename, // then parses the filename for a name. // CREATED: 2006-10-12//----------------------------------------------------------------------function nameFromPath ( path ) { 	var filename = filterFilename ( path );		var partsArray = filename.split ( "." );		var name = partsArray.shift ( );	return ( name );}//----------------------------------------------------------------------// FUNCTION: filterFilename// INPUT: path// OUTPUT: filename// DESCRIPTION: Parses a filepath for a filename, DOS & Unix formats.// CREATED: 2005-10-19//----------------------------------------------------------------------function filterFilename ( path ) { 	var partsArray = path.split ( "\\" );	if ( partsArray.length == 1 ) 		partsArray = path.split ( "/" );		var filename = partsArray.pop ( );	return ( filename );}//----------------------------------------------------------------------// FUNCTION: chkGraphicFormat// INPUT: path// OUTPUT: filename// DESCRIPTION: Looks at the file's extension to verify valid graphic format.// CREATED: 2006-02-25//----------------------------------------------------------------------function chkGraphicFormat ( input ) { 	var filename = filterFilename ( input.value );	var partsArray = filename.split ( "." );	if ( partsArray.length >= 2 ) {		var extension = partsArray.pop ( );		extension = extension.toUpperCase ( );		switch ( extension ) {			case "JPG":				return ( true );				break;			case "JPEG":				return ( true );				break;			case "GIF":				return ( true );				break;			case "GIFF":				return ( true );				break;			case "PNG":				return ( true );				break;			default:				alert ( "This file, with extension '." + extension + "', does not appear to be a valid graphic format.\r\rFiles should be of type .JPG, .GIF or .PNG." );				break;		}	} else {		alert ( "This file has not extension and does not appear to be a valid graphic format.\r\rFiles should be of type .JPG, .GIF or .PNG." );	}		input.value = "";	return ( false );}//----------------------------------------------------------------------// FUNCTION: checkForm// INPUT: myInput, min, max// OUTPUT: revise and alert// DESCRIPTION: Gives alert if value is out of range and corrects it.// CREATED: 2003-06-06//----------------------------------------------------------------------function checkForm ( myForm ) {	var checkArray = myForm.checkArrayStr.value.split ( ";" );	for ( i = 0; i < checkArray.length; i++ ) {		var fieldArray = checkArray[i].split ( "," );		var chkbxName = fieldArray[0] + "Chkbx";		for ( j = 0; j < myForm.elements.length; j++ ) {			if ( myForm.elements[j].name == fieldArray[0] ) {				if ( isEmpty ( myForm.elements[j].value ) ) {					alert ( "Please fill in the '" + fieldArray[1] + "' field." );					myForm.elements[j].focus ( );					return ( false );				} else if ( 					myForm.elements[j].value == 0 					&& myForm.elements[chkbxName].type == "checkbox"				) {					alert ( "You must select the '" + fieldArray[1] + "' checkbox to submit." );					myForm.elements[chkbxName].focus ( );					return ( false );				}			}		}	}return ( true );}//----------------------------------------------------------------------// FUNCTION: enableForm// INPUT: myForm// OUTPUT: // DESCRIPTION: Enables all inputs within the form.// CREATED: 2005-09-14//----------------------------------------------------------------------function enableForm ( myForm ) {	for ( i = 0; i < myForm.elements.length; i++ ) {		myForm.elements[i].disabled = false;	}}//----------------------------------------------------------------------// FUNCTION: enableAB// INPUT: myForm, A, B// OUTPUT: // DESCRIPTION: Enables inputs within the form with indexes from A to B.// CREATED: 2007-03-24//----------------------------------------------------------------------function enableAB ( myForm, A, B ) {	for ( i = A; i <= B; i++ ) {		myForm.elements[i].disabled = false;	}}//----------------------------------------------------------------------// FUNCTION: wakePrompt// INPUT: myForm// OUTPUT: // DESCRIPTION: Enables specified input on condition of emptyness.// CREATED: 2006-06-21//----------------------------------------------------------------------function wakePrompt ( myInput ) {if(document.searchForm.searchText.disabled){document.searchForm.searchText.disabled=false;document.searchForm.searchText.value='';document.searchForm.searchText.focus();document.searchForm.searchText.select();}	for ( i = 0; i < myForm.elements.length; i++ ) {		myForm.elements[i].disabled = false;	}}//----------------------------------------------------------------------// COOKIE FUNCTIONS//----------------------------------------------------------------------// FUNCTION: setCookie// INPUT: name, value, interval// OUTPUT: cookie// DESCRIPTION: Creates a cookie. Interval is seconds from now to expiration.// CREATED: 2003-06-05, by Tom Ogden Design. All rights reserved.//----------------------------------------------------------------------function setCookie ( name, value, interval ) { 	//-- interval must be in seconds. 	interval = interval * 1000; //-- Change to milliseconds for setTime.	var expiration = new Date ( );	var timeInt = expiration.getTime ( ) + interval	expiration.setTime ( timeInt );	cookieStr = name + "=" + value; //-- Eliminate spaces in cookies.	cookieStr += "; expires=";	cookieStr += expiration.toGMTString ( );	cookieStr += "; path=/";	document.cookie = cookieStr;}//----------------------------------------------------------------------// FUNCTION: copyCookie// INPUT: name0, name1// OUTPUT: cookie// DESCRIPTION: Copy an existing cookie into another cookie by new name.// CREATED: 2007-06-12, by Tom Ogden Design. All rights reserved.//----------------------------------------------------------------------function copyCookie ( name0, name1 ) { 	//-- interval must be in seconds. 	interval = 84600 * 1000; //-- Change to milliseconds for setTime.	var expiration = new Date ( );	var timeInt = expiration.getTime ( ) + interval	expiration.setTime ( timeInt );		//-- Value	var value = getCookieData ( name0 );	cookieStr = name1 + "=" + value; //-- Eliminate spaces in cookies.	cookieStr += "; expires=";	cookieStr += expiration.toGMTString ( );	cookieStr += "; path=/";	document.cookie = cookieStr;}//----------------------------------------------------------------------// FUNCTION: cookie2entryArray// INPUT: name// OUTPUT: entryArray// DESCRIPTION: Read a dataclass cookie and parse its fields into an array. // CREATED: 2008-12-01, by Tom Ogden. All rights reserved.// No associative keys are allowed in JavaScript. //----------------------------------------------------------------------function cookie2entryArray ( name ) { 	var data = getCookieData ( name );	var entryArray = [];	var partsArray = data.split ( "." );	var partsArray2 = partsArray[2].split ( "|" );	for ( ic2e = 0; ic2e < partsArray2.length; ic2e++ ) {		var entry = partsArray2[ic2e].split ( ":" );		entry[0] = hex2str ( entry[0] );		entry[1] = hex2str ( entry[1] );		entryArray[ic2e] = entry;	}		return ( entryArray );}//----------------------------------------------------------------------// FUNCTION: cookie2Form// INPUT: cookie, myForm// OUTPUT: // DESCRIPTION: Populate the values of a form with entryArray from cookie. // CREATED: 2008-12-02, by Tom Ogden. All rights reserved.//----------------------------------------------------------------------function entryArray2Form ( cookie, myForm ) { 	entryArray = cookie2entryArray ( cookie );	for ( mkey in entryArray ) {		if (typeof myForm.elements[entryArray[mkey][0]] != 'undefined') {			myForm.elements[entryArray[mkey][0]].value = entryArray[mkey][1];		} else {			//alert ( "No control exists named '" + entryArray[mkey][0] + "'." );		}	}}//----------------------------------------------------------------------// FUNCTION: delCookie// INPUT: name// OUTPUT: // DESCRIPTION: Deletes the specified cookie.// CREATED: 2003-07-24// 2007-08-10: Make it actually work by using setCookie. //----------------------------------------------------------------------function delCookie ( name ) { 	setCookie ( name, "", 0 );}//----------------------------------------------------------------------// FUNCTION: getCookieData// INPUT: label// OUTPUT: cookie's data field// DESCRIPTION: Given cookie label, get it's data// CREATED: 2002-10-21//----------------------------------------------------------------------function getCookieData ( label ) { 	var labelLen = label.length;	var cookieLen = document.cookie.length;	var cookieEnd;	for ( var i = 0; i < cookieLen; i++ ) {		var j = i + labelLen;		if ( document.cookie.substring ( i, j ) == label ) {			cookieEnd = document.cookie.indexOf ( ";", j );			if ( cookieEnd < 0 ) {				cookieEnd = document.cookie.length;			}			return unescape ( document.cookie.substring ( j+1, cookieEnd ) );		}	}	return false;}//----------------------------------------------------------------------// FUNCTION: cookiesEnabled// INPUT: // OUTPUT: true or false if enabled// DESCRIPTION: Test for browser enabled cookies by creating a test cookie // and looking to see if it exists. // CREATED: 2003-07-21//----------------------------------------------------------------------function cookiesEnabled ( ) {	setCookie ( "temp", "1", 86400 ); // 1 day required for IE4 for Mac	if ( getCookieData ( "temp" ) ) {		return true;	} else {		return false;	}}//----------------------------------------------------------------------// FUNCTION: setMarker// INPUT: // OUTPUT: cookie// DESCRIPTION: Creates a cookie to mark the current Request URI, including variables.// CREATED: 2003-05-21//----------------------------------------------------------------------function setMarker ( pathIndex ) { 	if ( isEmpty ( pathIndex ) ) pathIndex = "";	var path = escape ( location.pathname );	path += escape ( location.search );	cookieStr  = "marker" + pathIndex + "=" + path; //-- Eliminate spaces in cookies.	cookieStr += "; path=/";	document.cookie = cookieStr;}//----------------------------------------------------------------------// FUNCTION: backTrack// INPUT: // OUTPUT: Go back to previous page// DESCRIPTION: Looks for marker cookie and goes back to that URI, using // href or assign, not pathname or search (which need to combine to make// up the URI. If not found, it goes back to the last page in history. // CREATED: 2003-05-21//----------------------------------------------------------------------function backTrack ( pathIndex ) {	if ( isEmpty ( pathIndex ) ) pathIndex = "";	var markerName = "marker" + pathIndex;	var marker = getCookieData ( markerName );	delCookie ( markerName );		if ( marker ) {		window.location.href = marker;	} else {		history.back ( );	}}//----------------------------------------------------------------------// FUNCTION: doSetCookie// INPUT: name, value, interval, path// OUTPUT: cookie// DESCRIPTION: More detailed version of setCookie, for testing// CREATED: 2003-08-20//----------------------------------------------------------------------function doSetCookie ( name, value, interval, path ) { 	//-- interval must be in seconds. 	interval = interval * 1000; //-- Change to milliseconds for setTime.	var expiration = new Date ( );	var timeInt = expiration.getTime ( ) + interval	expiration.setTime ( timeInt );	cookieStr = name + "=" + value; //-- Eliminate spaces in cookies.	cookieStr += "; expires=";	cookieStr += expiration.toGMTString ( );	cookieStr += "; path=";	cookieStr += path;	document.cookie = cookieStr;}//----------------------------------------------------------------------// FUNCTION: store2list// INPUT: value, cookieName, isRepeatable, doSort, interval (seconds)// OUTPUT: cookie// DESCRIPTION: Adds the value to a list of data stored in a cookie.// CREATED: 2005-01-11//----------------------------------------------------------------------function store2list ( value, cookieName, isRepeatable, doSort, interval ) { 	var myData = getCookieData ( cookieName );	if ( myData ) {		var dataStr = hex2str ( myData );		var contentArray = dataStr.split ( "|" );	} else {		var contentArray = new Array ( );	}		// Add to value to array.	if ( !isRepeatable ) {		// See if value is already there.		var inTHERE = false;		for ( var i = 0; i < contentArray.length; i++ ) { 			if ( contentArray[i] == value ) inTHERE = true;		}		if ( !inTHERE ) {			contentArray[contentArray.length] = value; // push doesn't work in IE5 for Mac			}	} else {		contentArray[contentArray.length] = value; // push doesn't work in IE5 for Mac		}		// Sort array.	if ( doSort ) contentArray.sort ( compare );		// Encode into Hex and store.	var newData = str2hex ( contentArray.join ( "|" ) );	setCookie ( cookieName, newData, interval );	return newData;}//----------------------------------------------------------------------// SHOPPING CART FUNCTIONS//----------------------------------------------------------------------// FUNCTION: item (object)// INPUT: index, id, qty, instrSrc, instr, isCustom, price// OUTPUT: // DESCRIPTION: Object constructor populates properties. // CREATED: 2003-06-12// 2003-07-23: Add index ID, not stored in Cookie but inferred at parse time.//----------------------------------------------------------------------function item ( id, productID, pieceID, summary, qty, instrSrc, instr, isCustom, price ) { 	this.id 		= id;	this.productID 	= productID;	this.pieceID 	= pieceID;	this.summary 	= summary;	this.qty 		= parseInt ( qty );	this.instrSrc 	= instrSrc;	this.instr 		= instr;	this.isCustom 	= isCustom;	this.price 		= price;}//----------------------------------------------------------------------// FUNCTION: add_n_items// INPUT: cartName, productID, pieceID, summary, myQty// OUTPUT: Update cookie// DESCRIPTION: Add a single item to the count. Mainly used by links w/o forms.// CREATED: 2006-10-17// 2007-04-13: Add cartName and myQty variables. myQty == 0 triggers prompt.//----------------------------------------------------------------------function add_n_items ( cartName, productID, pieceID, summary, myQty ) {	// Zero qty triggers Prompt. 	if ( myQty == 0 ) {		var response = prompt ( "Quantity to add to cart of \r'" + summary + "'?", 1 );	 	myQty = parseInt ( parseOutAlpha ( response ) );	}	if ( myQty < 1 ) myQty = 1;	var cartArray = new getCartArray ( cartName );	var instrSrc = "";	var isCustom = 0;	var price = 0;	var i = 0;	var totalQty = 0;	if ( cartArray.length > i ) {	// ADD TO CART THAT ALREADY HAS ITEMS		// Parse cart to find matching product/piece		var isFound = false;		for ( var i = 0; i < cartArray.length && !isFound; i++ ) {			// If found, then add quantity			if ( productID == cartArray[i].productID && pieceID == cartArray[i].pieceID ) {				isFound = true;				cartArray[i].qty += myQty;				totalQty = cartArray[i].qty;			}		}				// If no matching product is found, add this item to the cart.		if ( !isFound ) {			var myItem = new item ( i, productID, pieceID, summary, myQty, instrSrc, "", isCustom, price );			cartArray[i] = myItem;			totalQty = myQty;		}	} else {	// ADD TO EMPTY CART		var myItem = new item ( i, productID, pieceID, summary, myQty, instrSrc, "", isCustom, price );		var cartArray = new Array ( myItem );		totalQty = myQty;	}	setCart ( cartName, cartArray );	alert ( "Total of " + totalQty + " units \r" + summary + "." );	//	history.go ( 0 );}//----------------------------------------------------------------------// FUNCTION: addItem// INPUT: cartname, productID, pieceID, summary, myForm, qtyIndex, instrSrc// OUTPUT: Update cookie// DESCRIPTION: Add item entry to cart and set cart cookie.// CREATED: 2003-06-12// array.push() & array.pop() are broken in IE5 for Mac. Work around.// 2007-04-13: Add cartName variable. //----------------------------------------------------------------------function addItem ( cartName, productID, pieceID, summary, myForm, qtyIndex, instrSrc ) { 	var myQty = parseInt ( myForm.elements[qtyIndex].value );	var cartArray = new getCartArray ( cartName );	var i = 0;	if ( cartArray.length > i ) {		var isFound = false;		for ( var i = 0; i < cartArray.length && !isFound; i++ ) {			if ( productID == cartArray[i].productID && pieceID == cartArray[i].pieceID ) {				if ( cartArray[i].instrSrc == "" ) {									isFound = true;					cartArray[i].qty += myQty;				}			}		}		if ( !isFound ) {			var myItem = new item ( i, productID, pieceID, summary, myQty, instrSrc, "" );			cartArray[i] = myItem;		}	} else {		var myItem = new item ( i, productID, pieceID, summary, myQty, instrSrc, "" );		var cartArray = new Array ( myItem );	}	setCart ( cartName, cartArray );		if ( instrSrc == "" ) {		history.go ( 0 );	} else {		setMarker ( "" );		window.location.href = "/products/details.php?id=" + i + "&instr=" + instrSrc;	}}//----------------------------------------------------------------------// FUNCTION: chQty// INPUT: id, qty// OUTPUT: alert// DESCRIPTION: Provides a way to discretely update just quantity of items.// CREATED: 2007-08-09//----------------------------------------------------------------------function chQty ( productID, pieceID, qty ) {	// DELETE ITEM IF QTY == 0	if ( qty == 0 ) {		newQty = 0;		// ELSE Ask for new quantity.	} else {		var newQty = prompt ( "How many items?", qty );		newQty = parseInt ( parseOutAlpha ( newQty ) );	}		// Load script page to execute. 	// NOTE: Must use same page to run script because of fault in 	// IE and Firefox that won't allow reload() after setting cookie. 		var oldLoc = window.location.href;	var newLoc = "1_cart.php";	newLoc += "?productID=" + productID;	newLoc += "&pieceID=" + pieceID;	newLoc += "&qty=" + newQty;	setMarker ( "" );	window.location.href = newLoc;		// Return to Cart Page	//window.location.href = oldLoc;	//window.location.reload ( );}//----------------------------------------------------------------------// FUNCTION: changeItem// INPUT: id, myForm, qtyIndex// OUTPUT: Update cookie// DESCRIPTION: Change item entry's qty and reset cart cookie.// CREATED: 2003-06-12// array.push() & array.pop() are broken in IE5 for Mac. Work around.// 2007-04-13: Add cartName variable. //----------------------------------------------------------------------function changeItem ( cartName, id, productID, pieceID, summary, myQty, instrSrc, instr, isCustom, price ) { 	var cartArray = new getCartArray ( cartName );	if ( cartArray.length > id ) {				cartArray[id].productID = productID;		cartArray[id].pieceID 	= pieceID;		cartArray[id].summary 	= summary;		cartArray[id].qty 		= myQty;		cartArray[id].instrSrc 	= instrSrc;		cartArray[id].instr 	= instr;		cartArray[id].isCustom 	= isCustom;		cartArray[id].price 	= price;	} else {		alert ( "The contents of the cart have been reduced unexpectectedly." )	}		setCart ( cartName, cartArray );}//----------------------------------------------------------------------// FUNCTION: delItem// INPUT: id// OUTPUT: Update cookie// DESCRIPTION: Delete all occurances of item entry from cart and set cart cookie.// CREATED: 2003-06-14// array.push() & array.pop() are broken in IE5 for Mac. Work around.// 2007-04-13: Add cartName variable. //----------------------------------------------------------------------function delItem ( cartName, myID ) { 	var cartArray = new getCartArray ( cartName );	var newCartArray = new Array ( );	var j = 0;	if ( cartArray.length > 0 ) {		for ( var i = 0; i < cartArray.length; i++ ) {			if ( cartArray[i].id != myID ) {				newCartArray[j++] = cartArray[i];			}		}			setCart ( cartName, newCartArray );	}	setMarker ( "" );	window.location.href = newLoc;}//----------------------------------------------------------------------// FUNCTION: submitItem// INPUT: myForm// OUTPUT: Update cookie// DESCRIPTION: Change item from Details form.// CREATED: 2003-07-24//----------------------------------------------------------------------function submitItem ( cartName ) { 	var myForm = document.detailsForm;		var id 			= myForm.id.value;	var productID 	= myForm.productID.value;	var pieceID 	= myForm.pieceID.value;	var summary 	= myForm.summary.value;	var myQty 		= myForm.qty.value;	var instrSrc 	= myForm.instrSrc.value;	var instr 		= myForm.instructions.value;	var isCustom	= myForm.isCustom.value;	var price		= myForm.price.value;	changeItem ( cartName, id, productID, pieceID, summary, myQty, instrSrc, instr );}//----------------------------------------------------------------------// FUNCTION: getCartArray// INPUT: cartName// OUTPUT: cartArray or false// DESCRIPTION: Read cart cookie and decrypt data to array.// CREATED: 2003-06-12// 2007-04-13: Add variable cart name.// 2007-08-10: Switch to 2D array. //----------------------------------------------------------------------function getCartArray ( cartName ) { 	var cartData = getCookieData ( cartName );	if ( cartData ) {		// Break into arguments of two dimensions.		var cartArray = cartData.split ( ":" );					var j = 0;		for ( var i = 0; i < cartArray.length; i++ ) { 			var lineArray = new Array ( );			lineArray = cartArray[i].split ( "." );						// Use if statement to filter corrupt entries			if ( lineArray.length == 8 && lineArray[0].length > 0 ) { 				var productID 	= hex2str ( lineArray[0] );				var pieceID 	= hex2str ( lineArray[1] );				var summary 	= hex2str ( lineArray[2] );				var qty 		= hex2str ( lineArray[3] );				var instrSrc 	= hex2str ( lineArray[4] );				var instr 		= hex2str ( lineArray[5] );				var isCustom	= hex2str ( lineArray[6] );				var price		= hex2str ( lineArray[7] );						cartArray[j] = new item ( j, productID, pieceID, summary, qty, instrSrc, instr, isCustom, price );				j++;			}		}	} else {		var cartArray = new Array ( );	}	return cartArray;	}//----------------------------------------------------------------------// FUNCTION: setCart// INPUT: cartArray// OUTPUT: cookie// DESCRIPTION: Creates a cookie to mark the current Request URI, including variables.// CREATED: 2003-05-21// array.push() & array.pop() are broken in IE5 for Mac. Work around.// 2007-04-13: Add cartName variable. // 2007-08-10: Revise to 2D array. //----------------------------------------------------------------------function setCart ( cartName, cartArray ) { 	var lineArray = new Array ( );	var cart2Darray = new Array ( );	var j = 0;	for ( var i = 0; i < cartArray.length; i++ ) {		lineArray[0] = str2hex ( cartArray[i].productID );		var productID = cartArray[i].productID;				lineArray[1] = str2hex ( cartArray[i].pieceID );		var pieceID = cartArray[i].pieceID;				lineArray[2] = str2hex ( cartArray[i].summary );		lineArray[3] = str2hex ( cartArray[i].qty );		lineArray[4] = str2hex ( cartArray[i].instrSrc );		lineArray[5] = str2hex ( cartArray[i].instr );		lineArray[6] = str2hex ( cartArray[i].isCustom );		lineArray[7] = str2hex ( cartArray[i].price );		cart2Darray[i] = lineArray.join ( "." );		j = 0;	}		var cartData = cart2Darray.join ( ":" );	var interval = 60 * 60 * 24 * 30; //-- Keep cart for 30 days	setCookie ( cartName, cartData, interval );	return cartData;}//----------------------------------------------------------------------// FUNCTION: checkRedundant// INPUT: myInput, redundantStr// OUTPUT: // DESCRIPTION: If string matches value, delete and alert.// CREATED: 2003-08-02//----------------------------------------------------------------------function checkRedundant ( myInput, redundantStr ) {	 if ( myInput.value == redundantStr ) {	 	myInput.value = "";	 	alert ( "Product style should not be the same as the product name.\rUnless a color or other material style applies, it's best to leave this field blank." );	 }}//----------------------------------------------------------------------// FUNCTION: syncAddresses// INPUT: bill2ship, myForm// OUTPUT: bill2shipON// DESCRIPTION: Checks checkbox and copies bill address to ship address// if ON, disabling shipping address. If off, enables shipping address.// CREATED: 2003-07-11//----------------------------------------------------------------------function syncAddresses ( bill2ship, myForm ) { 	if ( bill2ship.checked ) {		myForm.street1_1.value 			= myForm.street1_0.value;		myForm.street2_1.value 			= myForm.street2_0.value;		myForm.city_1.value 			= myForm.city_0.value;		myForm.state_1.selectedIndex 	= myForm.state_0.selectedIndex;		myForm.zip_1.value 				= myForm.zip_0.value;		myForm.street1_1.disabled 	= true;		myForm.street2_1.disabled 	= true;		myForm.city_1.disabled 		= true;		myForm.state_1.disabled 	= true;		myForm.zip_1.disabled 		= true;	} else {		myForm.street1_1.disabled 	= false;		myForm.street2_1.disabled 	= false;		myForm.city_1.disabled 		= false;		myForm.state_1.disabled 	= false;		myForm.zip_1.disabled 		= false;	}}//----------------------------------------------------------------------// XML FUNCTIONS//----------------------------------------------------------------------//----------------------------------------------------------------------// OBSOLETE FUNCTIONS//----------------------------------------------------------------------function comma2dec(Vnum) { //-- UPDATED 2001-12-05		var signage = "";	if ( Vnum < 0 ) {		Vnum = Math.abs(Vnum);		signage = "-";	}	if(Vnum > 99990000) {		alert("That number is outside legalparameters.");		focus();	} else {			var V10million =parseInt(Vnum / 10000000);		var V1million = (Vnum % 10000000)  / 1000000;		if(V1million / 1000000 == 1) {			V1million = 1;		} else if(V1million < 1) {			V1million = "0";		} else {			V1million =parseInt(V1million,10);		}		var V100thousand = (Vnum % 1000000)  / 100000;		if(V100thousand / 100000 == 1) {			V100thousand = 1;		} else if(V100thousand < 1) {			V100thousand = "0";		} else {			V100thousand =parseInt(V100thousand,10);		}		var V10thousand = (Vnum % 100000)  / 10000;		if(V10thousand / 10000 == 1) {			V10thousand = 1;		} else			if(V10thousand < 1) {			V10thousand = "0";		} else {			V10thousand =parseInt(V10thousand,10);		}		var V1thousand = (Vnum % 10000)  / 1000;		if(V1thousand / 1000 == 1) {			V1thousand = 1;		} else if(V1thousand < 1) {			V1thousand = "0";		} else {			V1thousand =parseInt(V1thousand,10);		}		var Vhundreds = (Vnum % 1000)  / 100;		if(Vhundreds / 100 == 1) {			Vhundreds = 1;		} else if(Vhundreds < 1) {			Vhundreds = "0";		} else {			Vhundreds =parseInt(Vhundreds,10);		}		var Vtens = (Vnum % 100)  / 10;		if(Vtens / 10 == 1) {			Vtens = 1;		} else if(Vtens < 1) {			Vtens = "0";		} else {			Vtens =parseInt(Vtens,10);		}		var Vones = (Vnum % 10)  / 1;		if(Vones / 1 == 1) {			Vones = 1;		} else if(Vones < 1) {			Vones = "0";		} else {			Vones =parseInt(Vones,10);		}		var Vcents =parseInt((((Vnum % 1) * 100)+0.5),10);		if(Vcents < 1) {			Vcents = "00";		} else if(Vcents % 10 == 0) {			Vcents = Vcents + "0";		} else if(Vcents % 10 == Vcents) {			Vcents = "0" + Vcents;		} else {			Vcents = Vcents;		}		if(Vcents == "900") {			Vcents = "90";		} else if(Vcents == "800") {			Vcents = "80";		} else if(Vcents == "700") {			Vcents = "70";		} else if(Vcents == "600") {			Vcents = "60";		} else if(Vcents == "500") {			Vcents = "50";		} else if(Vcents == "400") {			Vcents = "40";		} else if(Vcents == "300") {			Vcents = "30";		} else if(Vcents == "200") {			Vcents = "20";		} else if(Vcents == "100") {			Vcents = "10";		} else {			Vcents = Vcents;		}		var Vformat = "";		if(Vnum >= 10000000) {			Vformat = (V10million + "" + V1million + "," + V100thousand + "" + V10thousand + "" + V1thousand + "," + Vhundreds + "" + Vtens + "" + Vones + "." + Vcents);		} else if(Vnum >= 1000000) {			Vformat = (V1million + "," + V100thousand + "" + V10thousand + "" + V1thousand + "," + Vhundreds + "" + Vtens + "" + Vones + "." + Vcents);		} else if(Vnum >= 100000) {			Vformat = (V100thousand + "" + V10thousand + "" + V1thousand + "," + Vhundreds + "" + Vtens + "" + Vones + "." + Vcents);		} else if(Vnum >= 10000) {			Vformat = (V10thousand + "" + V1thousand + "," + Vhundreds + "" + Vtens + "" + Vones + "." + Vcents);		} else if(Vnum >= 1000) {			Vformat = (V1thousand + "," + Vhundreds + "" + Vtens + "" + Vones + "." + Vcents);		} else if(Vnum >= 100) {			Vformat = (Vhundreds + "" + Vtens + "" + Vones + "." + Vcents);		} else if(Vnum >= 10) {			Vformat = (Vtens + "" + Vones + "." + Vcents);		} else if(Vnum >= 1) {			Vformat = (Vones + "." + Vcents);		} else {			Vformat = ("0." + Vcents);		}		Vformat = signage + Vformat;		return Vformat;	}}