Overview | File | Class | Tree | Index | Help
| The Gravey 2.0 Framework and AIM RIA
PREV NEXT | FRAMES NO FRAMES

## grvUtils.js

#### Summary

Collection of general utility routines
Version: 2.0
Requires:

- grvValidate.js

Author: Bruce Wallace (PolyGlotInc.com)

Class Summary
grvArgs | This function parses ampersand-separated name=value argument pairs from the query string of the URL; It stores the name=value pairs in a static list; adapted from here.

Method Summary
`static boolean` | `grvAfter( <String> datestr, <Date> date )` Determine whether given date is at or before a given datestr (where empty means "future").
`static boolean` | `grvAfterNow( <String> datestr )` Determine whether today is at or before a given date (where empty means "future").
`static Object` | `grvAppName(appId)`
`static Object` | `grvArgsToString( args )`
`static Object` | `grvArrayToString( a )`
`static boolean` | `grvBefore( <String> datestr, <Date> date )` Determine whether a given datestr is explicitly before the given date.
`static boolean` | `grvBeforeNow( <String> datestr )` Determine whether a given date is explicitly before today.
`static void` | `grvBusy()` set the cursor to the hourglass icon
`static void` | `grvBusyDo( <String> funcname, <String> funcargs, <int> optDelayMilliSecs )` generic utility function to queue up for future execution the specified function with the specified arguments after a specified amount of delay.
`static void` | `grvClearGlobalVar( <String> varname )` static routine to dynamically undefine/delete a global variable
`static void` | `grvClearGlobalVars()` static routine to dynamically undefine/delete ALL "...GlobalVars" variables
`static void` | `grvClearPersistentVars()` static routine to dynamically undefine/delete ALL "...PersistentVars" variables
`static boolean` | `grvDateKeyFilter( <int> keyCode, <String> valueSoFar )` is the given character a legal addition to the given dollar string
`static String` | `grvDiamond(<boolean> optBlankFlag)` return the HTML to draw a diamond
`static boolean` | `grvDollarKeyFilter( <int> keyCode, <String> valueSoFar )` is the given character a legal addition to the given dollar string
`static Object` | `grvDollarStrFilter(s)`
`static String` | `grvDot()` return the HTML to draw a biggish dot
`static void` | `grvEditElem( e, makeSelected, makeEdited, makeInvalid, optUnselectColor )`
`static void` | `grvEditElemID( ID, makeSelected, makeEdited, makeInvalid )`
`static String` | `grvEpsilon()` return the HTML to draw a smallish "E"
`static Object` | `grvFormatDate( d, f )`
`static String` | `grvFormatDecimal( <anyType> v, <String> currencyPreSymbol, <String> currencyPostSymbol, <String> sepSymbol, <boolean> optZeroAsBlankFlag )` format given value as -<$>#<,>###.00<%>
`static String` | `grvFormatDollar( <anyType> v, <boolean> optZeroAsBlankFlag )` format given value as $#,###.00
`static String` | `grvFormatDollarNot( v )` like format_dollar except empty string returned for zero
`static String` | `grvFormatErrorStr( msg )` format Server Error Messages
`static String` | `grvFormatLpadded( s,len,padChar )` pad or truncate to be exactly given length
`static String` | `grvFormatMultilineStr( s,len )` convert CRs to tags
`static String` | `grvFormatPaddedStr( s,len )` blankpad or truncate to be exactly given length
`static String` | `grvFormatPercent( <anyType> v, <boolean> optZeroAsBlankFlag )` format given value as ####.00%
`static String` | `grvFormatRpadded( s,len,padChar )` pad or truncate to be exactly given length
`static String` | `grvGenHook( <String> hookID, <String> optInnerHTML )` generate a piece of HTML, identified by the given ID, that can safely have its innerHTML replaced at runtime.
`static Object` | `grvGetArg( argname )`
`static Object` | `grvGetElemVisibility( e )`
`static Object` | `grvGetFormInt( ID )`
`static Object` | `grvGetFormValue( ID )`
`static Object` | `grvGetGlobalVar( <String> varname )` static routine to return the value of persistent variable with given name
`static Object` | `grvGetHook( hookID )`
`static Object` | `grvGetPersistentVar( <String> varname )` static routine to return the value of the persistent variable with given name
`static Object` | `grvGetTodayAsMMDDYYYY()`
`static Object` | `grvGetTodayAsXXDDYYYY(monthNames)`
`static Object` | `grvGlobalVar()`
`static void` | `grvHighlightElem( e, makeSelected, selectColor, optUnselectColor )`
`static Object` | `grvIsChecked( ID )`
`static Object` | `grvIsZeroDollars(v)`
`static boolean` | `grvKeyFilter( <int> keyCode, <String> allowedChars )` Is the given keyCode in the given list of allowed characters?
`static boolean` | `grvNoDuplicates( <String> s, <String> charList )` Is there no more than one occurance of each character in the given character list in the given string?
`static void` | `grvNotBusy()` set the cursor to the default icon
`static Object` | `grvObjectToInitializer( o )`
`static Object` | `grvObjectToShortInitializer( o )`
`static Object` | `grvObjectToString( o )`
`static Object` | `grvPersistentVar()`
`static Object` | `grvPleaseWait( <boolean> enableFlag, <String> msg, appId )` create and open a window (if enabled) with the specified message
`static String` | `grvRightArrow()` return the HTML to draw a bold right arrow
`static void` | `grvSelectElem( e, makeSelected, optUnselectColor )`
`static void` | `grvSelectElemID( ID, makeSelected, optUnselectColor )`
`static void` | `grvSendStatusMessage( <String> msg )` send a message to the browser status bar
`static void` | `grvSetBackgroundColor( ID, color )`
`static void` | `grvSetButtonElemText( button, str )`
`static void` | `grvSetButtonText( buttonId, str )`
`static void` | `grvSetElemBackgroundColor( e, color )`
`static void` | `grvSetElemDisplay( e, visibleFlag )`
`static void` | `grvSetElemText( e, str )`
`static void` | `grvSetElemVisibility( e, visibleFlag )`
`static void` | `grvSetFormValue( ID, theValue )`
`static void` | `grvSetGlobalVar( <String> varname, <Object> value )` static routine to dynamically define/update a global (to window/page but reloaded with page) variable with the given name and value.
`static void` | `grvSetPersistentVar( <String> varname, <Object> value )` static routine to dynamically define/update a persistent (across page loads) variable with the given name and value.
`static void` | `grvSetText( ID, str )`
`static void` | `grvSetVisibility( ID, visibleFlag )`
`static boolean` | `grvStrFilter( s, <String> allowedChars )` Does the given string consist of only characters in the given list of allowed characters?
`static String` | `grvSubitem( isInValid )` return the HTML to draw a subitem bullet
`static Object` | `grvTimestamp()`
`static Object` | `grvTrace(flag,msg)`
`static Object` | `grvTraceEvt(msg)`
`static Object` | `grvTraceMrk(msg)`
`static Object` | `grvTraceMsg(msg)`
`static Object` | `grvTraceMVC(msg)`
`static Object` | `grvTraceObj(msg)`
`static Object` | `grvTraceTODO(msg)`
`static void` | `grvUNWAIT(appId)` close the "please wait" window if it exists otherwise no effect
`static boolean` | `grvUpperKeyFilter( <int> keyCode, <String> valueSoFar )` convert the given character to uppercase
`static String` | `grvURLDecode( <String> encoded )` This decodes URL-encoded strings because the Javascript function "unescape" only does part of the job; adapted from here.
`static void` | `grvWAIT(appId)` Create an idempotent "wait a minute" window, if one doesn't exist, and squirrel away a reference to it that survives window reloads
`static boolean` | `grvWAITING(appId)` are we in "please wait" mode?
`static Object` | `grvWaitWindowName(appId)`

    // This file uses JSDoc-friendly comments [ http://jsdoc.sourceforge.net/ ]

    /**
     * @file         grvUtils.js
     * @fileoverview Collection of general utility routines
     * @author       Bruce Wallace  (PolyGlotInc.com)
     * @requires     grvValidate.js
     * @version      2.0
     */

    //////////////////////////////////////////////////////////////////
    // GRAVEY LEXICAL CODING CONVENTIONS:
    // (*) All private variables or functions start with "_"
    // (*) All variables and functions start with a lowercase letter
    // (*) All Classes start with an uppercase letter
    // (*) All Class methods and instance variables start with lowercase
    // (*) All Class "static" methods and variables start with uppercase
    // (*) All constants start with "k"
    // (*) All global variables start with "g"
    // (*) All event handler functions start with "on"
    //
    // (*) All Gravey utility global variables start with "gGrv"
    // (*) All Gravey MVC     global variables start with "gMVC"
    // (*) All Gravey EDO     global variables start with "gEDO"
    // (*) All Gravey utility functions start with "grv"
    // (*) All Gravey MVC     functions start with "mvc"
    // (*) All Gravey MVC event handler functions start with "onMVC"
    // (*) All Gravey EDO event handler functions start with "onEDO"
    // (*) All Gravey MVC classes start with "MVC"
    // (*) All Gravey EDO classes start with "EDO"
    //////////////////////////////////////////////////////////////////

    //global debug flags to enable verbose event tracing
    var gGrvTraceObj = false;	//OO simulation tracing
    var gGrvTraceMVC = false;	//MVC setup tracing
    var gGrvTraceMrk = false;	//neverChanged/everChanged tracing
    var gGrvTraceEvt = false;	//Event processing tracing
    var gGrvTraceMsg = false;	//broadcast message tracing
    var gGrvTraceTODO= false;	//"not implemented yet" msgs
    function grvTrace(flag,msg){ if (flag) return grvBreak(msg); else return true; }

    function grvTraceMVC(msg){ return grvTrace(gGrvTraceMVC,msg); }
    function grvTraceObj(msg){ return grvTrace(gGrvTraceObj,msg); }
    function grvTraceEvt(msg){ return grvTrace(gGrvTraceEvt,msg); }
    function grvTraceMrk(msg){ return grvTrace(gGrvTraceMrk,msg); }
    function grvTraceMsg(msg){ return grvTrace(gGrvTraceMsg,msg); }

    function grvTraceTODO(msg){ return grvTrace(gGrvTraceTODO,"TO DO:"+msg); }

    function grvTimestamp(){ return (new Date()).getTime(); }

    // ----------------------------------------------------------------------------
    // Utility routines for Formatting Data
    // ----------------------------------------------------------------------------

    /** return the HTML to draw a bold right arrow @type String */
    function grvRightArrow(){ return '<font face="Symbol">&#222;</font>'; }

    /** return the HTML to draw a biggish dot @type String */
    function grvDot       (){ return '<font face="Symbol">&#183;</font>'; }

    /** return the HTML to draw a smallish "E" @type String */
    function grvEpsilon   (){ return '<font face="Symbol">&#101;</font>'; }

    /** return the HTML to draw a diamond
     * @param {boolean} optBlankFlag if true, says generate blanks of same size as 1 diamond
     * @type String
     */
    function grvDiamond(optBlankFlag){ return optBlankFlag ? "&nbsp;&nbsp;" : "&diams;"; }

    /** return the HTML to draw a subitem bullet @type String */
    function grvSubitem( isInValid ){ return isInValid ? grvEpsilon() : grvRightArrow() }

    /** Is the given keyCode in the given list of allowed characters?
     * @param {int} keyCode the charCode of the character to validate
     * @param {String} allowedChars the list of characters that are allowed
     * @return true iff keyCode is legal
     * @type boolean
     */
    function grvKeyFilter( keyCode, allowedChars ){
    	return allowedChars.indexOf(String.fromCharCode(keyCode)) >= 0;
    }

    /** Does the given string consist of only characters in the given
     * list of allowed characters?
     * @param {int} keyCode the charCode of the character to validate
     * @param {String} allowedChars the list of characters that are allowed
     * @return true iff keyCode is legal
     * @type boolean
     */
    function grvStrFilter( s, allowedChars ){
    	var q = "";
    	for (var i=0; i<s.length; ++i)
    	{
    	  var c = s.charAt(i);
    	  if (allowedChars.indexOf(c) >= 0) q += c;
    	}
    	return q;
    }

    /** Is there no more than one occurance of each
     * character in the given character list in the given string?
     * @param {String} s string to check
     * @param {String} charList list of characters that should occur only once
     * @return true if there are no duplicates
     * @type boolean
     */
    function grvNoDuplicates( s, charList )
    {
    	for (var i=0; i<charList.length; ++i)
    	{
    	  var c = charList.charAt(i);
    	  var first = s.indexOf(c);
    	  if (first!=-1 && first!=s.lastIndexOf(c)) return false;
    	}
    	return true;
    }

    var kDigitChars = "0123456789";
    var kFloatChars = "+-.";

    /** convert the given character to uppercase
     * @param {int} keyCode the proposed new character
     * @param {String} valueSoFar the value so far
     * @return updated char iff character is legal else null
     * @type boolean
     */
    function grvUpperKeyFilter( keyCode, valueSoFar )
    {
    	if ( keyCode>96 && keyCode<123 ) keyCode -= 32;
    	return keyCode;
    }

    /** is the given character a legal addition to the given dollar string
     * @param {int} keyCode the proposed new character
     * @param {String} valueSoFar the value so far
     * @return updated char iff character is legal else null
     * @type boolean
     */
    function grvDateKeyFilter( keyCode, valueSoFar )
    {
    	if ( grvKeyFilter( keyCode, kDigitChars+"/-" ) ) return keyCode;
    	return null;
    }

    /** is the given character a legal addition to the given dollar string
     * @param {int} keyCode the proposed new character
     * @param {String} valueSoFar the value so far
     * @return updated char iff character is legal else null
     * @type boolean
     */
    function grvDollarKeyFilter( keyCode, valueSoFar )
    {
    	if ( grvKeyFilter( keyCode, kDigitChars+kFloatChars+"$," ) )
    //	&& grvNoDuplicates( valueSoFar+String.fromCharCode(keyCode), "$"+kFloatChars );
    	  return keyCode;
    	return null;
    }
    function grvDollarStrFilter(s){ return grvStrFilter(s,kDigitChars+kFloatChars); }
    function grvIsZeroDollars(v){ return Math.abs(parseFloat(v))<0.01; }

    /** format given value as -<$>#<,>###.00<%>
     * @type String
     * @param {anyType} v value to format
     * @param {String} currencyPreSymbol   prefix "currency symbol" to add
     * @param {String} currencyPostSymbol postfix "currency symbol" to add
     * @param {String} sepSymbol thousands "separator" to add
     * @param {boolean} optZeroAsBlankFlag optional flag to make zero format as blank
     * @author Bruce Wallace (PolyGlotInc.com)
     * @version 2.0
     */
    function grvFormatDecimal( v, currencyPreSymbol, currencyPostSymbol, sepSymbol, optZeroAsBlankFlag )
    {
    	if ( v==null || v=="null" ) return grvDot();
    	if ( grvIsZeroDollars(v) ) v = 0; //get rid of microcents and negative zeroes
    	if ( optZeroAsBlankFlag && v==0 ) return "&nbsp;";

    	// Do the equivalent to XSL::format-number($v,'$#,###.00')
    	var x = parseFloat(v).toFixed(2);
    	var sign = '';
    	if (x < 0){ sign = '-'; x = x.substr(1); }
        var C    = x.split("");
        var n    = C.length-4;
        var s    = x.substring(n+1,n+4);

    	for (var i=n; i>=0; --i)
    	    s = (((C.length-i)%3==0 && i!=0) ? sepSymbol : "") + C[i] + s;

    	return sign + currencyPreSymbol + s + currencyPostSymbol;
    }

    /** format given value as $#,###.00
     * @type String
     * @param {anyType} v value to format
     * @param {boolean} optZeroAsBlankFlag optional flag to make zero format as blank
     * @author Bruce Wallace (PolyGlotInc.com)
     * @version 2.0
     */
    function grvFormatDollar ( v, optZeroAsBlankFlag ) {
      return grvFormatDecimal( v, "$", "", ",", optZeroAsBlankFlag );
    }

    // a global month names array
    var kMonthNames = new Array(
    		'January',
    		'February',
    		'March',
    		'April',
    		'May',
    		'June',
    		'July',
    		'August',
    		'September',
    		'October',
    		'November',
    		'December'
    	);

    // a global day names array
    var kDayNames = new Array(
    		'Sunday',
    		'Monday',
    		'Tuesday',
    		'Wednesday',
    		'Thursday',
    		'Friday',
    		'Saturday'
    	);

    function grvFormatDate( d, f )
    {
        if (!d) return '';
        return f.replace(/(yyyy|mmmm|mmm|mm|dddd|ddd|dd|hh|nn|ss|a\/p)/gi,
            function($1)
            {
                switch ($1.toLowerCase())
                {
                case 'yyyy': return d.getFullYear();
                case 'mmmm': return kMonthNames[d.getMonth()];
                case 'mmm':  return kMonthNames[d.getMonth()].substr(0, 3);
                case 'mm':   return grvFormatLpadded( (d.getMonth()+1), 2, "0" );
                case 'dddd': return kDayNames[d.getDay()];
                case 'ddd':  return kDayNames[d.getDay()].substr(0, 3);
                case 'dd':   return grvFormatLpadded( d.getDate(), 2, "0" );
                case 'hh':   return grvFormatLpadded( ((h=d.getHours()%12)?h:12), 2, "0" );
                case 'nn':   return grvFormatLpadded( d.getMinutes(), 2, "0" );
                case 'ss':   return grvFormatLpadded( d.getSeconds(), 2, "0" );
                case 'a/p':  return d.getHours() < 12 ? 'a' : 'p';
                }
            }
        );
    }

    /** format given value as ####.00%
     * @type String
     * @param {anyType} v value to format
     * @param {boolean} optZeroAsBlankFlag optional flag to make zero format as blank
     * @author Bruce Wallace (PolyGlotInc.com)
     * @version 2.0
     */
    function grvFormatPercent( v, optZeroAsBlankFlag ) {
      return grvFormatDecimal( v, "", "%", "", optZeroAsBlankFlag );
    }

    /** like format_dollar except empty string returned for zero @type String */
    function grvFormatDollarNot( v ){ return grvFormatDollar( v, true ); }

    /** pad or truncate to be exactly given length @type String */
    function grvFormatRpadded( s,len,padChar ){
    	if ( s==null || s=="null" ) return grvDot();
    	for (var i=0; i<len; ++i) s += padChar;
    	return s.substr(0,len);
    }

    /** pad or truncate to be exactly given length @type String */
    function grvFormatLpadded( s,len,padChar ){
    	if ( s==null || s=="null" ) return grvDot();
    	for (var i=0; i<len; ++i) s = padChar+s;
    	return s.substring(s.length-len);
    }

    /** blankpad or truncate to be exactly given length @type String */
    function grvFormatPaddedStr( s,len ){
    	return grvFormatRpadded( s,len,"&nbsp;");
    }

    /** convert CRs to <br> tags @type String */
    function grvFormatMultilineStr( s,len )
    {
    	if (s==null || s=="null") return grvDot();
    	return s.replace( new RegExp( "\\n", "g" ), "<br>" );
    }

    /** format Server Error Messages @type String */
    function grvFormatErrorStr( msg ){
    	if (grvIsEmpty(msg)) return "";
    	msg = msg.replace( new RegExp( "\\n", "g" ), "<br>" );
    	var HTML  = new Array();
    		HTML.push( '<table class="grvErrpanel" cellpadding="10" cellspacing="0" width="100%">' );
    		HTML.push( '<tr><td>SERVER ERROR: '+msg+'</td></tr>' );
    		HTML.push( '</table>' );
     return HTML.join('');
    }

    /** generate a piece of HTML, identified by the given ID,
     * that can safely have its innerHTML replaced at runtime.
     * @param {String} hookID name of the HTML to be generated
     * @param {String} optInnerHTML optional HTML to be inserted
     * into the generated HTML
     * @return generated HTML
     * @type String
     * @see #grvGetHook
     * @author Bruce Wallace (PolyGlotInc.com)
     * @version 2.0
     */
    function grvGenHook( hookID, optInnerHTML ){
    	return '<span id="'+hookID+'">'
    	     + (optInnerHTML?optInnerHTML:"")
    	     + '</span>';
    }
    function grvGetHook( hookID ){
    	//special case: document.body
    	if (hookID=="document.body"){
    	 var e = document.body;
    	 grvTraceMVC("document body is:["+e+"]");
    	 return e;
    	}

    	var e = document.getElementById( hookID );
    	if (e==null) grvTraceMVC("cant find hook["+hookID+"]");
    	return e;
    }

    function grvSetElemBackgroundColor( e, color ){
        if (!e) {grvBreak("null setElemBackgroundColor!"); return;}
    	e.style.backgroundColor = color;
    }
    function grvSetBackgroundColor( ID, color ){
    	grvSetElemBackgroundColor( document.getElementById(ID), color );
    }
    function grvSetElemText( e, str ){
        if (!e) {grvBreak("null setElemText!"); return;}
    	e.innerHTML = str;
    }
    function grvSetText( ID, str ){
    	grvSetElemText( grvGetHook(ID), str );
    }
    function grvSetButtonElemText( button, str )
    {
    	if (!button) {grvBreak("null setButtonText!"); return;}
    	if (button.childNodes[0]) button.childNodes[0].nodeValue = str; else
    	if (button.value)         button.value = str;                   else
      /*if (button.innerHTML)*/   button.innerHTML = str;
    }
    function grvSetButtonText( buttonId, str ){
    	grvSetButtonElemText( grvGetHook(buttonId), str );
    }

    //TODO implement these via CSS instead
    var kColorTeal       = '#6eaba1';
    var kColorTealLight  = '#99CCCC';
    var kColorCornstarch = '#FFFAF0';
    var kColorWhitePepper= '#F0F0CC';
    var kColorDaffodil   = '#FFFACA';
    var kColorNavy       = '#000066';
    var kColorDarkSilver = '#COCOCO';
    var kColorLime       = '#66FF66';
    var kColorLightMoney = '#CCFFCC';
    var kColorMatteSilver= '#CCCCCC';
    var kColorLemonCream = '#FFFFCC';
    var kColorPeriwinkle = '#9CA9C5';
    var kColorBanana     = '#FFFF66';
    var kColorTurqoise   = '#66CCCC';
    var kColorPumpkin    = '#FFCC33';
    var kColorPumpkinGrey= '#DDBB08';
    var kColorDustyRose  = '#FFE0E0';
    var kColorDustierRose= '#EEAAAA';
    var kColorRoseGrey   = '#DAABAB';
    var kColorLipstick   = '#FF6666';
    var kColorYellow     = '#FFFF00';

    var      kInValidColor = '#FF9900';
    var       kEditedColor = kColorTealLight;//'#FFCC99';
    var     kSelectedColor = kColorLemonCream;
    var   kUnSelectedColor = kColorCornstarch;//kColorDaffodil;
    var kROUnselectedColor = kColorMatteSilver;

    function grvHighlightElem( e, makeSelected, selectColor, optUnselectColor ){
    	if ( grvIsUndefined(optUnselectColor) ) optUnselectColor = kUnSelectedColor;
    	grvSetElemBackgroundColor( e, makeSelected?selectColor:optUnselectColor );
    }
    /*ALTERNATE COLOR SCHEME...
    //set the background color of the given element based on
    //whether it is selected, dirty, and valid.
    function grvEditElem( e, makeSelected, makeEdited, makeInvalid ){
    	var useColor = makeSelected || makeEdited || makeInvalid;
    	grvHighlightElem( e, useColor, makeInvalid ? kInValidColor :
    	                               makeEdited  ? kEditedColor  :
    	                                             kSelectedColor );
    }
    */
    //set the background color of the given element based on
    //whether it is selected, dirty, and valid.
    function grvEditElem( e, makeSelected, makeEdited, makeInvalid, optUnselectColor ){
    	var useColor = makeSelected || makeEdited;
    	grvHighlightElem( e, useColor, makeEdited ? kEditedColor  :
    	                                          kSelectedColor, optUnselectColor );
    }
    function grvEditElemID( ID, makeSelected, makeEdited, makeInvalid ){
    	grvEditElem( grvGetHook(ID), makeSelected, makeEdited, makeInvalid );
    }
    function grvSelectElem( e, makeSelected, optUnselectColor ){
    	grvHighlightElem( e, makeSelected, kSelectedColor, optUnselectColor );
    }
    function grvSelectElemID( ID, makeSelected, optUnselectColor ){
    	grvSelectElem( grvGetHook(ID), makeSelected, optUnselectColor );
    }

    function grvSetElemVisibility( e, visibleFlag )
    {
        if (!e) {if (grvTraceMVC("null setElemVisibility!")) return;}
    	e.style.visibility = visibleFlag ? "visible"  : "hidden";
    	e.style.position   = visibleFlag ? "relative" : "absolute";
    }
    function grvGetElemVisibility( e )
    {
        if (!e) {if (grvTraceMVC("null getElemVisibility!")) return false;}
    	return e.style.visibility == "visible";
    }

    function grvSetElemDisplay( e, visibleFlag )
    {
        if (!e) {if (grvTraceMVC("null setElemDisplay!")) return;}
    	e.style.display = visibleFlag ? "inline" : "none";
    }
    function grvSetVisibility( ID, visibleFlag ){
      grvSetElemVisibility( grvGetHook(ID), visibleFlag );
    }

    function grvGetFormInt( ID ){
    	return parseInt( grvGetFormValue(ID) );
    }
    function grvGetFormValue( ID ){
    	return document.getElementById(ID).value;
    }
    function grvSetFormValue( ID, theValue ){
    	document.getElementById(ID).value = theValue;
    }

    var kMonthNames = new Array(
    				"January","February","March","April","May","June","July",
    				"August","September","October","November","December");
    var kMonthNums = new Array(
    				"01","02","03","04","05","06","07",
    				"08","09","10","11","12");

    function grvGetTodayAsXXDDYYYY(monthNames)
    {
    	var now = new Date();
    	return monthNames[ now.getMonth() ]
    	     + "/" + now.getDate()
    	     + "/" + now.getFullYear();
    }
    function grvGetTodayAsMMDDYYYY(){
      return grvGetTodayAsXXDDYYYY( kMonthNums );
    }

    /**
     * Determine whether a given datestr is explicitly before the given date.
     * @param {String} datestr string rendition of date in Date.parse format
     * @param {Date} date date object to compare to
     * @return true if given date is not empty and before given date
     * @type boolean
     * @author Bruce Wallace (PolyGlotInc.com)
     * @version 2.0
     */
    function grvBefore( datestr, date ){
    	return datestr && datestr.length>0 && ( date > Date.parse(datestr) );
    }

    /**
     * Determine whether given date is at or before a given datestr (where empty means "future").
     * @param {String} datestr string rendition of date in Date.parse format
     * @param {Date} date date object to compare to
     * @return true if given date is empty or after today's date
     * @type boolean
     * @author Bruce Wallace (PolyGlotInc.com)
     * @version 2.0
     */
    function grvAfter( datestr, date ){
    	return( (datestr && datestr.length>0) ? (date < Date.parse(datestr)) : true	);
    }

    /**
     * Determine whether a given date is explicitly before today.
     * @param {String} datestr string rendition of date in Date.parse format
     * @return true if given date is not empty and before today's date
     * @type boolean
     * @author Bruce Wallace (PolyGlotInc.com)
     * @version 2.0
     */
    function grvBeforeNow( datestr ){ return grvBefore( datestr, new Date() ); }

    /**
     * Determine whether today is at or before a given date (where empty means "future").
     * @param {String} datestr string rendition of date in Date.parse format
     * @return true if given date is empty or after today's date
     * @type boolean
     * @author Bruce Wallace (PolyGlotInc.com)
     * @version 2.0
     */
    function grvAfterNow( datestr ){ return grvAfter( datestr, new Date() ); }

    // ----------------------------------------------------------------------------
    // Utility routines for "please wait" indicators
    // ----------------------------------------------------------------------------

    function grvAppName(appId){
    	return appId ? appId : (kAppName?kAppName:"");
    }
    function grvWaitWindowName(appId){
    	return "_gGrvWaitWindow" + grvAppName(appId);
    }
    /** Create an idempotent "wait a minute" window, if one doesn't exist,
     * and squirrel away a reference to it that survives window reloads
     */
    function grvWAIT(appId)
    {
    	// HACK! windows get goofed up if we dont suppress
    	// the "please wait" window on launch...
    	if (_gGrvHackStartupInhibitWait) return;

    	var winName = grvWaitWindowName(appId);
    	if (navigator[ winName ]==null)
    		navigator[ winName ]= grvPleaseWait( true, "Loading data.", appId );
    }
    /** close the "please wait" window if it exists otherwise no effect */
    function grvUNWAIT(appId) {
    	var winName = grvWaitWindowName(appId);
    	if (navigator[ winName ]==null) return;
    	    navigator[ winName ].close();
    	    navigator[ winName ] = null;
    }

    /** are we in "please wait" mode? @type boolean */
    function grvWAITING(appId){ return navigator[ grvWaitWindowName(appId) ]; }

    /** create and open a window (if enabled) with the specified message
     * @param {boolean} enableFlag iff true then create window
     * @param {String} msg message to place in window
     * @return the created window or null if not enabled
     * @type Object
     */
    function grvPleaseWait( enableFlag, msg, appId )
    {
    	var theWindow = null;
    	if ( enableFlag )
    	{
    	 var xMax = screen.width, yMax = screen.height;
         var xOffset = (xMax - 220)/2, yOffset = (yMax - 100)/2;
         theWindow = window.open("", 'grvPleaseWait', 'width=250 height=100 toolbar=no scrollbars=no menubar=no resizable=yes top='+yOffset+' left='+xOffset+'');
         theWindow.document.write("<BODY BGCOLOR="+kColorTeal+">");
         theWindow.document.write("<TITLE>" +grvAppName(appId)+ " Processing...</TITLE>");
         theWindow.document.write('<FONT FACE="Arial" SIZE=2><layer id="c"><left><B>'+msg+'<br/>Please Wait.</left></layer></font><br>');
    	}
    	return theWindow;
    }

    /** set the cursor to the hourglass icon */
    function grvBusy() {
      document.body.style.cursor='wait';
    }
    /** set the cursor to the default icon */
    function grvNotBusy() {
      document.body.style.cursor='default';
    }

    /**
     * generic utility function to queue up for future execution the specified
     * function with the specified arguments after a specified amount of delay.
     * THIS function returns immediately, and the specified function will execute
     * later (in potentially a different thread). If this is called with the same
     * function specified as was specified earlier, and that function has not
     * executed yet, then the scheduled execute time is updated, rather than the
     * function being executed twice.
     * @param {String} funcname the name of the function to call
     * @param {String} funcargs a string image of the parameters to be passed
     * @param {int} optDelayMilliSecs optional delay amount (default 5 milliSeconds)
     * @author Bruce Wallace  (PolyGlotInc.com)
     * @version 2.0
     */
    function grvBusyDo( funcname, funcargs, optDelayMilliSecs )
    {
    	var timedelay = optDelayMilliSecs || 5;
    //	grvBusy();
    	var globalVarName = "_gGrvTimeout"+funcname;
    	if (navigator[ globalVarName ]==null) navigator[globalVarName] = null;
    	if (navigator[ globalVarName ]!=null) clearTimeout( navigator[globalVarName] );
    	    navigator[ globalVarName ] = setTimeout( funcname+funcargs, timedelay );
    }

    // ----------------------------------------------------------------------------
    // Utility routines for URL Handling
    // ----------------------------------------------------------------------------

    /** This decodes URL-encoded strings because the Javascript
     * function "unescape" only does part of the job; adapted from
     * <a target="_blank" href="http://www.albionresearch.com/misc/urlencode.php">here.</a>
     * @param {String} encoded the URL-encoded string to translate
     * @return decoded version of given encoded string
     * @type String
     * @author Bruce Wallace (PolyGlotInc.com)
     * @version 2.0
     */
    function grvURLDecode( encoded )
    {
       // Replace + with space
       // Replace %xx with equivalent character
       // Put [ERROR] in output if %xx is invalid.
       var HEXCHARS = "0123456789ABCDEFabcdef";
       var plaintext = "";
       var i = 0;
       while (i < encoded.length) {
           var ch = encoded.charAt(i);
    	   if (ch == "+") {
    	       plaintext += " ";
    		   i++;
    	   } else if (ch == "%") {
    			if (i < (encoded.length-2)
    					&& HEXCHARS.indexOf(encoded.charAt(i+1)) != -1
    					&& HEXCHARS.indexOf(encoded.charAt(i+2)) != -1 )
    			{
    				plaintext += unescape( encoded.substr(i,3) );
    				i += 3;
    			} else {
    				throw 'Bad escape combination near ...' + encoded.substr(i);
    				i++;
    			}
    		} else {
    		   plaintext += ch;
    		   i++;
    		}
    	}
       return plaintext;
    }

    /**
     * @class This function parses ampersand-separated name=value
     * argument pairs from the query string of the URL; It stores the
     * name=value pairs in a static list; adapted from
     * <a target="_blank" href="http://www.oreilly.com/catalog/jscript3/chapter/ch13.html#ch13_08.htm">here.</a>
     * @author Bruce Wallace (PolyGlotInc.com)
     * @version 2.0
     */
    function grvArgs( anArgName )
    {
    	if ( grvIsUndefined(grvArgs.ARGS) )
    	{
    		grvArgs.ARGS = new Object(); //private singleton

    	    var query = location.search.substring(1);  // Get query string.
    	    var pairs = query.split("&");              // Break at ampersand.

    	    for (var i=0; i<pairs.length; ++i)
    	    {
    		  var pos = pairs[i].indexOf('=');            // Look for "name=value".
    		  if (pos == -1) continue;                    // If not found, skip.
    		  var argname   = pairs[i].substring(0,pos);  // Extract the name.
    		  var value     = pairs[i].substring(pos+1);  // Extract the value.
    		  grvArgs.ARGS[argname] = grvURLDecode(value);// Store in LIST.
    	    }
    	}

        return grvArgs.ARGS[ anArgName ];	// Return the specified argument
    }

    function grvGetArg( argname ) {
    	return grvArgs( argname );
    }

    function grvIsChecked( ID )
    {
      var checkbox = document.getElementById( ID );
      return checkbox.checked;
    }

    /** send a message to the browser status bar
     * @param {String} msg the message to send.
     */
    function grvSendStatusMessage( msg )
    {
        window.status = msg; grvTraceMsg(msg);
        window.status = "";
    }

    // ----------------------------------------------------------------------------
    // Utility routines to convert entities into strings
    // ----------------------------------------------------------------------------

    function grvObjectToString( o )
    {
    	var s = "";
    	for (var property in o)// iterate over all properties
        	s += "Property [" + property + "] is [" +  o[property] +"]\n";
        return s;
    }
    function grvObjectToInitializer( o )
    {
    	var s = "{\n";
    	for (var property in o)// iterate over all properties
    	{
    	  var q = (o[property] instanceof Function) ? '' : '"';
    	  s += property + ':'+q + o[property] +q+',\n';
        }
        return s.substring(0,s.length-2)+"\n}";//get rid of dangling comma
    }
    function grvObjectToShortInitializer( o )
    {
    	var s = "{\n";
    	for (var property in o)// iterate over all properties
    	{
    	  var P = o[ property ];
    	  if (!(P instanceof Function))
    	       s += property + ':"' + P + '",\n';
    //	  else s += property + ': function,\n';
        }
        return s.substring(0,s.length-2)+"\n}";//get rid of dangling comma
    }
    function grvArrayToString( a )
    {
    	var s = "";
    	for (var i in a)// iterate over all array items
        	s += "["+ i +"] is ["+  a[i] +"]\n";
        return s;
    }
    function grvArgsToString( args )
    {
         var s = "";
         for (var i=0; i<args.length; ++i)// iterate over all function args
        	s += "["+ i +"] is ["+  args[i] +"]\n";
         return s;
    }

    ///// GLOBAL-PERSISTENCE VARIABLES ROUTINES /////

    function grvPersistentVar()
    {
    	if (navigator._gGrvGlobalMap==null) navigator._gGrvGlobalMap = new Object();
    	return navigator._gGrvGlobalMap;
    }

    /** static routine to dynamically define/update a persistent (across page loads)
     * variable with the given name and value.
     * @param {String} varname name of "persistent" variable
     * @param {Object} value value to set variable to
     */
    function grvSetPersistentVar( varname, value ) //persisted across page loads
    {
    	grvPersistentVar()[varname] = value;
    }

    /** static routine to return the value of the persistent variable with given name
     * @param {String} varname name of "persistent" variable
     * @return {Object} value of variable (empty object if not previously defined)
     * @type Object
     */
    function grvGetPersistentVar( varname )
    {
    	return grvPersistentVar()[varname];
    }

    /** static routine to dynamically undefine/delete ALL "...PersistentVars" variables  */
    function grvClearPersistentVars(){ grvPersistentVar() = null; }

    function grvGlobalVar()
    {
    	if (window._gGrvGlobalMap==null) window._gGrvGlobalMap = new Object();
    	return window._gGrvGlobalMap;
    }

    /** static routine to dynamically define/update a global (to window/page
     * but reloaded with page) variable with the given name and value.
     * @param {String} varname name of "persistent" variable
     * @param {Object} value value to set variable to
     */
    function grvSetGlobalVar( varname, value )
    {
    	grvGlobalVar()[ varname ] = value;
    }

    /** static routine to return the value of persistent variable with given name
     * @param {String} varname name of "global" i.e. "static" variable
     * @return {Object} value of variable (empty object if not previously defined)
     * @type Object
     */
    function grvGetGlobalVar( varname )
    {
    	return grvGlobalVar()[ varname ];
    }

    /** static routine to dynamically undefine/delete ALL "...GlobalVars" variables */
    function grvClearGlobalVars(){ grvGlobalVar() = null; }

    /** static routine to dynamically undefine/delete a global variable
     * @param {String} varname name of "persistent" variable
     */
    function grvClearGlobalVar( varname ){ delete grvGlobalVar()[ varname ]; }

Overview | File | Class | Tree | Index | Help
| The Gravey 2.0 Framework and AIM RIA
PREV NEXT | FRAMES NO FRAMES

Documentation generated by JSDoc on Sun Feb 11 13:31:42 2007