// JavaScript Document

/*
	addNameValuePair			= add a name/value pair to a url
	addNameValuePair			= ditto, different version
	checkForOneValue			= make sure a list of fields has at least one value
	checkMissingValues			= do some common validation
    clearAll					= clear all elements in all forms
    clearDocument				= clear all form elements in a document
    clearForm					= clear all form elements in a form
    concatCheckbox				= concat a check box value to a search string
    concatRadio					= concat a radio value to a search string
	concatSearchString			= concat a name/value pair to a search string
    concatSelect				= concat a select value to a search string
    concatText					= concat a text value to a search string
	concatUnknown				= concat a value of unknown type to a search string
    concatWords					= add a string to another string with a separator
	findElementByName			= find an element on a form by its name
    focusOnFirst				= focus to first text field in a form
    fromQueryStringToForm		= move elements from query string to form
    getCheckboxValue			= get the value of a checkbox
    getRadioChoice				= get the selected item in a radio button
    getRadioValue				= get the value of the checked radio button
    getSelected					= get the index of the selected item in a select list
    getSelectedValue			= get the value of the selected item in a select list
	getValueUnknownType			= get value from a field of unknown type
    hasData						= does a field have something
    isEmpty						= is a data field empty
    isEnterKey					= to see if the key just typed was the Enter key
    isSelect					= is a select box field
    showForms					= for debugging, shows the list of forms in an alert box.
    splitQueryString			= split a query string into its components
    submitIfEnter				= do a submit if enter key is struck
    uniqueName					= get a unique name, using date stamp and seconds
*/
//
//		addNameValuePair
//
/*		Add a name value pair to a url, figuring out whether to
		begin it with a ? or &.
		
		@param		url  --  current value of the url (required)
		@param		name --  the name for the name/value pair (required)
		@param		value--  the value for the name/value pair (opt)
		@return		the new url
*/
	function addNameValuePair( url, name, value )
	{
		var ans = url;
		
		if( hasData( url )  &&  hasData( name ) )
		{
			if( value == null )  value = "";
			
			ans = addNameValuePair2( url, name + "=" + value );
		}
		return( ans );
	}											// end addNameValuePair
//
//		addNameValuePair2
//
/*		Add a name value pair to a url, figuring out whether to
		begin it with a ? or &.  The pair has already been set up.
		
		@param		url  --  current value of the url (required)
		@param		pair --  the name/value pair (required)
		@return		the new url
*/
	function addNameValuePair2( url, pair )
	{
		var ans = url;
		
		if( hasData( url )  &&  hasData( pair ) )
		{
			var ix = url.indexOf( "?" );
			if( ix >= 0 )						// already has a pair
				ans = url + "&" + pair;
			else								// first pair
				ans = url + "?" + pair;
		}
		return( ans );
	}											// end addNameValuePair2
/*
		centerWindow  --  get the x and y coordinates for centering 
		a window.
		
		This is taken from Danny Goodwin, Javascrit & DHTML Cookbook,
		recipe 6.9 (the cross-browser modal dialog window).
		
		param -- w		= width of window (if none, will use 1/2 the outer window width)
		param -- h		= height of window (if none, will use 1/2 the outer window height)
		return -- pos   = object with 
						  pos.x -- the x coordinate
						  pos.y -- the y coordinate
						  pos.w -- the width (is the same as the passed param if that
									was passed)
						  pos.h -- the height (is the same as the passed param if that
									was passed)
*/
	function centerWindow( w, h )
	{
		var pos = new Object();
			
        if ( window.screenX ) 			// Netscape 4+
		{
            // Center on the main window.
			// If don't have inputs, make 'em up.
			if( isEmpty( w ) || w < 1 )  w = 2 * window.outerWidth / 3;
			if( isEmpty( h ) || h < 1 )  h = 2 * window.outerHeight / 3;
			
            pos.x = window.screenX + 
               ((window.outerWidth - w) / 2);
				
            pos.y = window.screenY + 
               ((window.outerHeight - h) / 2);
        } 
		else 
		{
            // The best we can do is center in screen.
			// If don't have inputs, make 'em up.
			if( isEmpty( w ) || w < 1 )  w = 2 * screen.width / 3;
			if( isEmpty( h ) || h < 1 )  h = 2 * screen.height / 3;
			
            pos.x = (screen.width - w) / 2;
			
            pos.y = (screen.height - h) / 2;
        }

		pos.w = w;								// in case set here
		pos.h = h;								// ditto
		return( pos );
	}											// end centerWindow
//
//		checkForOneValue
//
/*		Check certain fields on a form to make sure at least
		one of them has a value -- for validation.  Note:
		if a field doesn't exist on the form, it is considered
		to be empty.
		
		@param		form		the form (document.formname)
		@param		fieldNames	comma-delimited list of the field names to check
		@return		boolean		true  -- at least one field has a value.
								false -- no field has a value.

		if( ! checkForOneValue( document.myform,
						"full_name, yesno_ind, ssn" ) )
		{
			window.alert( "Please enter something" );
		}
*/
function checkForOneValue( form, fieldNames )
{
	var ans = false;
	
	var names = fieldNames.split( "," );
	var ix;
	var value;
/*
		Loop through all the names.
*/		
	for( ix = 0; ix < names.length; ix++ )
	{
		value = getValueUnknownType( form, names[ix] );
/*
		See if you have something.  If you do, you're all
		done.  If you don't, keep looking.
*/		
		if( hasData( value ) )
		{
			ans = true;
			break;
		}
	}											// end loop
	
	return( ans );
}												// end checkForOneValue
//
//		checkMissingValues
//
/*		Check certain fields on a form for missing values --
		to be used as part of validation before saving it.
		
		@param		form		the form (document.formname)
		@param		fieldNames	comma-delimited list of the field names to check
		@param		descriptions	comma-delmited list of the descriptions of 
								the fields, to
								use in an error message.  There needs to be
								one element here for each element in "fieldNames"
		@return		errorMsg	if null, all was fine.  Otherwise, a list
								of the fields (the descriptions) missing data.

		var msg = checkMissingValues( document.myform,
						"full_name, yesno_ind, ssn",
						"Full Name, Yes/No indicator, Social Security #" );
*/
function checkMissingValues( form, fieldNames, descriptions )
{
	var ans = null;
	
	var names = fieldNames.split( "," );
	var descs = descriptions.split( "," );
	
	var ix;
	var value;
/*
		Loop through all the names.
		Does not check to make sure both lists are the same
		length.
*/		
	for( ix = 0; ix < names.length; ix++ )
	{
		value = getValueUnknownType( form, names[ix] );
/*
		See if you have something.  If not, add this field
		to the list of fields missing data.
*/		
		if( isEmpty( value ) )
		{
			ans = concatWords( ans, trim( descs[ix] ), ",\n" );
		}
	}											// end loop
	
	return( ans );
}												// end checkMissingValues
/*
        clearAll -- clear all elements in all forms on a page.
        This differs from "reset" which sets all elements to
        their default values.
*/
function clearAll()
{
//
//		Loop through every element of every form of every frame on the page.
//
    for (var h = 0; h < frames.length; h++) 	// loop through frames
    {
        clearDocument( frames[h].document );
    }
    clearDocument( window.document );
}
//
//		clearDocument
//
//		param		=	the document object
//
function clearDocument( doc )
{
//
//		Loop through every form in this document.
//
    //window.alert("In clear document");
    for (var i = 0; i < doc.forms.length; i++)  // through forms
    {
        clearForm( doc.forms[i] );
    }
}												// end clearDocument	
//
//		clearForm
//
function clearForm( form )
{
    var i;
    var ans;
/*
        clear Query Form

        For text, textarea, password -- clear the value to "".
        For hidden, leave as is.
        For radio -- default value.
        For checkbox -- nothing checked.
        For select -- first value..
*/		
    var ie;
    var ir
    var type;
    var radio;
    var element;
    var name;

    //window.alert( "In clearForm, # elements: " + form.elements.length );
/*
        Clear enterable text elements
*/		
    for( ie = 0; ie < form.elements.length; ie++ )
    {
        element = form.elements[ie];			// make the element its own
        type = element.type;					// get its type
        name = form.elements[ie].name;
    /*	
        window.alert( "Type: " + type + 
            "  Name: " + name + 
            "  Element: " + element );
    */
        if( type == "text"  ||  				// clear these
            type == "textarea"  ||
            type == "password" )
        {
            element.value = "";
        }
        else if( type == "hidden" )
        {
/*
        For now, leave hidden as is on the notion that this is not changed
        by the user.  There is also no "defaultValue" for a hidden field,
        so I can't do a reset, though the browser can.  That value is not
        made public.
*/		
        }
        else if( type == "radio" )
        {
                element.checked = element.defaultChecked;
        }
        else if( type == "checkbox" )
        {
            element.checked = false;
        }
        else if( type.indexOf( "select" ) == 0 )
        {
/*
        Loop through all the options, de-selecting them.
*/		
            for( var io = 0; io < element.length; io++ )
            {
                element.options[io].selected = false;
            }
            element.options[0].selected = true;	// now select first
        }
    }											// end loop through elements
    //window.alert("After loop");
}												// end clearForm
/*
        concatCheckBox
        
        Get the value of a checkbox and, if it is not
        blank, add it as a name/value pair to the passed
        search string.
        
        @param		ss			=	current value of search string
        @param		formName	=	name of the form to check
        @param		fieldName	=	the field name to check
        @return		ans			=	the new value of the search string.
                                    Is the same as the entry value if
                                    not changed.
*/		
function concatCheckBox( ss, formName, fieldName )
{
    var ans;
    var cb;
    var value;
    
    cb = document.forms[formName].elements[fieldName];
    value = getCheckboxValue( cb );
	
    if( hasData( value ) )
    {
        ans = concatSearchString( ss, fieldName, value);
    }
    else
    {
        ans = ss;
    }
    return( ans );
}												//end concatCheckBox
/*
        concatRadio
        
        Get the value of a radio button and, if it is not
        blank, add it as a name/value pair to the passed
        search string.
        
        @param		ss			=	current value of search string
        @param		formName	=	name of the form to check
        @param		fieldName	=	the field name to check
        @return		ans			=	the new value of the search string.
                                    Is the same as the entry value if
                                    not changed.
*/		
function concatRadio( ss, formName, fieldName )
{
    var ans;
    var radio;
    var value;
    
    radio = document.forms[formName].elements[fieldName];
    value = getRadioValue( radio );
    
    if( hasData( value ) )
    {
        ans = concatSearchString( ss, fieldName, value );
    }
    else
    {
        ans = ss;
    }
    return( ans );
}												//end concatRadio
//
//		concatSearchString
//
/**		Add a name value pair to an existing search string.
		The string does NOT begin with a "?", but each
		successive pair is separated with a "&".
		
		current		=	current value of the search string
		fieldName	=	the field name
		value		=	the value
		
		returns:	the new search string
*/
	function concatSearchString( current, fieldName, value )
	{
		var ans;
		
		if( ! value ||  value == null )  value = "";
		
        ans = concatWords( current, fieldName + "=" + value, "&" );
		return( ans );
	}											// end concatSearchString
/*
        concatSelect
        
        Get the value of a select list and, if it is not
        blank, add it as a name/value pair to the passed
        search string.
        
        @param		ss			=	current value of search string
        @param		formName	=	name of the form to check
        @param		fieldName	=	the field name to check
        @return		ans			=	the new value of the search string.
                                    Is the same as the entry value if
                                    not changed.
*/		
function concatSelect( ss, formName, fieldName )
{
    var ans;
    var select;
    var value;
    
    select = document.forms[formName].elements[fieldName];
    value = getSelectedValue( select, false );
    
    if( hasData( value ) )
    {
        ans = concatSearchString( ss, fieldName, value );
    }
    else
    {
        ans = ss;
    }
    return( ans );
}												//end concatSelect
/*
        concatText
        
        Get the value of a text field and, if it is not
        blank, add it as a name/value pair to the passed
        search string.
        
        @param		ss			=	current value of search string
        @param		formName	=	name of the form to check
        @param		fieldName	=	the field name to check
                                    false --  don't encode it.
        @return		ans			=	the new value of the search string.
                                    Is the same as the entry value if
                                    not changed.
*/		
function concatText( ss, formName, fieldName )
{
    return( concatText( ss, formName, fieldName, false ) );
}
/*
        concatText
        
        Get the value of a text field and, if it is not
        blank, add it as a name/value pair to the passed
        search string.
        
        @param		ss			=	current value of search string
        @param		formName	=	name of the form to check
        @param		fieldName	=	the field name to check
        @param		boolean		=	true  --  encode it<br>
                                    false --  don't encode it.
        @return		ans			=	the new value of the search string.
                                    Is the same as the entry value if
                                    not changed.
*/		
function concatText( ss, formName, fieldName, encode )
{
    var ans;
    var text;
    var s;
    
    text = document.forms[formName].elements[fieldName];
    
    if( text != null  &&  hasData( text.value ) )
    {
        s = text.value;
        if( encode )  s = escape( text.value );
        ans = concatSearchString( ss, fieldName, s );
    }
    else
    {
        ans = ss;
    }
    return( ans );
}												//end concatText
/*
        concatUnknown
        
        Get the value of a field of unknown type and, if it is not
        blank, add it as a name/value pair to the passed
        search string.
        
        @param		ss			=	current value of search string
        @param		formName	=	name of the form to check
        @param		fieldName	=	the field name to check
        @return		ans			=	the new value of the search string.
                                    Is the same as the entry value if
                                    not changed.
*/		
function concatUnknown( ss, formName, fieldName )
{
    var ans;
	var form;
    var value;
    
	form = document.forms[ formName ];
	
    value = getValueUnknownType( form, fieldName );
    
    if( hasData( value ) )
    {
        ans = concatSearchString( ss, fieldName, value );
    }
    else
    {
        ans = ss;
    }
    return( ans );
}												//end concatUnknown
//
//		concatWords
//
/*		Add a string to another string, including a separator if
        the first string is not empty.
        
        param		String to add to
        param		String to add
        param		separator
        
        i.e. var x = "";
        x = concatWords( x, "Hello", " and " );	==> Hello
        x = concatWords( x, "Goodbye", " and " );	==> Hello and Goodbye
*/
    function concatWords( w1, w2, connect )
    {
        var ans = w1;
        
        if( connect == null )  connect = "";
        
        if( hasData( w2 ) )				
        {
            if( hasData( w1 ) )
                ans = w1 + connect + w2;
            else
                ans = w2;
        }
        if( ans == null )
            ans = "";
            
        return( ans );
	}											// end concatWords
//
//		findElementByName
//
/*		Find an object's element # in a form, when you
		know the name.
		
		@param		form object
		@param		the field name to look up
		@return		the index of the field. -1 = not found;
					0 = first one.
*/
	function findElementByName( form, name )
	{
		var ans = -1;
		
		if( form != null  &&  hasData( name ) )
		{
			for( var i = 0; i < form.elements.length; i++ )
			{
				if( name.toLowerCase() == form.elements[i].name.toLowerCase() )
				{
					ans = i;
					break;
				}
			}
		}
		return( ans );
	}											// end findElementByName
/*
        focusOnFirst
        
        Find the first text field in a form and give it focus.
        
        @param		String  --  name of the form
*/		
    function focusOnFirst( formName )
    {
        var i;
        var all = document.forms[formName].elements;
        
        //window.alert("In focusonfirst for form: " + formName +
        //	"\nAll: " + all + "  Leng: " + all.length);
        
        for( i = 0; i < all.length; i++ )
        {
            //window.alert("Item: " + i + " " + all[i] );
            
            if( ! all[i] )  continue;
            
            //window.alert("Item: " + i + " Name: " + all[i].name +
            //	"  Type: " + all[i].type );
            
            if( isTypeEditable( all[i].type ) )
            {
                all[i].focus();
                break;
            }
        }
        //window.alert("at end of focusonfirst");
    }
//
//		fromQueryStringToForm
//
/*		Move all the name/value pairs from a query string into
        the elements of a form.  This assumes the "names" in the
        query string are also the field names in the form.
        If there is no form element with that name, that name/value
        pair is skipped (though it will be in the returned array).
        
        param		String		the query String (&name1=value1&name2=value2.....)
        param		form		the HTML form object (i.e. document.formname )
        return		Array		the array of name/value pairs
*/
function fromQueryStringToForm( s, formObj )
{
    var ir;
    var results = splitQueryString( s );		// returns an Array
/*
        Now move these results into form elements.
        [0] = name 1
        [1] = value 1
        [2] = name 2
        [3] = value 2
        ........
*/		
    var element;
    var name;
    for( ir = 0; ir < results.length; ir++ )
    {
        name = results[ir++];
        if( name != null )
        {
            element = formObj.elements[ name ];
            if( element != null )				// works for undefined
            {
                element.value = results[ ir ];
            }
        }
    }
    return( results );
}												// end fromQueryStringToForm
//
//	getCheckboxValue -- get the value of a checkbox after
//						making sure it's checked and legit.
//
//	passed:		checkbox element  (document.formname.checkboxname)
//	returned: 	value of box, or null if not checked.  Could be ""
//				if that is the value of the checkbox.
//  
function getCheckboxValue( cb )
{
    var ans = null;
    
    if( cb  &&  cb != null  &&  cb.checked )
    {
        ans = cb.value;
    }
    return( ans );
}												// end getCheckboxValue
//
//	Find which element of a radio button is selected.
//  If the length is undefined, that means there's only one,
//	but you can't refer to rb[0], because there is no array
//
//	passed:	radiobutton element  (document.formname.buttonname)
//	returned: checked element number (0 = first, -1 = none)
//  
//	To reference it: rb[n].value  or rb[n].checked
//
function getRadioChoice( rb )
{
    var ans = -1;
    
    if( rb ||  rb != null )
    {
        for( i = 0; i < rb.length; i++ )
        {
            if( rb[i].checked )
            {
                ans = i;
                break;
            }
        }
    }
	
    return ans;
}												// end getRadioChoice
//
//	getRadioValue -- get the value of the checked radio button
//
//	passed:	radiobutton element  (document.formname.buttonname)
//	returned: checked element value (null = none checked)
//  
function getRadioValue( rb )
{
    var ans = null;
    var ix;
    
    ix = getRadioChoice( rb );
    if( ix >= 0 )
        ans = rb[ix].value;
	
	else
	{
/*
		See if this is the odd case of only one radio button.
		In that case, it's not treated as an array.
		If you have the object, but it has no length,
		then check the first value for being checked.
*/
		if( rb  &&  ! rb.length )
		{
			if( rb.checked )  ans = rb.value;
		}
	}
        
    return ans;
}												// end getRadioValue
//
//	getSelected -- 	to get the index of an item in a select list 
//					that has been
//					selected.  Any selected item is ok, even if it
//					is all blanks
//
//	getSelected( selectobject)    
//		(i.e. getSelected( document.formname.fieldname ) )
//
//	@param:		selectobject	=	the select form element
//	@returns:	int				=	-1 -- none selected
//								=  >=0 -- item selected
//
function getSelected( selObj )
{
    return( getSelected( selObj, true ) );
}												// end getSelected - 1
/*
    getSelected -- 	to get the index of the item in a select list 
                    that has been
                    selected.  There's an option to allow or not
                    allow an answer of a blank.

    getSelected( selectobject, boolean)    
        (i.e. getSelected( document.formname.fieldname ) )

    @param:		selectobject	=	the select form element
    @param:		boolean			=	true -- allow blank
                                =	false-- don't allow blank
    @returns:	int				=	-1 -- none selected
                                =  >=0 -- item selected
*/
function getSelected( selObj, allowBlank )
{
    var ans = -1;
    if( selObj  &&  selObj != null )
    {
        var ix = selObj.selectedIndex;
        if( ix >= 0 )
        {
            if( allowBlank  ||  ! isEmpty( selObj.options[ix].value ) )
                ans = ix;
        }
    }
    return ans;	
}												// end getSelected - 2

//
//	getSelectedValue -- to get the value of an item in a select list 
//					that has been
//					selected.  There's an option to allow or not
//					allow an answer of a blank.
//
//	getSelectedValue( selectobject, boolean)    
//		(i.e. getSelected( document.formname.fieldname, true ) )
//
//	@param:		selectobject	=	the select form element
//  @param:		boolean			=	true -- allow blank
//								=	false-- don't allow blank
//	@returns:	string			=	the value of the selected item (or null)
//
function getSelectedValue( selObj, allowBlank )
{
    var ans = null;
    var ix;
    
    ix = getSelected( selObj, allowBlank )
    if( ix >= 0 )
    {
        ans = selObj.options[ix].value;
    }
    return ans;	
}												// end getSelectedValue
//
//		getValueUnknownType
//
/*		Get the value of a form field when you don't know
		which type of field it is.
		
		@param		form object
		@param		field name
		@return		the value, or null if it can't find the field,
					or empty if the field is here, but empty
*/
function getValueUnknownType( formObj, fieldName )
{
	var ans = null;
	var element = null;
	var formName;
	var ix;
	var type = null;
	
	fieldName 	= trim( fieldName );
	formName	= formObj.name;
	
	if( formObj.elements[fieldName] )
		element		= formObj.elements[fieldName];
		
	if( element )
	{
/*
		If there is no element by this name, skip it.
		Branch by type, so you can get the value.
		The findElementByName, etc. is because, for some
		reason, using "element" comes up with an
		undefined type for radio buttons.
*/		
		type = element.type;
		
		if( isEmpty( type ) )
		{
			ix = findElementByName( formObj, fieldName );
			if( ix >= 0 )
			{
				element = formObj.elements[ix];
				type = element.type;
			}
		}
		
		if( hasData( type ) )
		{
	        if( type == "text"  || 
	            type == "textarea"  ||
	            type == "password"  ||
				type == "hidden" )
	        {
	            ans = element.value;
	        }
	        else if( type == "radio" )
	        {
/*
		Don't ask me why, but it seems that this form of the element
		name -- a variable for the form and for the element -- 
		is necessary in order for JS to be able to get the length
		of the radio button.
*/		
	           	ans = getRadioValue( document.forms[formName].elements[fieldName] );
	        }
	        else if( type == "checkbox" )
	        {
	            ans = getCheckboxValue( element );
	        }
	        else if( type.indexOf( "select" ) == 0 )
	        {
				ans = getSelectedValue( element, false );
			}
		}
		/*
			window.alert( "ValueUnk, name: " + fieldName +
				"  element: " + element +
				"  type: " + type +
				"  ans: " + ans +
				"  empty?: " + isEmpty( ans ) );
		*/
	}											// end if have the element
	
	return( ans );
}												// end getValueUnknownType
//
//		hasData  --  see if a string is not empty
//
//		param		s = string to check
//		return		true  = has data
//					false = is empty
//
    function hasData( s )
    {
        return( ! isEmpty( s ) );
    }
//
//	isEmpty -- checks to see if a string or number
//		is empty (no non-blank characters) or not defined.
//
//	@params:	s	=	string to check
//	@returns:	true	=	is empty
//				false	=	is not empty
//
function isEmpty( s )
{
    var ans = true;
	
	if( typeof s == "string" )
	{
	    if( s  &&  s != null  &&  s.length > 0 )
	    {
	        for( i = 0; i < s.length; i++ )
	        {
	            c = s.charAt( i );
	            if( (c != ' ')  &&  (c != '\t')  &&  (c != '\n') )
	            {
	                ans = false;
	                break;
	            }
	        }
	    }
	}
	
	else if( typeof s == "number" )
	{
		if( s  && s != null )
		{
			ans = false;
		}
	}
    return ans;
}
//
//		isEnterKey
//
/*		To see if the key just typed was the enter key.
        This (tries to) takes care of the differences between
        browsers.
        
        It comes from Danny Goodman, "Javascript & DHTML Cookbook",
        page 206.

        must be called like this:
        
        isEnterKey(event)
        
        from an onkeypress event handler.
        
        and could be used like this:
        onkeypress="(isEnterKey(event) == true) ? form.submit(); return false; : return true;"
        
        If it's an enter key, submit the form.  If not, accept the character.
        The catch is that for the onkeypress function, a true value means accept
        the character that was entered and a false value means do nothing.
        
        arg:		event  -- the event object
        return:		true  --  the character entered was an Enter key
                    false --  the character entered was NOT an enter key
*/
function isEnterKey( evt )
{
    var ans = false;				// assume not an Enter
//
//		Netscape > 4 can pass the event as an argument.  IE < 6 doesn't, but
//		instead sets up an "event" object.
//		I.E. 6 seems to do both, so check for it first.	
//
//    evt = (evt) ? evt : event;		// if defined, use it; if not, look at event.
	
	evt = (window.event) ? window.event : evt
    
    if( evt )
    {
//
//		"which" is the key pressed in Netscape 4.
//		"charCode" is for Netscape 6+
//		"keyCode" is for IE (and for some versions of Netscape)
//
        var charCode = (evt.charCode) ? evt.charCode :
                       ( (evt.which) ? evt.which : evt.keyCode );
        if( charCode == 13  ||  charCode == 3 )
        {
            ans = true;
        }
    }
    return ans;
}												// end isEnterKey
    
//
//	isNumeric -- checks to see if a string is all numeric characters
//				( 0 - 9, no decimal or sign)
//
//	@params:	s	=	string to check
//	@returns:	true	=	is all numeric
//				false	=	is not all numeric
//
function isNumeric( s )
{
    var ans = false;
    if( s != null  &&  s.length > 0 )
    {
        ans = true;
        for( i = 0; i < s.length; i++ )
        {
            c = s.charAt( i );
            if( ( c < '0' )  || 
                ( c > '9' ) )
            {
                ans = false;
                break;
            }
        }
    }
    return ans;
}
//
//		isSelect
//
/**		See if a given field is a select box.

        @param		the form element
        @return		true  --  is.
                    false --  is not.
*/
function isSelect( x )
{
    var ans = false;
    var type;
    
    if( x != null )
    {
        type = x.type;							// get its type
        if( type.indexOf( "select" ) == 0 )
            ans = true;
    }
    return( ans );
}												// end isSelect
//
//		isTypeEditable
//
/*		See if this type is editable

		@param		String		the type of the html element
		@return		boolean		true -- it is.
								false -- it isn't.
*/
function isTypeEditable( type )
{
	var ans = false;
	
	if( hasData( type ) )
	{
		type = type.toLowerCase();
		
        if( type.indexOf( "text" ) == 0 	||
			type == "password"				||
			type == "radio"					||
			type == "checkbox"				||
			type.indexOf( "select" ) == 0 )
        {
			ans = true;
		}
	}
	return( ans );
}												// end isTypeEditable
//
//		showForms
//
/**		For debugging, will display the list of existing forms in
        a window alert box.
        
        @param		nothing
*/
    function showForms()
    {
        var i;
        var msg = "";
        for( i = 0; i < document.forms.length; i++ )
        {
            msg += "\n" + "Form name #: " + i + ". " + 
                    document.forms[i].name;
        }
        window.alert("# forms: " + document.forms.length + msg )
    }											// end showForms
//
//		splitQueryString
//
/*		Take a query string (name/value pairs separated by ampersands)
        and return all the name/value pairs.
        
        param		query string (&name1=value1&name2=&name3=value3)
        return		Array  -- where elements 0,2,4,... are the
                    names and elements 1,3,5.... are the values.
*/
function splitQueryString( s )
{
    var results = new Array();
    var ir;
    var i;
    
    if ( s ) 
    {
        var srchArray = s.split("&");			// get name/value pairs
        var tempArray = new Array();			// array for each name/value
        ir = 0;									// counter into results
/*
        Loop through each name/value pair, getting the name
        and the value.  Test the value of the srchArray in
        case the query string was badly formed and there 
        are some empty values (for example, if the
        query string begins with &, the first srchArray element
        will be empty.)
*/		
        for (i = 0; i < srchArray.length; i++) 
        {
            if( srchArray[i] != null  &&  srchArray[i].length > 0 )
            {
                tempArray = srchArray[i].split("=");
    
                results[ir++] = tempArray[0];	// store name
                results[ir++] = tempArray[1];	// store value
            }
        }
    }
    return( results );
}												// end splitQueryString
//
//		submitIfEnter
//
/*		Submit a form if an Enter key is pressed.
        This submits the form without doing anything else.

        From code in Danny Goodman's "Javascript & DHTML Cookbook".
        
        This must be called like this:
        
        onkeypress="return submitIfEnter(event)
        
        arg:		event  		-- 	the event object
                    otherFunc 	--	the name of a function to call before
                                    doing the submit.  If it returns true,
                                    the submit will be done.  If it returns
                                    false, the submit will not be done.
                                    It is optional and may be null.
                    funcArg		--  an argument for the otherFunc.  It will
                                    be passed to the function, if there is
                                    a function.  Because it could be undefined,
                                    the function itself has to figure out whether
                                    there is anything there.
        return:		true  		--  the character entered was a regular key
                    false 		--  the character entered was an enter key AND
                                    the submit was done.
			
	Notes: In Netscape 4 & 6 & 7, the event object is passed as an
	argument.  It seems also to be passed as an argument in IE6, though
	in earlier versions of IE it was undefined.  
	In all versions of IE, the event info
	is also placed in a global variable, window.event.
	
	Furthermore, the "target" is the property name in Netscape, but srcElement
	is the name in IE (whether using the passed argument in later versions or
	the global variable in any version.)
	
	The code from Danny Goodman and other sources would check for the
	passed argument first and, if there, assume Netscape.  Can't do
	that anymore.  Have to check the global variable first.
*/
function submitIfEnter( evt, otherFunc, funcArg )
{
    var ans = true;
	var target;

    if( isEnterKey( evt ) )
    {
		target = null;
		
		if( window.event )
		{
			target = window.event.srcElement;
		}
		else if( evt )
		{
			target = evt.target;
		}
		
        if( target )
        {
            var form = target.form;
            if( form )
            {
/*
        See if there is a function to run before the submit.
*/		
                var doSubmit = false;
                
                if( arguments.length < 2 )
                {
                    doSubmit = true;			// ok as is
                }
                
				else if( arguments.length == 2 )	
                {
                    if( otherFunc() )	// ok.  Passed.
                        doSubmit = true;
                }
                
				else
                {
                    if( otherFunc( funcArg ) )	// ok.  Passed.
                        doSubmit = true;
                }
/*
        Submit if all is ok.
*/		
                if( doSubmit )
                {
                    form.submit();
                    ans = false;
                }
            }
        }
    }
    return ans;
}												// end submitIfEnter
//
//	trim  --  trim a string of leading and trailing blanks
//
//	@params:	s	=	string to check
//	@returns:	s   =	the new string
//
function trim( s )
{
    var ans;
    
    ans = trimFirst( s );
    ans = trimLast( ans );
    return ans;
}
//
//	trimFirst  --  trim leading blanks from a string
//
//	@param:		s	=	string to trim
//	@return:	new string
//
function trimFirst( s )
{
    var ans = "";
    if( s != null  &&  s.length > 0 )
    {
/*
        Loop thru, looking for 1st non-blank character.
*/		
        for( i = 0; i < s.length; i++ )
        {
            c = s.charAt( i );
            if( (c != ' ')  &&  (c != '\t')  &&  (c != '\n') )
            {
                ans = s.substr( i );
                break;
            }
        }
    }
    return ans;
}												// end trimFirst
//
//	trimLast  --  trim trailing blanks from a string
//
//	@param:		s	=	string to trim
//	@return:	new string
//
function trimLast( s )
{
    var ans = "";
    if( s != null  &&  s.length > 0 )
    {
/*
        Loop thru, looking for 1st non-blank character.
*/		
        for( i = s.length - 1; i >= 0; i-- )
        {
            c = s.charAt( i );
            if( (c != ' ')  &&  (c != '\t')  &&  (c != '\n') )
            {
                ans = s.substr( 0, i+1 );
                break;
            }
        }
    }
    return ans;
}												// end trimLast
//
//		uniqueName
//
//		@param		nothing
//		@return		a string that should be unique, to be used as a name
//
//		Taken for the ModalWindows.js script file.
//
function uniqueName()
{
    var ans = (new Date()).getTime().toString();
    return ans;
}


