November 2010

  dSurvey: library of useful javascript procedures. These are used by several other libraries, so this is a "root" library


A note on global variable:
   Two kinds of global variables may be used by javascript programmers:
        javascript-globals : Defined in the main javascript (on the front page) or in javascript functions, using
                              standard syntax
        dSurvey-globals     :Defined using the Save_Globals (or variants thereof) and read using Read_Globals.
                           
    For several reasons, including avoiding variable name clashes, "dSurvey globals" are used extensively.  However, a few
    "javascript globals" are used, such as variables that identify the participant and session.



***  Summary of functions  *** 

String manipulation:
  newstring =  strip(astring,which)          : strip spaces
  newstr    =  space(str,what)               : remove/replace internal spaces
  notMatch   = compareStrings(string1,string2,optstring) : compare 2 strings, return 0 if same
  ithWord=  =  Word_inString(needle,haystack,icase)  : find word number in haystack that matches needle
  astring   =  manyDots(aval,amax,dastring)  : create a string of dots, the number cycling between 1 and amax
  words2    =  parseAt(astring,adelim)        : parse string into two sections, return as 2 element array
  aword     =  parseUsing(astring,leftc,rightc,all3)         : return phrase between the first leftc char and next rightc char -- such as ( and )
  aword     =  parseUsingOuter(astring,leftc,rightc,all3)    : return phrase between the first leftc char and last rightc char -- such  [ and ]
  atime     =  Seconds_ToTime(nseconds)      : convert nseconds to time format (i.e.;  hh:mm:ss
  thewords   = getWord(astring,nth,adelim)   : parse string to array of words, or extract nth word
  argArray   = parseArgString(vv)            : parse a string into an array, using , as seperator -- but NOT if comma is inside of " or '
  cvalue     = addCommas(avalue)             : add commas to a number , in the proper positions (doesn't change decimal portion of number)
  astuff     = matchWild(orig,acand)         : orig has a *, and wildcard matches acand, return portion of acand covered by the *
  dstring = svy_dollars(avalue)              : return a $xx.yy string, given a value
  newString=splitString(astring,ilen,abr)    :   Split string into ilen long chunks
  aTable=makeATable(alist,ncols2,astyle,athrow,tablespec) :  Given a list, create a table

  newname=cvtToArrayName(aname0)             : convert a varname_n_ to varname[n].
                                               Last character MUST be a _. Thus, varname_3_a will NOT be changed
  newname=cvtFromArrayName(aname0)           : convert a varname[n] to varname_n_.


Array manipulation:
  newarray  = Concat_Arrays(a1,a2,a3,a4,a5)                 : concatentate from 1 to 5 arrays or nodelists (or copy an array)
  theindex = find_InArray(tofind,anarray,adef,verbose,err)  :   Case insensitive find  in array. Returns index into anarray. Ignores element 0


dSurvey global variable read/write:
  Show_Variables(adiv,retstr)                     : Display current dSurvey global variables & arrays in a new window
  avalue=Read_Global(varname,undef,anindex)       : read the  survey-global variable specified in the varname string (can be an array element). undef is optional error message
  Save_Global(varname,avalue,anindex,forcea)      : save avalue to survey-global variable specifed in the varname string. varname can be an array element
  Read_priorGlobal(nth,vname,deff,aindex)         : Read value of  variable from the dSurvey archive.
  Save_priorGlobal(nth,vame,avalue,anindex)       : Save value of a variable to the dSurvey archive
  Save_GlobalHistory(nowr)                        : Save all current survey-global variables to a history archive
  Retrieve_GlobalHistory(nowr,No_overwrite)       : Retrieve the "nowr" round of survey-global variables, and copy them to the current set of globals
  Reset_recentHistory()                           : Zero out recent history variables

Element attribute manipulation:
   getAttributes(anode,attlist,adefs)             : retrieve attributes of anode
   get_elemValue(e1,defval,mods)                  : read value of an element (INPUT, OPTION, or other). returns defval if not found (radio and checkbox)
   ok= set_elemValue(e1,newval)                   : set value of an element (INPUT, OPTION, or other)
   Find_Class(daclasslist,this1)                  : T/F if classlist (a string var) contains  is one of the classes of the this1 element.
   Find_Name(namelist,this1)                      : T/F if namelist (a string var) contains the value of this1's name attribute
   get_elements(a_names,classname,namelist )      : Return an array of elements in "a_name", have a class in classname, and has a name in namelist
   get_elements_remove(a_name,classname,namelist) : Return an array of elements in "a_name", thad do NOT have  a class in classname, and NOT a name in namelist
   delete_elements(chkElement,daflag,namelist)    : delete a list of elements (uses get_elements)
   Add_Attribute(elemList,d_attribute,d_val,append)    :  Add an attibute, and its value, to elemList elements.
    update_styles(elemList,styleString)                : Update style attribute to elemList elements
    update_class(elemList,classname)            :   Add a class to elemlist elements
   svy_addID(aelem)                             : return, or create, an id for an element

Event handlers (typically used as afunction in the Add_Event procedure)
  Add_Event(elemList,etype,afunction)    :  Add event handlers; for etype events using afunction as the handler, to a set of elements 
    Arrow_Increment(e)                   :   Allow use of arrow keys to change numeric values; uses the "default" attribute as a default value.
    Check_Bounds(e)                      :   Check the bounds of an input field for min and max (using min and max atttributes)
    Check_Char(e)                        :  Capture keyboard and return an identifying string if arrow or other such key is hit
    Confirm_Input(e)                     : Check an input element's values for questionables (uses minConfirm, maxConfirmm, allowedConfirm, and nameConfirm attributes)
    disable_autocompletes(daflag)        :  Turn off autocompletes AND contextmenu in all input boxes with a daflag class

File retrieval procedures:
    Get_xmlFile(XMLfilename,varname,acomment,afunc,arg1,arg2,arg3,arg4,arg5)     : retrieve XMLfilename, save to varname, after saving call afunc(arg1,...,arg5)
    Get_File(filename,varname,acomment,afunc,arg1,arg2,arg3,arg4,arg5)           : retrieve text filename, save to varname, after saving call afunc(arg1,...,arg5)
    Post_toServer(url,acontent,varname,acomment,afunc,arg1,arg2,arg3,arg4,arg5)  : put acontent to server (using aURL), save response to varname, after saving call afunc(arg1,...,arg5)
    Display_Content(varname,target,wopts) : Show  contents  of the variable specified in "varname" in the target window (varname usually html file from a Get_File call). Varname MUST be a string!


HTML Display and check procedures:
   Check_RadiosDone(formname,varlist,errmess)       :  Checks that a list of radio buttons have been chosen from.
   Highlight_One(me1,aname,astyle)                  : Highlight (change style) of one of a set of named elements
   writeStatus(m1)                                  : write a message to the page status div (at the bottom of the screen
   writeAlert(amess,duration)                       : write a message to the yellow alert box, of duration seconds
   displayDiv(adiv,todo)                            : adiv to toggle between block and none. Or, if todo specified, to the todo status
   htmlSurround(tagname,string)                     : return a string: <tagname>string</tagname> (used in <set>)

Other:
    make_procString(pname,arg1,arg2,arg3,...,arg8)     : Make a function string, with quoted arguments, suitable for use as an onClick, etc argument.
    Launch_Proc(pname,pwait,arg1,arg2,arg3,arg4,arg5)   : Launch a procedure using setTimeout
    evaluate_function(funcString,amess,elem)            : evaulate a string containing a function
    resolveRelativeURL(url,baseUrl)                     :  if url is "relative", prepend the directory of the baseURL
    debugOn(level)                                      :  return true if debug enabled and has level >alevel (alevel default value is 1)
    svy_cloneObject(what)                               : CLONE an object (that may contain other objects and arrays)

    numSibling(anode,notext)                  : number of siblings (including self) of anode (can exclude non-elements
    whichSibling(anode,notext)                : position number in siblings of anode (1,...,)
    getSibling(anode,nth,notext)              : return pointer to nth sibling of anode (possibly skip non-elements)
    removeHTMLTags(htmlString)                : extract text from a string containing html 


    isIE()                                              :  return 1 if Internet Explorer
    isfalse()                                           : returns a false

========== Function details =======================

 --- String functions --

strip 

  newstring=strip(astring,which)

     Strip leading and/or training spaces
        If which is L, then leading only (left),
                    R, then trailing (right) only
     Otherwise (if not specified), leading and trailing
     If astring is a number, it is converted into a string.
     If it is an object, nothing happens

space

   newstr=space(str,what)

       Remove spaces (either shrink to 1 space, or remove altogether)
       what is a character string to replace spaces with. If not specified, ' ' (shrink to 1 space) is used.
       This does NOT strip leading and trailing spaces


compareStrings

   notMatch  = compareStrings(string1,string2,optstring) 

     Compare two strings, return first character that is different (1= means first character)
     If strings are identical, return a 0
     By default, strings will have spaces stripped, and will be capitalized

     You can control this with optstring.
         optstring should be a space delimited list of options
          Supported options are: case  nostrip  crunch  tabspace crlspace
             case : case sensitive search
            strip : strip leading and trailing spaces
           crunch : crunch internal spaces (sequence of spaces collapsed to one space
         tabspace : convert tabs to 1 space
        crlfspace : convert crlfs to 1 space

     Note that crunch occurs AFTER strip (a crunch will NOT remove a leading & trailing space)

     Examples:
       nn=compareStrings('this is real ','This is real') --> 0
       nn=compareStrings('this is real ','This is real','CASE') --> 1
       nn=compareStrings('This is real ','This  is real') --> 6 (two spaces in string 2 after This)
       nn=compareStrings('This is real ','This  is real','CRUNCH') --> 0
       nn=compareStrings('This    is real ','This\tis real','CRUNCH TABSPACE ') --> 0  (tab is converted to spacd



Word_inString

  Word_inString(myneedle,myhaystack,useCase) {

  where :
    myneedle : space delimited list of words to search for
    myhaystack : space delimited list of words to search in
    usecase :  case sensitivity flag

   See if any of the words, possibly wildcarded, in myneedle are in the list of words in myhaystack

   If useCase not specified, or is 0, uses a case insensitive search and possibly * wildcarded search (myneedle can contain words with * in them)
    useCase=1: use a case SENSITIVE search

    return value is the word number in HAYSTACK that is matched (starting at 1), or 0 if none

   Needle can be more than one word. In which case, first match is a success (return is the word matched in haystack that matches one of the words
   in needle)

    example:
         ifoo=Word_inString('cruel','hello Cruel world ',0);
    would return 2

manyDots

  astring=manyDots(aval,amax,dastring)
        Create a string of dots.
             Aval : The length of the string to return. Required.
             Amax : optional. The maximum length. If aval>amax, the remainder of aval/amax is used.
                      Default value=10
         dastring : optional. The default is ".................."
                      If you want to create a string of something else, specify dastring.

parseAt

    list2=parseAt(astring,adelim)

       Parse a string into a 2 element array, splitting at the adelim character.
       adelim will NOT appear in either element of the array.
       The split only occurs at the first adelim -- hence the 2nd element may contain adelim
       If adelim not specified, comma is used
    Examples:
          b2=parseAt('this is, really and truely, a bad phrase ')
            b1[0]='this is'
            b1[1]='really and truely, a bad phrase ')

          b2=parseAt('this is short ')
            b1[0]='this is short'
            b1[1]='')

          b2=parseAt('this is short ','')
            b1[0]='this'
            b1[1]='is short')

parseUsing

  aword=parseUsing(astring,leftc,rightc,all3)
           Returns a substring from astring, as delimited by the leftc and rightc character.
           The first firstc delimiter is used, and the rightc following the firstc.

           If leftc exists but not rightc, returns the string after leftc to the end
           If rights exists, but not leftc, returns ''
              If rightc is not specified, return  from first leftc to end of string (not inclusive)
              If leftc is not specified, return to last rightc (not inclusive)
          If all3=1, return a 3 element array:
                [0] : stuff before leftc
                [1]  : between leftc and rightc (non-inclusive)
                [2]  : stuff after rightc

          Examples:
                astring='this is[very simple]for me'
                '
              aval=parseUsing(astring,'[',']') -->   "very simple"
              aval=parseUsing(astring,'',']') -->   "this is[very simple"
              aval=parseUsing(astring,'[','' ) -->   "very simple]for me"
              aval=parseUsing(astring,'[','x' ) -->   "very simple]for me"
              aval=parseUsing(astring,'x',']' ) -->   ""
              aval=parseUsing(astring,'x','y' ) -->   ""

              aval=parseUsing(astring,'[',']',1) -->   "this is", "very simple", "for me"
              aval=parseUsing(astring,'',']',1) -->     "" , "this is[very simple", "for me"
              aval=parseUsing(astring,'[','',1 ) -->    "this is", "very simple]for me", ""
              aval=parseUsing(astring,'[','x',1 ) -->   "this is", "very simple]for me", ""
              aval=parseUsing(astring,'x',']',1 ) -->   "this is[very simple]for me" , "" , ""
              aval=parseUsing(astring,'x','y',1 ) -->   "this is[very simple]for me" , "" , ""

              aval=parseUsing("the var[9] is set ",'[',']') will return "9"

parseUsingOuter

  aword=parseUsingOuter(astring,leftc,rightc,all3)
      Similar to parseUsing, except use the LAST rightc character (search backwards from the end of the string).
      Example:
          aval=parseUsing('%group[%which_ticket[%mychoice],3]','[',']')  -- will return '%which_ticket[%mychoice,3'
      while
          aval=parseUsingOuter('%group[%which_ticket[%mychoice],3]','[',']')  -- will return '%which_ticket[%mychoice,3],3'
   T

seconds_ToTime

  atime=Seconds_ToTime(nseconds)

        Converts a number of seconds to a  hh:mm:ss time format.
        Example: atime=Seconds_ToTime(250)
                 yields "04:10" (without the quotes)
                 atime=Seconds_ToTime(50)
                  yields ":50" (without the quotes)
getWord

  thewords   =  getWord(astring,nth,adelim)
       Parse string to array of words, or extract nth word

      arguments:
          astring : a string containing words; by default seperated by one or more spaces. 
          nth     : optional. Nth word to return. If not specified, or 0, array of all words returned
                    Thus, word "1" is the first word in the string.
          adelim  : optional. A delimiter. If not specified, a space (or spaces) is used

       If adelim =' ' (or ''), which is the default, then unique "words" are returned -- spaces are NOT considered
       to be words, nor are ever   part of a word.  If adelim is anything else, then no attempt to 
       shorten words (the delimiter is used as is).

        If nth is > # of words, a '' is returned.
        As noted above, if nth=0, an array containing all the words is used.
        Since this removes extaneous spaces, the results are more robust than .split(' ')

       Special case: if nth is an array, then return a string of words from nth[0] to nth[1], inclusive
       eg: toget=[2,3] ;
           foo=getWord("this is not very silly",toget)
           would return "not very"

      Examples:
          astring="this is my string of words "
            getWord(astring,1) = "this"
            getWord(astring) = array of 6 elements 
            getWord(astring,7)=''
            toget=[3,4] ;  foo=getWord(astring,toget)  = "my string"

parseArgString

  argArray= parseArgString(vv,noquote)                
  
    Parse a string into an array, using , as seperator -- but NOT if comma is inside of " or '
    If noquote is specified and equals 1, then ' and " are stripped from ends of arguments.
    Example:   z=parseArgString("this,that,'my, friend',those",1);
               would yield: z[0]="this",  z[1]="that", z[2]="my, friend", z[3]='those'

    Example:   z=parseArgString("this,that,'my, friend',those");
               would yield: z[0]="this",  z[1]="that", z[2]="'my, friend'", z[3]='those'
               Note that z[2] retains the ' characters               

addCommas:

        newstring=addCommas(numval)

   Add commas to numval. Decimal component will not be changed.
    
 cvtToArrayName(aname0)
   Convert a varname_n_ to varname[n].
   Will always STRIP and capitalize
   Last character MUST be a _. Thus, varname_3 or varname_3_a will NOT be changed

      Example: foo2=cvtToArrayName('hello_2_') would yield HELLO[2]

cvtFromArrayName(aname0)
   convert a varname[n] to varname_n_.
   Will always STRIP and capitalize
   Last character MUST be a ]. Thus, varname[3  or varname[3]a  will NOT be changed

     Example: foo2=cvtFromArrayName('hello[3]') would yield HELLO_3_


matchWild(orig,anew,all1) {


   orig has a * in it : compare orig to anew, if wildcard match, return the part of anew "covered" by the * in orig
   or, return orig with this portion replacing * (if all1=1)
   in either case, if no match return a ''
   
   Example:
      foo=matchWild('H[*]','H[12]') --> 12
      foo=matchWild('H[*]','H[12]x') --> ''
      foo=matchWild('H[*]','AH[12]) --> ''


-- Array manipulation --

Concat_Arrays

   nearray=Concat_Arrays(a1,a2,a3,a4,a5) {

         Create an array that is the concatenation of up to 5 arrays and nodelists.
          a1...a5 : arrays or nodelists.
         If you just specify a1, then newarray will be a copy of a1

         This is useful since nodelists do NOT have a concat function
         It is also useful since it "clones" :  a new array is returned.
        
         Thus:   foonew=Concat_Arrays(fooOld) will create a new array -- foonew can be changed without effecting fooOld

find_InArray

      theindex=find_InArray(tofind,anarray,adef,verbose,errmess) {

    Case insensitive find  in array -- returns index into anarray
                tofind : the string to look for
                anarray : array with strings. Array element 0 is ignored 
                adef : if tofind ='' then return adef (no searching done)
                verbose : if 1, show an error message if unfound (show errmess also, if specified)
                errmess : error message (if not specified, '...' is use)
        If no match, return 0


svy_dollars
  dstring = svy_dollars(avalue)                  return a $xx.yy string, given a value

  Given a numeric value (avalue), returns a string of the format $nnnn.dd   (preceded by a $ sign, with 2 digits to right of decimal point).


makeATable

  aTable=makeATable(alist,ncols2,astyle,athrow,tablespec) {

  Given a list, create a table

    alist: array of string element to use when creating table
    ncols: number of columns in this table. If 2 elment array, 2nd element is "new row" signal (if not specified, 5 is used)
            the new row signal, if specified, is compared to elements in alist. If an element matches
            (exactly, case and spaces are used), then a new row is started (the element(s) that match
           will NOT be included in the table
   astyle: style to use when displaying elements of table (use '' if no extra styles are to be added)
            Or, astyle can be an array. Each element of the array is matched to a column.
            If # columns > astyle.length, use the last element in astyle (for these "extra" columns)
   th1  : if specified, use this as top row(s) of table, using <th>  (use 0 to ignore)
   tablespec: string to include verbatim in the <table >



splitString 
     newString=splitString(astring,ilen,abr)    

     Split string into ilen long chunks, using abr to seperate the chunks.
     The chunks can be less then ilen characters if a ' ' or a '_' is within 3 characters
     of the end of the chunk.

      Examples:
         new1=splitString('hello ',10,'|')   ==>  'hello '    (no change)
         new1=splitString('helloWorld',5,'|')   ==>  'hello|World '    (split after 5 characters)
         new1=splitString('hello CruelWorld',5,'|')   ==>  'hello|CruelWo|rld '    (split at no 7 characters, or at a ' ')
         new1=splitString('hello CruelWorld',10,'|')   ==>  'hello Crue|lWorld '    (space not close to end of "chunk")
        
         Hint: you can us abr='<br>' to break up string for displaying via html.

 -----  dSurvey global variable read/write:  -----

Show_Variables

  Show_Variables(adiv,retstr)

      Display current dSurvey global variables & arrays in a new window.
      This is a debugging tool.

   If adiv specified as a string -- display content in the adiv element (that has an id of adiv).
   If retStr=1, return as a string.

Read_Global

  avalue=Read_Global(varname,undef,anindex)

        Read a  survey-global variable named in the (case-insensitive) varname (string) variable
        varname can be an array.
        If anindex is included, it is used as the index of the varname array. If varname already includes a [xx],
        then [xx][anindex] will be read.  Note that anindex can be a number, or a string (string is useful if
        the varname array contains objects).

        Example: xv=Read_Global('MyVars[3]','') ;
                 xv=Read_Global['MyVars','',3);  ;         // same as above

        Example: xv=Read_Global('MyVars[3][2]','nosuch') ;
                 xv=Read_Global['MyVars[3]','nosuch','2');  ;         // same as above

        The undef argument is optional. If used, it should be an error, possibly a string  "error message".
        It will be returned if the variable is undefined. If undef is not defined, 'n.a.' is returned
        (when the variable is undefined).

Save_Global

  Save_Global(varname,avalue,anindex,forceArray)
        Save avalue to a survey-global variable named in the varname (case-insensitive string) variable
        varname can be an array -- if the array does not exist, it will be created
        If anindex is included, it is used as the index of the varname array (see Read_Global for more details)
        Example: Save_Global('MyVars[3]','30.3');
        If avalue is an array object, and you want to save varname as an array, set forceArray=1
                Example:
                    var alist=[1,5,102];
                    Save_Global('myList',alist,1,1);
                where the 3rd argument is an offset. So, a value of 1 means "start the values at index 1, not 0"
       Note that if avalue is NOT an array object, but you specify forceArray=1, then a single element array will be created.


Read_priorGlobal
     aval=Read_priorGlobal(nthround,varname,undef,arrIindex) {

     Similar to Read_Global, but pulls from the nthround of the priorRound database (the "history" database)


        nthround: the index to the priorRound (i.e.; which round) . Typically, a round number
                  (say, a number used in a prior call to Save_GlobalHistory)
                 If nthround ='', then retrieve from the "$recent" round.
        varname,undef,arrIndex: same as in Read_Global

       Example:  foo=Read_priorGlobal(5,'cost[1]','',3)
                  would return the value the cost[1][3] from archive for "round" 5. If no such variable (or "round") return a ''

Save_priorGlobal

   Save_priorGlobal(nthround,varname,avalue,anindex,forceArray) {

     Similar to Save_Global, but saves a single variable to the nthround of the priorRounds (the "history")
     database

        nthround: the index to the priorRounds (i.e.; which round). Typically, a round number.
                  In addition, save to the  "$recent" round.
                  If nthround='', only save to the '$recent' round.

        varname,avalue,anindex.forceArray : same as in Save_Global


Save_GlobalHistory

  Save_GlobalHistory(nowr)

         Saves all of  current  "global" variables to the nowr "round" of the priorRounds (history) variables.
         If nowr not specified, use the value of the "nowround" global variable.
            If nowround doesn't exist, use 0.

         To save just one variable, use save_priorGlobal.

Retrieve_GlobalHistory

 Retrieve_GlobalHistory(nowr,No_overwrite)

       Retrieve from the nowr "round" of the priorRound (history) variables, and write to current global variables.
       If nowr='', read from the '$recent' round.

       To retrieve one variable from a prior round, use Read_priorGlobal

       Arguments:
                      nowr:  index to the priorRound variables. If not specified, or '',  use "startup"
             no_overwrite :   if 1, add values from archive to current dSurvey-globals (overwriting variables of the same name)
                              Otherwise, remove ALL variables from the current dSurvey-globals (basically, overwrite/replace
                             all dSurvey-globals)

       Special case:
               if nowr='$LASTSAVE', return the round number of the most recent Save_GlobalHistory

      returns:
          0      - failure (the requested dSurvey-global archive does not exist)
          1      - success - overwrite dSurvey-globals
          2      - sucess, no overwrite, but no variables found in object
          n>2..  - success, n-2 variables retrieved
                  Thus, a return of "10" means "8 variables were extracted from the requested dSurvey-global-archive"


Reset_recentHistory

  Reset_recentHistory()

     Clear recent round in the priorRound (history) database

  Reset_recentHistory(nowr)

     Clear recent round in the priorRound (history) database, and then copy the nowr round's value
     from priorRound to the recent round in priorRound.  

        
  The "recent round" variables are read using  VARNAME.

  Note that nornmally, recent round variables are created whenever a
  a VARNAME. or VARNAME.nthround variable is written.
  In the latter case, two values are written: one for the "recent round", and one for the "nthround" round.


       -----  read/write element values and attributes  -----


getAttributes

    attrs= getAttributes(anode,attlist,adefs)

    For the andoe "node", find the values of the attributes listed in attlist (a space delimited list).

        anode: dom node that may have attributes
        attlist : space delmited list of case-inSensitive attributes
        adefs : defaults

   Two formats: multiple attributes and one attribute. They are chosen by how adefs is specified: as a string or as an object.

    Multiple:
        Adefs is either unspecified, or is an object.
        Returns an object with elements listed in attlist ( using capitalized & stripped) used as indices.
        If an attribute (in attlist) does not exist, a value of '' is returned, or a default is pulled from adefs.
          If adefs is not specified, '' is the default for all attributes.
          If adefs is specified and is an object, the defaults values for the attlist attributes is read from adefs (it they exist)

        Example: if attlist="a1a A2 A4"
            anode has attributes A1a="11"  A3="33"
            adefs['A2']='miss1';
          Then using
             newobj=getAtributes(anode,attlist,adefs);
          yields:
            newobj['A1A']='11'          -- note use oF capialized "a1a", note case insensitive match of "a1a" and "A1a"
            newobj['0~A1A']='A1a'     -- the 0~ prefix is used to find original (case preserved) attribute name
            newobj['A2']='miss1'
            newobj['0~A2']='A2'     -- the 0~ prefix is used to find original (case preserved) attribute name
            newobj['A4']=''            -- if no attribute found, no 0~ object-element created
         Note that newobj['A4'] is set to '' (since it is not an attrtibute of the node, and it was not defined in adefs)
         Also note that newobj['A3'] is NOT an element of newobj, since A3 does not appear in attlist

    Single:
        Adefs should be a string, with '' a valid string.
        Return the value of the first encountered attribute (in attlist) as a string. If none of the attributes listed in attlist are
        round, return the value of adefs.
         Example (assuming a1a="11" is the only attribute of anode):
             aval=getAttributes(anode,'a1a','')
          returns '11'
             aval=getAttributes(anode,'a1ab','xx')
          returns 'xx'
             aval=getAttributes(anode,'a1ab',null)
         returns null

         Hint: to check for existence of an attribute, set adefs=null, and check for a null value:
              Example:
                  aval=getAttributes(anode,'value',null);
                  if (aval===null) alert("no value!" );

get_elemValue 

     daval= get_elemValue(e1,defval,modifiers)     : 

    Returns the "value" of an element.

             e1  : an element.  Or a string containing a name of an ID (element with this id=name is used)
                 Returns defval if no such ID=name element.
           defval : value returned if not selected (RADIO, CHECKBOX, OPTION). Default is '' (an empty string)
                   Note: an INPUT type="text" or "hidden", or a textarea,  an unfilled or unspecified value a "" (defval is NOT used).
           modifiers : strip, case, or space removal flags. Default is no modification.

        This works with two sets of elements:
              INPUT and OPTION and TEXTAREA : reads  & returns the value="" attribute.  For RADIO, CHECKBOX, and OPTION, returns defval
                                if not-checked (or not selected). For INPUT, returns "" if no value attribute exists (or the value attribute equals "").
              All other  : reads & returns  the innerHTML
                
        Modifiers:
               '1'   : strip and capitalize (strip means "remove leading and trailing spaces)
               '0'   : strip
           or, specify any mix of 1 letter codes:
               S   : strip
               U   : upper case         
               L   : lower case
               R   : remove ALL spaces (including embedded spaces)
               N   : check if numeric. If not (if isNaN=true), return defval
           Examples: 'SU' (same as '1')
                     'N'   
                     'RL'

        Notes:
          * in typical use, all INPUT (and OPTION) elements will be examined -- thus unchecked radio buttons will
              be examined (and will have defval returned).  
          *  Also, it is recommended that each OPTION element have it's own name (to avoid the need to lookup the name
             of its SELECT).
          *  Tecnhical Note: For INPUT and OPTION and TEXTAREA, values are read using e1.value.
                             Sometimes this doesn't work right, in which case getAttribute('value') is used.

set_elemValue

   ok= set_elemValue(e1,newval)     : 
        Sets the "value" of an element.
             e1  : an element. Or a string containing a name of an ID (element with this id=name is used)
           newval : new value assigned to the element.

        This works with two sets of elements:
              INPUT and OPTION : sets the value of the value attribute to newval.
                                 To avoid odd problems, sets with both elem.value and elem.setAttribute('value')
              All other  : change the value of the innerHTML
          
         Returns 1 if success, 0 if failure (failure only occurs if e1 is a string and no such ID can be found)      


Find_Class

  qis=Find_Class(classlist,aelem)
        See if classlist (a string variable) contains contains one of the classes of the aelem element.
        Uses a case insensitive, possibly wildcarded search (uses Find_InList)
        Return >0 if yes, 0 if no (or if no classes in this element)

Find_Name

  qis=Find_Name(namelist,this1)
    See if namelist (a string variable)  contains the name field of the this1 element
    Uses a case insensitive search, possibly wildcarded search (uses Find_InList)
    Returns 1 if yes, 0 if no (or if no name for this element)



get_elements

  nlist=get_elements(tname,classname,namelist )

     Returns an array containing elements that match tname and classname.

          tname:    tname can have several forms:
                        "tagname"    : Elements with this tag will be considered (i.e.; "INPUT")
                        "id."        : Elements that are inside of an element (say, a DIV) with this ID are considered.
                        "id.tagname" : Elements with this tagname, that are inside of a parent (say, a DIV or SPAN) with this id,
                                       are considered
                      Or,
                                 a mixture of the above 3 in a space delimited list -- in which case lists are created for
                                 each element, and then combined. Double counts are NOT checked for!
                      Or
                        array_of_elements : Elements reference by this array will be considered.
                                            For example, an array created by an earlier call to get_elements
                     Notes:
                           * if tname ='' or 0, all elements will be examined
                           * you can consider "tname" as a shortcut for "document.tagname"

          classname :  
                        Classname can contain a single name, or multiple names in a space delimited list
                       If included, only elements with one of the names in classname are considered (i.e.; "KEYINC"). 
                        Or, classname='' for "all classes"
                        If not included, all classes.
                        Note: alist=get_elements('',aclass) can be used like as a "getElementsByClassName" function

            namelist:  If included, elements must ALSO have a name that appears in the name list (case insensitive).
                       If not included, any name (or no name) is okay.
                       Special case: if a namelist item contains a *, a wildcard match is done
                       Special case: if name includes (typically at end) the # character, the # character is replaced by the
                                     value of the IDX attribute (if no IDX attribute, it is removed).
                                     This is sometimes more focused than using *.
                                     Examples:
                                          <input name="FOO1" idx="1">
                                           ...
                                          alist=get_elements('input','','FOO#')
                                      get_elements will add "1" to the 'FOO' argument, and the result ('FOO1') matches

                                          <input name="FOO1" idx="1">
                                           ...
                                          alist=get_elements('input','','GOO#')
                                      get_elements will add "1" to the 'GOO' argument, and the result ('GOO1') does NOT match
                                        
                                       
        In the simplest case of tname, where just a tagname is specified (such as "INPUT")
            a) it must have a matching tag name (case insensitive);  
            b) it must have a matching class (in the list of classes defined for the element) (case insensitive)
            c) if namelist is not specified, that's all. If namelist IS specified (and !=0 or '') then the 
               name of the element must appear in the namelist (case insensitive match)

       Examples:
               alist=get_elements('myResults.input')
                      Returns an array of all elements in with an INPUT tagname in an element with id="myResults"
                      Note: you can consider "tname" as a shortcut for "document.tname"

               alist=get_elements('myResults.input','CHANGEME')
                     Same as above, but then selects only those elements that have a CHANGEME class

               alist=get_elements('myResults.input','CHANGEME','price cost')
                     Same as above, but also selects only those elements that have a name of price or cost.



get_elements_remove

   nlist=get_elements_remove(tname,classname,namelist ) 
        Same as get_elements, but if elements selected by tname  have NONE of the classes in classname and NONE of the names in namelist.
       Note that if classname and namelist are not specified, get_elements and get_elements_remove are identical

delete_elements

  ndid = delete_elements(tname,classname,namelist) 
        Delete a list of elements.
        This calls get_elements, using the 3 arguments.
        Then, it deletes all the nodes returned by get_elements (and the nodes' children).


svy_getVal

   avalue=svy_getVal(arg1,defval0,cnode,argType,pRound) {

     A general "return value of something" function.
     
     where:
         avalue=svy_getVal(arg1,defval0,cnode,argType,pRound) {
         arg1 -- thing to get value of
        defval -- default value to return (if arg1 does not exist). Optional: '' is used if not specified
        cElem  --  a DOM node of an XHTML element.  Optional. If not specified, attribute and # lookup will not work
       argType --  sets the default "type" of "arg1" . Optional: '%' (survey global) is used if not specified
       pround -- optional. The "prior round" to lookup a variable from. Only used if argtype=".'

 Details

   Arg1:
        Type of arg1                            What is returned
       a number (eg; 105.3)                  The value of the number is returned without any modification
       quoted string (eg; 'hello world')     The ' (or ") are stripped, and the string is returned without further modification
       DOM element object (or an array)      The value of the DOM object (or the 0th element of an array of dom objects)
                                          Depending on the DOM tag: value is the value attribute (INPUT and OPTION)
                                          or the innerHTML (DIV and SPAN)
       survey global variable name          The value of the "arg1" survey global variable.
                                             If % is the first character, arg1 is treated as a survey global variable (after stripping the %).
                                         You can specify elements of a survey  global array by using arg1[n].
                                            Special case: you can # as an array index, # will be replaced by the IDX of cElem.
                                            Special case: an array index can be a survey global variable, or element, or ...  -- its recursive!

       element name                         The "value" of the XHTML element with a name of "arg1".
                                            If @ is the first character, arg1 is treated as an element name (after stripping the @).
                                         Note that the "name" attribute is used, not the "id" attribute.
                                         Thus, if more than one element has this name, the value of the first element is returned.
                                         You can narrow this down by using the # character as a suffix.
                                                Example:  @cost#
                                         # means "look for an element with a name of arg1, and an IDX atttribute that matches the
                                         IDX attribute of cElem".

       attribute name                     The value of the arg1 attribute of the cElem node.
                                            If # is the first character, arg1 is treated as an attribute name (after stripping the #).
                                            If arg1 ='#', then the "IDX" attribute is used.

      survey-prior variable               The value of a survey-prior variable. arg1 must have a syntax of:
                                              varname.round or arr[n].round ; where n can be a number, variable name, or another array

  DefVal:
        Value to return is arg1 can not be found.  For example, if no such survey global variable exists.
        Note that in some cases, an error results (defval is not used). In particular, an error message is shown when:.
                an attribute name is asked for, or a # is used in a element name lookup, but cnode is not a DOM (an XHTML) element.

  cElem:
      A DOM (xhtml) element.
      cElem is used when an attribute is being looked up, a # appears in an element name, or a # is used in a
      survey global array index. In these cases, if cElem is not a DOM object, an error occurs.

  argType:
     The "type of arg1".  By default, arg1 is assumed to be a survey global variable. You can override this default
      by setting argType.
      Argtype can have the following values:
         "" (the default) : survey global variable
         "%"  or 'GLOBAL' or 'G':  survey global variable (same as default)
        "@"   or 'ELEMENT'  or 'E' : element name
        "#"   or 'ATTRIBUTE' or 'A' : attribute name
        "."   or 'PRIOR' or 'P' : survey prior variable
     argTytpe is NOT used if one arg1 explicitily specifies the type. That is: if arg1 starts with a %, #, @, or contains a ".", then
     argType is IGNORED.

  pround :
    Used if argType="." -- the "round" of the prior variable to look up. Otherwise, ignored



Add_Attribute

   Add_Attribute(elemList,d_attribute,d_val,append,replaceChar)

        Add an attibute, and its value, to elements that have a match elemList

            elemlist: an array, or nodelist, of elements to modify. Could be created by get_elements .
           d_attribute: the attribute to add (or overwrite, or replace)
            d_val   : value for this attribute
            append: optional. If equal to 1 (or "APPEND"), append d_val to current value of  d_attribute. 
                              If equal to 2 (or "APPEND_EXISTS"), append d_val to current value IF non-empty value exists. If empty, do nothing.
                              Otherwise, replace with d_val (or add a new attribute if one doesn't exist)
            replaceChar = optional, only used if append=1 or 2. If exists and not '', then before appending, check for the replaceChar
                          variable. If it is found, replace it with d_val (rather then adding d_val to the end of d_attribute's value)


            alist=get_elements('INPUT','SHOWME')  ;
            Add_attribute(alist,'name',1) ;
 
                Given the list all INPUT elements that have  SHOWME as one of their classnames...    
                A "1" will be added to the name of these elements (assuming a name exists).


            Thus: 
                 <INPUT Type="text" name="cost" class="SHOWME">
            will be transformed into
                 <INPUT Type="text" name="cost1" class="SHOWME">

           alist=get_elements('SPAN,'SHOW1','fee price') 
           Add_attribute(alist,'name',1) ;

                Will find all SPAN elements that have  SHOW1 as one of their classnames, AND that have name of 
                fee or pricerange.  A '2' is appended to the name.

            In the above,
                 <INPUT Type="text" name="cost" class="SHOW1">
                 <INPUT Type="text" name="fee" class="SHOW1">

            will be transformed into
                 <INPUT Type="text" name="cost" class="SHOW1">
                 <INPUT Type="text" name="fee2" class="SHOW1">

update_styles

  update_styles(elemlist,styleString)
           elemlist: an array, or nodelist, of elements to  modify. Could be created by get_elements .
           styleString: the string containing the style to add
       
           Note: If the element already has a style defined, the styleString will be appended to the currently specified style.

       Examples:

            alist=get_elements s('SPAN','INFOLINKS')
            alist=update_styles(alist,'color:blue; text-decoration: underline')

                will find all SPAN elements that have  INFOLINKS as one of their classnames.    
                A style of 'color:blue; text-decoration: underline'  is added to the span.
                
           Also, you could concatenate elements with different tags into a single array. For example:
              alist0=get_elements('div') ; 
              alist2=get_elements('span') ;
              alist12=Concat_Arrays(alist,alist2) ;
              alistuse=get_elements(alist12,'INPUT','BLUEME')
              update_styles(alist12,'color:blue; text-decoration: underline')
         All INPUT elements that are in a DIV or SPAN that has BLUEME class will have the "text-decoration" style added.

update_class
          
  update_class(chkElements,daclass0)

      For all elements in chkElements (say, as generated by get_elements), add the daclass0 class (to the class attribute)

svy_addID
    svy_addID(aelem) 

    For the node identified by aelem, return its ID attribute. If no ID attribute, create a unique one, assign it to the element, and then return it.

   
 --- Event handlers ----             

Add_Event

  Add_Event(elemList,etype,afunction)
      Add event handlers to a set of elements.  
           elemlist: an array, or nodelist, of elements to  modify. Could be created by get_elements
          etype:  an event type (i.e.; "CLICK")
          afunction: name of the function to call. Must be an existing object: do NOT quote it or use ()
        
       Example:
              alist=get_elements('INPUT','KEYINC')
              Add_Event(alist,'click',Arrow_Increment)
       will find all INPUT elements that have  KEYINC as one of their classnames. An event handler for "CLICK" is added that
       points to Arrow_Increment.  This is equivalent to adding  onClick="Arrow_Increment()" directly to the element(s).

       WARNING: Add_Event does not seem to work when the array contains elements in the work-area.  Thus, Add_Event should be
                called AFTER Display_Modules (and not as part of construction of some modules for inclusion in the module_order).

Arrow_Increment
   
  Arrow_Increment(e) -- an event handler
        Allow use of arrow keys to change numeric values.
        This uses the "default" attribute as a default value.
        Right and down increment by 1. Up and left decrement by 1. PgUp decrements by 10, PgDn increments by 10.
        ESC will set the valu to the "default" attribute (or to "" if no default element is defined)
        ESC ESC sets the value to "".
        Increment and decementing are ONLY attempted if the value is a valid number.

        Typically, this is added to an input field using the Add_Event; hence in addition to  the 'default' attribute,
        the input element should also have an appropriate value included in the class attribute (such as "keyinc")

Check_Bounds  
  
  Check_Bounds(e)   -- an event handler
        Check the bounds of an input field for min and max (don't let it exceed either)
        This uses "min=nnn" and "max=nnn" attributes in the input element that is being checked.

        Typically, this is added to an input field using the Add_Event; hence in addition to min and max attributes,
        the input element should also  have an appropriate value included in the class attribute (such as "checkbound")
 
        Also checks for non-numeric; if found sets field to blank.

Check_Char

 Check_Char(e)

         Capture keyboard and return an identifying string if arrow or other such key is hit
         Returned values are: ALT CRLF PGUP ESC PGDN END BKSP HOME LEFT UP RIGHT DOWN 

Confirm_Input 

  Confirm_Input(e)  --  Check an input element's values for questionables 

       Checks the value of an input field for "questionable" values.  If such a "questionable value" is found, the user is asked
       to confirm it.  If he does NOT confirm, the value is reset to ''.

       Several attributes are used -- you can use any subset of them. If none of the attributes are specified, Confirm_Input does nothing.
         minConfirm: a numeric value. If the entered value is not a number, an error alert is shown, and value is set to ''.
                     Otherwise, if the entered value is <minConfirm, a confirmation box is shown.
         maxConfirm: a numeric value. If the entered value is not a number, an error alert is shown, and value is set to ''.
                     Otherwise, if the entered value is greater than maxConfirm, a confirmation box is shown.
         allowedConfirm: a space delimited set of words. If the entered valued is more than one word, an error alert is shown and value is
                         set to ''. Otherwise, if the entered word is NOT in the allowedConfirm list (case INsensitive), a confirmation box
                        is shown.

           ifEmpty:  if value is '', check for a ifEmpty element. If it exists, set field to the value of ifEmpty
                     (using svy_getVal to evaluate the iFempty attribute's value).

                nameConfirm  : a string used in confirm messages (to identify the variable). if nameConfirm is not specified, the name attribute
                               is displayed. If no name or nameConfirm attributes are specified, a generic message is used.

disable_autocompletes

   disable_autocompletes(daflag) 
             Turn off autocompletes AND contextmenu in all input boxes with a daflag class
             If daflag="" or 0, a value of "noauto" is checked for.


 ----- File retrieval procedures ---

Get_xmlFile

    Get_xmlFile(filename,varname,acomment,afunc,arg1,arg2,arg3,arg4,arg5) {

   Read a file, save the "xml documentElement" to a javascript global varname. An internal cache is supported.

   Where:
      filename:
           URL of resource (such as /subdir/filename) to GET from server.

              eg: 'ers6_a.xml'  or '/dsurvey/dsurvey.cmd?todo=103&session=my1'

           Note: if filename does NOT start with a /, then prepend SvyXMLGetFileHdr (if it exists), otherwise prepend /

	   Note: (DEPRECATED) if filename starts with a '=', then strip this '=', and then try to use 
                 the xmlFileCache (see below).
	         Or, if filename starts with a '==', then strip this '==', and then try to use the 
                 xmlFileCache (see below).
            
           filename can be a two element array
                filename[0]= the filename
                filename[1] = cache buster rule
                                 0 = do NOT bust cache (allowed cached file to be returned by server)
                                 1=  bust cache (add a random string to the request-string sent to the server)
                                 2=  bust cache, by setting headers
                        2 is not quite as strong (the rules don't always seem to work)
    
		 
     varname: a variable name (as a string). A javascript global variable, with this name,  will recieve the results from the server.
             These results will be an xml "node", containing the DOM tree of the XML file.

        varnames can be an array. 
            First element (varname):where to store dom version of xml file,
            Second element (varnameReturn): store returnCode (if '', do NOT store returnCode
                           This can be used for checking errors.
            Third element (retainComments): a flag to "retain comments" (if equal to "1")

        If just one variable (not an array), then on error an alert occurs and nothing is set, 
        and comments are NOT retained


     acomment:  in various status, etc output
     afunc:     string. The name of a function to call on succesful retrieval of the fil.e
     arg1 .. arg5  : strings (or numbers). Arguments sent to afunc.
                   Note that afunc also has access to the "varname" javascript global.

    The xmlFileCache (mostly deprecatd):
	IF filename starts with an '=', then the xmlFileCache is used.
	If this resource (after stripping this leading '=') has been retrieved and saved in this cache, 
        this "cached" version will be returned.
        If is has not been retrieved, an XMLHTTP request will be used to get it. And the server's response, 
        will be stored in the cache.

	Notes:
	  * if =filename is used, cache storage uses the Case InSensitive filename.
	  * if =-filename is used, cache storage uses the Case Sensitive filename.
          * the cache uses the xmlFileCache javascript global variable. If this does not exist (if you have not
            created it before calling Get_xmlFile), caching will NOT be attempted.
	


Get_File

    Get_File(filename,varname,acomment,afunc,arg1,arg2,arg3,arg4,arg5) {

          Same syntax as Get_xmlFile.
          Differences:
                The "varname" javascript global will be a string, containing the contents of what the server returned. 
                In contrast, "varname" in Get_xmlFile is a dom node that contains the DOM tree representing the contents of the xml file.

         5 Dec 2010 addition: if filename can be a two element array
                filename[0]= the filename
                filename[1] = cache buster rule
                                 0 = do NOT bust cache (allowed cached file to be returned by server)
                                 1=  bust cache (add a random string to the request-string sent to the server)
                                 2=  bust cache, by setting headers
                        2 is not quite as strong (the rules don't always seem to work)

                
         Note: Get_File should probably be named Get_fromServer -- while it can be used for files, it can also be used to 
               run a server side script.

Post_toServer

    Post_toServer(url,acontent,varname,acomment,afunc,arg1,arg2,arg3,arg4,arg5) 

    Post acontent to server (using aURL), save response to varname, after saving call afunc(arg1,...,arg5).
    
    This is similar to Get_File, except a POST request is used instead of a GET request. And the "body" of the post
    is specified in the acontent variable.


Display_Content

  Display_Content(varname,target,daopts)

  Display contents of the variable named in varname in the target window, as an HTML file. 
  This can be used as the "afunc" function in a Get_File.
  When opening the target window, dapopts will be used as the window attributes.
  If daopts is not specified, defaults are used: "toolbar=0,menubar=0,directories=0,scrollbars=1,resizable=1" 

   ---  HTML Display and check procedures --

Check_RadiosDone

  Check_RadiosDone(formname,varlist,errmess)
        Checks that a list of radio buttons have been chosen from.
           forname : the name of the form containing radio buttons to check
           varlist: a space delimited list of names of radio buttons
           errmess : optional -- an error message to display in an alert box. If not specified, a default message is used.
        
        For each (set) of radio buttons refered to in the varlist list, a check is run to see if any of them have been checked.
        If not, the error message is displayed and FALSE is returned.
        
        If all the radio buttons (referred to in the varlist) have some value checked, TRUE is returned.

        Note: this requires that a <form> ... </form> envelop the <input type="radio" ..> buttons you want to test.


 
writeAlert

    writeAlert(amessage,secondsDuration)  

  Write a message to the alert box (a transient yellow box in the lower half of the screen).
  If secondsDuration is specified, then the message will disapper after secondsDuration seconds.
  Or, an alert() if that can't be done.

  Note: this tries to call the E2_writeAlert function (in svyLibeE2.js).


writeStatus

    writeStatus(m1)  

  Write a message to the page status div (at the bottom of the screen). 
  Or, an alert() if that can't be done.

  Note: this tries to call the E2_writeStatus function (in svyLibeE2.js).

Highlight_One

      Highlight_One(me1,aname,astyle) 

   Change the style of of one of a set of named elements, setting all others in this set to an original style.
   me1 is element to set (typically 'this'), aname argument is the name to look for, astyle is the new style (fully specified CSS style; such as "x:ab; y:zz")
   if me1 is not an object, it is assumed to be an ID (and an element with this ID is used)

    This looks for all elements with a name attribute of "aname".  

displayDiv

   displayDiv(adiv,todo) 

   Toggle display of the adiv element (usually a span or a div) -- where adiv is a string containing the id of the element to be toggled.
   Todo is optional. If specified, insteadof toggling, the display style attribute will be set to todo.
   Recommended values of todo are "none" and "block"    

htmlSurround
   astring=htmlSurrond(tagname,string);

   returns <tagname>string</tagname>  (i.e.; <em>hello!</em>

   This is mostly used in <set> (since <set> can NOT have html tags embedded).


 ---- other procedures ---

make_procString

    make_procString(pname,arg1,arg2,arg3,arg4,arg5)

   Make a function string, with quoted arguments, suitable for use as an onClick, etc argument.
   Example:
        jones='This is big ';
        afunc=make_procString('comp1',25,jones,'simple');
    would yield:
          comp1(25,'This is big','simple')
    Note that arg1 ... arg5 will be sent as strings. So arg1...arg5 can NOT be objects.

Launch_Proc

      Launch_Proc(pname,pwait,arg1,arg2,arg3,arg4,arg5)   

   Launch a procedure using setTimeout. As in make_procString, pname is the function name and arg1 ... arg5 are arguments to the function.
   pwait is a millisecond pause, before launching the procedure. If not specified, 500 (1/2 second) is used.

evaluate_function

  evaluate_function(fstring,amess,aelem)

    Fstring should be a string that specifies a function call. For example 'myFunc(3,"hello")'
    Returns amess if an error (i.e.; if myFunc doesn't exist)
    If one of the argument in fstring is "@this", then aelem is replaced.  This is useful if evaluate_function is 
    the outcome of an event, in which case you could use "this" as an argument (to grant access to the elements attributes).

 Evaluate a function == replace "@this" arguments with aelem (if aelem <>'') 
 Otherwise, returns results of evaluating function.

resolveRelativeURL

   resolveRelativeURL(url,baseUrl)   

  Rsolve a relative URL, using the directory of the baseurl
  If url starts with a /, just return url
  Else, prepend the "directory" portion of baseurl to url, and return
        In /foo/bar/help.htm, the "directory" portion would be "/foo/bar/"


isIE
  isIE() 

   Returns true if this browser seems to be Internet Explorer.


debugOn

   debugOn(level)

   Returns true if the debug level (typically set in the base page for a session) is greater than or equal to level.



 =================

Appendix 1: functions used in setValue and <SET>.

   svy_trueFalse, svy_assignTo, svy_whichOne,svy_getWord,svy_random,svy_randomExample, svy_addth,
   svy_toFixed, svy_addStyle, svy_currentTime, svyPrior, svyMiss

   Notes:
            *  these functions use svy_getVal to lookup up values (when required). See above for a long description of svy_getVal.
            *  when used in a "set", etc. attribute, the arguments should NOT be quoted (they are treated as strings, not variable names).
            *  to use the value of a survey global variable, preface argument "names"  with a "%", 
            *  to use the value of some other element on the page, preface argument "names" with a "@"
            *  In general, but not always, not including a preface means that the values of elements are used.

Note that several deprecated, or near deprecated, functions are listed at the bottome of this section. 
It easier to use the syntax of dSurvey equations.
  
        ---------


  svy_trueFalse(arg1,default)   -- converts a 0/1 value to "false" or "true" text string. If arg1 is not 0 or 1, returns the 'default'.
           Example:  setVar="svy_trueFalse(%quest[1],No answer)" 
      
   svy_addth(arg1)
           If arg1 is an integer, returns st,nd,rd, or th.
            Arg1 is, like all the svy_ function, interpreted by svy_getVal.

   svy_toFixed(arg1,ndec)            
         avalue.toFixed(ndec) ; where avalue is the numeric value of arg1.

                      
  svy_whichOne(nvar,a0,a1..,a7) 
            Looks up the numeric value of the nvar argument, and returns the value of the appropriate a0,..,a7 arguments.
            Thus,
                 if nvar=0, then a0 (the 2nd argument) is returned.
                 if nvar=1, then a1 (the 3rd argument) is returned.
                       ...
                 if nvar=7, then a7 (the 9th argument) is returned.

             If nvar>7, or <0,  or nvar is evaulated to something other than an integer:  a '' is returned.
             As with the other svy_ ... functions, the values of nvar AND the a0... variables, are determined by
             calling svy_getVal.

            Example:
                If useMax can take values of 1,2, or 3...    
                    tmp3=svy_whichOne(useMax,max_offer,max_offer_group,max_offer_all2) 


  svy_random(arg1,arg2,arg3) 

            Compute a uniform random numberbetween arg1 and arg2 (arg1 as the minumum and arg2 as the maximum).

            Arg3 is optional. If specified, it is number used as the "resolution" -- the random number will be rounded to this value.
            For example stats_random(10,5,1) will produce an integer between 5 and 15.

            If arg1 (or arg2) are NOT numbers, svy_getVal is used to get their values. If, even after use of svy_getVal, v1 or v2
            is not a number, a '' is returned.

  svy_randomExample(arg1,arg2,arg3,arg4,arg5,arg6) 
            Return  a string displaying possible draws from a uniform random distribution, using "v1,v2,...,vj,vk"
               arg1: Low end. REQUIRED. This is always the first number displayed
                arg2 : High end. REQUIRED. This is always the last number displayed
                arg3: Number of v1,v2  (if 3, v1,v3,v3 displayed, and vj,vk,vm). Optional: default is 1 (just the fist and last values)
                arg4: resolution.   Optional. Default is 1 (move by ones)
                arg5:  # decimal points to display.  Optional, default is 0 (integer display)
                arg6: string to prepend to value.   Optional. Default is '' (no prepend)
          Example: svy_randomExample(100,200,2,0.1,2,$) would yield:
                   $100.10,$100.20,$100.30,...,$199.80,$199.90,$200.00

  svy_getWord(astring,nth,adelim) 
                Extract nth word from astring. Similar to getWord, it evaluates functions first (i.e.; replaces dSurvey variables with their values).

  svy_addStyle(astring,aelem,ireplace)
            
                astring should contain valid CSS-style attributes (i.e.; font-weight:500). It will be added to any existing
                style attribute, or be used as the style attribute if one has not been defined. 
                Note that astring is used as is,   svy_getVal is NOT used on astring.

                aelem should either be an element object, or an ID that will be looked up using document.getElementById. It specifies
                the element to add the style (in astring) to.

                ireplace optional. If equal to 1, astring will replace the current style. Otherwise, astring is added to the elements current style


  svy_currentTime(timeType,dateType) {

    Return time and/or date.

   If no arguments: return  hh:mm:ss xM 

     timeType:  
          0= javascript milliseconds
          1 =  mm:hh:ss xM

     dateType:
          1=  date Month Year
         2 = day-of-week, date Month Year

      if timeType and dateType ==2 : return as: xday Month date year hh:mm:ss GMT-xxxx (tz) 

      if both time and date specified, format is date-string, time-string 

svyPrior(avar,around,defval)
  Return value of a the avar prior variable from round around. If around not specified, or '', read from the $recent round.
  If no such variable, return defval.  
  This is basically a shortcut to read_prirorGlobal.
  If used within a setValue, avar should be a 'quoted' variable name.
  Around can be 

svyMiss(avar,defval)
  Return value of avar. If no such avar, return defval.
  avar AND defval can be variables, including prior variables.
  If defval not specified, 0 is used.
  This is basically a short cut to svy_getVal.

  Caution: when called as function from a <SET> (or someother such dynamic extension) avar and defval should be 'quoted' --
  otherwise the "value of avar and defval" will be sent to svyMiss.

   ---------  Deprecated functions ----

  svy_logical(falseVal,trueVal,Type,arg1,arg2,arg3,arg4,arg5)
        Deprecated.

              Evaluate logical expressions arg1 to arg5, using Type to control how the conditions are combined.
               Return trueVal if expressions combine to be True, falseVal otherwise.
             Typically, one uses falseVal=0 and trueVal=1.
                   Type can be OR, AND, XOR.

                   For details on the syntax of  arg1...arg5: see the description of doIf
                   For details on how to use OR, AND, and XOR: see the description of doIF_list.

                  Note:
                          Actually, svy_logical is basically a short cut to the doIf_list function.  Hence, Type may consist of more than just
                          an OR, AND or XOR -- you can specify a space delimited list of conditions that have OR, XOR, or AND as the first word.

   svy_add(arg1,..,arg8)   -- adds one to eight values. You can prepend a "-" to subtract the value
         This is  deprecated: use svyMiss with +.
     
                Example:  setVar="svy_add(%offer[#],-%cost[#],-%fee[#])" 

                Caution: if any of the arguments are non-numeric (say, a ''), svy_add returns a "NaN" (not a number) result.
                However: if argn has the formax 'xxx:avalue', then if xxx evaluates to not-a-number, then avalue (which should
                         be a number) will be used.  
                           Example:    vv=svy_add(%v1:0,%v2:0) 
                                       (this means that if v1 or v2 have not been defined, use 0 for its value when doing the addition).

   svy_prod(arg1,..,arg8)   -- Similar to svy_add -- but multiplies one to eight values. You can prepend a "-" to multiply the negative value
         This is  deprecated: use svyMiss with *.

            See the caution and the "however" in svy_add!

    svy_concat(arg1,..,arg8)  -- concatenate up to 8 values.
         This is deprecated: use $+

               All  arguments are converted to strings.
  

   svy_assignTo(davar,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10) -- check logical conditions and return associated value
       Somewhat deprecated, use svy_whichOne of if/then/else.

             svy_assignTo has two syntaxes:

                A)  "switch" syntax -- consider the value of one variable, and return a string associated with this value
                B)  "case" syntax -- consider the value of several variables, and return a string associated with the first true condition.
               
             Syntax "A" :
                 davar: a value, or survey-global variable, etc. (svy_getVal returns the current value of davar)
                 arg1... : test conditions
                  
                The arg1,.. variables are should be structured as :
                   aval:newValue
                If the value of davar equals aval, the newValue is returned. aval and newValue  are equal.
                A match is case-insensitive, with leading & trailing  spaces stripped, string match is used.
            
                If no match, use the argN without a colon sign (typically the last argument specified).
                If no argN without an equal sign, return original value of davar.

                Example:     setVar="svy_assignTo(group#,1:TypeA,2:MyB,3:C,No Such Type) ;
                              So, if this is for ticket 1, and GROUP1=2, "MyB" will be used as the value.

             Syntax "B" :

                davar=0 or "" -- this signals "use syntax B" 
                arg1 ... : logical conditions with associate value

                The arg1,.. variables are should be structured as :
                   l_conditions:newValue
                The first argument (starting with arg1) whose logical condition, or conditions, evaluate to true, will have its value returned.
                    newValue: is evaluated with svy_getVal, so it can be a number, survey-global variable, etc.
                   l_condtions: one, or several, logical conditions (in a space delmited list).  l_conditions is evaluated with the doIf_list
                                function -- see the doIf_list (and doIf) functions for the details.

                 As with syntax A, an argument (typically the last) that does not have a ":", is used as the default (if none of the arguments
                 evaluate to true).

                 Example: setVar="svy_assignTo(0, %myage.GT.65 : %pension,  %myAge.lt. 21 : %allowance, OR   %myEDUC.eq.1  %myJail.ne.0: no income, %WAGE)";

                 Notes:
                      * if more than one condition is true (say, myage=70 and myEduc=1), the first true value (the value of the %pension survey global variable)
                         is returned.

         =========================================================================================

  ========      DEPRECATED FUNCTIONS: NO LONGER SUPPORTED  ===========

get_elementsC

  nlist=get_elementsC(cache_name,tname,classname,namelist,cbase ) 

        This is a front end to get_elements; it implements a cache to speed up processing.

        Arguments:
                cache_name : index to cache -- read from (if exists), or written to (if does not exist)
                tname    : see get_elements. One small change: if not specified, used 'div span inputs'
                classname  : see get_elements
                namelist   : see get_elements
                cbase      : alternative to tname. If a cache entry with this name exists, use it instead of tname

        The cache is used to return a list of elements, saving processing time.
        The cache works by checking for an entry with the name given in the cache_name argument.
        
        Thus, for caching to work, you must include the same cache_name in multiple calls to get_elementsC.

        Basically:
             If there is NO cache_name entry available,
                  i) uses the 2nd to 4th argument to call get_elements.
                 ii) saves the list of elements (from step i) to the cache (using cache_name as an "index")
                 iii) returns the list of elements
             If there IS a cache_name entry
                i ) returns the value from this cache

        
        Example:
                alist=get_elementsC('c1','inputs div','SETVALUE')
                .... 
                alist=get_elementsC('c1','inputs div','SETVALUE')
                        or
                alist=get_elementsC('c1')             

       CAUTION:
           The cache does NOT keep track of "changes to the current contents". 
           That is, if you rewrite the contents of the page (with new DIVs, etc); a cache-hit will 
           incorrectly return  results -- it will return a list pointing to elements in the now removed 
           prior contents.

           Thus, you should ALWAYS reset the cache immediately after loading new contents.
           
           To reset the cache, use:  get_elementsC('%RESET')

        SPECIAL CASE: Using a cached list (cbase) instead of tname

           In many cases, you may wish to subset a previously cached list of elements.
           To do this, specify a cbase argument.

           Example:
                alist=get_elementsC('ALL_INPUTS','inputs')
                ...
                blist=get_elementsC('AI_SET','inputs','SETVALUE','','ALL_INPUTS')

           Basically, this is a shortcut for:
                blist=get_elementsC('AI_SET',alist,'SETVALUE')


       Notes: 
          * if cache_name is 0 or '', get_elementsC is EXACTLY the same as get_elements (the cache is not written to or read from)
          * if cache_name is not available, and you only have 1 argument, an empty array is returned.

