home *** CD-ROM | disk | FTP | other *** search
/ The Net Power 1997 January / NETPower0197.iso / pc / html / issue / feat1 / buttonbr / bbar.txt
Encoding:
Text File  |  1996-09-29  |  9.2 KB  |  309 lines

  1. /* The ButtonBar code was written by Andrew Houghton; it can be used and
  2.  * modified freely, but this header message must be included in any source
  3.  * (in particular you may want to remove all comments other than this one).
  4.  * Please email me at 'aah@cmu.edu' with comments or suggestions.  If you
  5.  * make use of this code I would appreciate hearing about it.
  6.  */
  7.  
  8. /* ButtonBar version 0.9
  9.  *
  10.  * A generic button array holder.. called ButtonBar since it was originally
  11.  * meant to handle multiple buttons in a row.  The button images can be GIFS
  12.  * or JPEGS, they can animate, etc.  By default, the button bar only allows
  13.  * a single button to be pressed, though you can toggle that and allow
  14.  * multiple buttons to be selected at a time.
  15.  * 
  16.  * In your JavaScript code:
  17.  * 1) create a new object of type ButtonBar
  18.  * 2) call addButton() for each button you want to add to the ButtonBar
  19.  * 3) call asTable() to get the buttonset written out as a table
  20.  *
  21.  * Notes:
  22.  *  1) all buttons start in the "unselected", or "up" mode
  23.  *  2) if there is only one button, and you choose a ButtonBar of type 
  24.  *     "SINGLE" (the default), that button can be pressed, but only 
  25.  *      once -- you'll never be able to toggle it.
  26.  */
  27.  
  28. /* ImageButton
  29.  *
  30.  * internal object to ButtonBar; holds a button's specific information
  31.  *
  32.  * Notes:
  33.  *  1) an ImageButton's 'status' property reflects whether that button is
  34.  *     in a selected state:
  35.  *      true == selected
  36.  *      false == unselected
  37.  */
  38.  
  39. function ImageButton(selectedName, unselectedName, selected, unselected, sScript, uScript) {
  40.     this.status = false;
  41.  
  42.     this.selectedName = selectedName;
  43.     this.unselectedName = unselectedName;
  44.  
  45.     this.selected = selected;
  46.     this.unselected = unselected;
  47.  
  48.     this.sScript = sScript;    
  49.     this.uScript = uScript;
  50. }
  51.  
  52. /* ButtonBar.addButton()
  53.  *
  54.  * Call this function to add a button to the ButtonBar.
  55.  *                                                      
  56.  * REQUIRED Arguments:
  57.  *  unselected: string representing the URL of an image to use when button 
  58.  *              is "up"
  59.  *  selected:   string representing the URL of an image to use when button 
  60.  *              is "down"
  61.  *
  62.  * OPTIONAL Arguments: 
  63.  *  uScript:    string to be eval'd when button moves to "up" state
  64.  *  sScript:    string to be eval'd when button moves to "down" state
  65.  *
  66.  * Notes:
  67.  *  1) unselected and selected *must* be passed, though they can both be 
  68.  *     the same
  69.  *  2) uScript and sScript can be ignored, since JavaScript will consider
  70.  *     them to be null, and when they're evaluated nothing will happen..
  71.  *     this will make for a functional, though useless, button bar.
  72.  */
  73.  
  74. function ButtonBar_addButton(unselected, selected, uScript, sScript) {
  75.     if ((unselected == null) || (selected == null)) {
  76.         alert("ButtonBar ("+this.name+"): attempt to pass null values to addButton() failed");
  77.         return;
  78.     }
  79.     
  80.     var sImage = new Image();
  81.     var uImage = new Image();
  82.  
  83.     sImage.src = selected;
  84.     uImage.src = unselected;
  85.     
  86.     var element = this.numButtons;
  87.  
  88.     this.buttonArray[element] = new ImageButton(selected, unselected, sImage, uImage, sScript, uScript);
  89.     
  90.     this.numButtons++;
  91. }
  92.  
  93. /* ButtonBar.select()
  94.  *
  95.  * Internal function.  Handles toggling a button from unselected to selected state.
  96.  */
  97.  
  98. function ButtonBar_selectButton(element) {
  99.     var tableElement = this.prefix + element;
  100.  
  101.     eval("document."+tableElement).src = this.buttonArray[element].selected.src;
  102.  
  103.     eval (this.buttonArray[element].sScript);
  104.  
  105.     this.buttonArray[element].status = true;
  106. }
  107.  
  108. /* ButtonBar.unselect()
  109.  *
  110.  * Internal function.  Handles toggling a button from selected to unselected state.
  111.  */
  112.  
  113. function ButtonBar_unselectButton(element) {
  114.     var tableElement = this.prefix + element;
  115.  
  116.     eval("document."+tableElement).src = this.buttonArray[element].unselected.src;
  117.  
  118.     eval (this.buttonArray[element].uScript);
  119.  
  120.     this.buttonArray[element].status = false;
  121. }
  122.  
  123. /* ButtonBar.onClick()
  124.  *
  125.  * Internal function.  Handles an onClick() event on a button.
  126.  */
  127.  
  128. function ButtonBar_onClick(element) {
  129.     if (this.type == "MULTI") {
  130.         if (this.buttonArray[element].status == true) {
  131.             this.unselectButton(element);
  132.         } else {
  133.             this.selectButton(element);
  134.         }
  135.     } else {
  136.         if (this.selected == element) {
  137.             return;
  138.         }        
  139.  
  140.         if (this.selected != null) {
  141.             this.unselectButton(this.selected);
  142.             this.selected = null;
  143.         }
  144.     
  145.         this.selectButton(element);
  146.         this.selected = element;
  147.     }
  148. }
  149.  
  150. /* ButtonBar.asTable()
  151.  *
  152.  * Returns:
  153.  *  a string representing the ButtonBar as a table.  The table correctly 
  154.  *  handles onClick() events and changing the button state, etc. 
  155.  *
  156.  * REQUIRED Arguments:
  157.  *  None
  158.  *
  159.  * OPTIONAL Arguments:
  160.  *  tableOptions: string representing any table-wide options; this string is
  161.  *                dropped verbatim into the <TABLE> start tag.  This defaults
  162.  *                to "NOPADDING CELLSPACING=0 CELLPADDING=0 NOWRAP"
  163.  *  tableSetup:   string allowing control over table rows and columns;
  164.  *                accepted formats are:
  165.  *
  166.  *  1)            "[n1,n2,n3,...,nn]" where 'n1' etc. represent the number
  167.  *                of buttons to drop into any given row.
  168.  *  2)            "rows,columns"
  169.  *
  170.  * Examples:
  171.  *  1) asTable("[2,6,3,1]") would return a table with the first 2 buttons in
  172.  *     the first row, then next 6 in the second row, the next 3 in the third
  173.  *     row, and the next 1 in the last row.
  174.  *  2) asTable("6,3") would return a table with three buttons in each row,
  175.  *     with a maximum of 6 rows.
  176.  *
  177.  * Notes:
  178.  *  1) a ButtonBar will default to a single row, NOWRAP table with all
  179.  *     buttons visible.
  180.  *  2) if there are more cells than buttons, excess cells are left empty.
  181.  *  3) if there are fewer cells than buttons, only the specified
  182.  *     number of cells will be filled; excess buttons will not appear.
  183.  *     
  184.  */
  185.  
  186. function ButtonBar_asTable(tableOptions, tableSetup) {
  187.     var c, r, i=0;
  188.     var rArray = new Array();
  189.  
  190.     if (typeof(tableSetup) != "string") {
  191.         rArray[0] = this.numButtons;
  192.     } else {
  193.         if ((tableSetup.charAt(0) == "[") && (tableSetup.charAt(tableSetup.length - 1) == "]")) {
  194.             var tempString = tableSetup.substring(1, tableSetup.length -1);
  195.             rArray = tempString.split(",");
  196.         } else {
  197.             var tempArray = new Array();
  198.             tempArray = tableSetup.split(",");
  199.             if ((tempArray.length > 2) || (parseInt(tempArray[0]) == 0) || (parseInt(tempArray[1]) == 0)) {
  200.                 rArray[0] = this.numButtons;
  201.             } else {
  202.                 var j;
  203.                 for (j = 0; j < parseInt(tempArray[0]); j++) {
  204.                     rArray[j] = parseInt(tempArray[1]);
  205.                 }
  206.             }
  207.         }
  208.     }
  209.  
  210.     var tableSet = "<TABLE ";
  211.     if (typeof(tableOptions) == "string") {
  212.         tableSet += tableOptions;
  213.     } else {
  214.         tableSet += "NOPADDING CELLSPACING=0 CELLPADDING=0 NOWRAP";
  215.     }
  216.     tableSet +=">";
  217.     
  218.     for (r=0; r < rArray.length; r++) {
  219.         var tableData = "<TR>";
  220.         for (c=0; c < rArray[r]; c++) {
  221.             if (i >= this.numButtons) {
  222.                 continue;
  223.             }
  224.             tableData += "<TD><A HREF=\"javascript:"
  225.             tableData += this.name;
  226.             tableData += ".onClick("+i+")\"><IMG SRC='" + this.buttonArray[i].unselectedName + "'";
  227.             tableData += " NAME = '";
  228.             tableData += this.prefix;
  229.             tableData += i + "'></A></TD>"
  230.             i++;
  231.         }
  232.         tableData += "</TR>";
  233.         tableSet += tableData;
  234.     }
  235.  
  236.     tableSet += "</TABLE>";
  237.  
  238.     return tableSet;
  239. }
  240.  
  241. /* ButtonBar()
  242.  *
  243.  * Returns:
  244.  *  a ButtonBar object
  245.  *
  246.  * REQUIRED Arguments:
  247.  *  name: the ButtonBar must know it's own name; if you create a ButtonBar
  248.  *        object named 'foo', pass "foo" as the first argument.
  249.  *
  250.  * OPTIONAL Arguments:
  251.  *  type: the type of ButtonBar.  Defined types:
  252.  *        MULTI:  allow multiple buttons to be depressed at the same time.
  253.  *        SINGLE: allow only a single button to be depressed at a time.
  254.  *  prefix: every button is named; the button number is added to the
  255.  *          prefix to form that name.
  256.  *
  257.  * Examples:
  258.  *  1) var bBar = new ButtonBar("bBar") would return a new, default 
  259.  *     ButtonBar object.
  260.  *  2) var foo = new ButtonBar("foo", "MULTI") would return a new
  261.  *     ButtonBar object which would allow multiple buttons to be selected
  262.  *     at a time.
  263.  *  3) var test = new ButtonBar("test", "SINGLE", "foo") would return a
  264.  *     new ButtonBar object which would only allow a single button to
  265.  *     be selected at a time, and where the buttons would be named 'foo0',
  266.  *     'foo1', 'foo2', etc.
  267.  *
  268.  * Notes:
  269.  *  1) ButtonBar objects default to 'SINGLE' mode;  if a string is passed
  270.  *     as type which doesn't match 'MULTI', type defaults top 'SINGLE'.
  271.  *  1) You should change the default prefix if you have more than one
  272.  *     ButtonBar on a page.. results are undefined when you have more
  273.  *     than one button named 'default0'..
  274.  *  2) ButtonBar.selected holds the index of the currently selected
  275.  *     button in 'SINGLE' mode;  in 'MULTI' it doesn't reflect anything.
  276.  */
  277.  
  278. function ButtonBar(name, type, prefix) {
  279.     if (typeof(name) != "string") {
  280.         alert("ButtonBar object *MUST* know it's own name")
  281.     } else {
  282.         this.name = name;
  283.     }
  284.  
  285.     this.selected = null;
  286.     this.buttonArray = new Array();
  287.     
  288.     if (typeof(type) == "string") {
  289.         this.type = type.toUpperCase();
  290.     } else {
  291.         this.type = "SINGLE";
  292.     }
  293.  
  294.     if (typeof(prefix) == "string") {
  295.         this.prefix = prefix;
  296.     } else {
  297.         this.prefix = "default";
  298.     }
  299.  
  300.     this.numButtons = 0;
  301.  
  302.  
  303.     this.addButton = ButtonBar_addButton;
  304.     this.onClick = ButtonBar_onClick;
  305.     this.selectButton = ButtonBar_selectButton;
  306.     this.unselectButton = ButtonBar_unselectButton;
  307.     this.asTable = ButtonBar_asTable;
  308. }
  309.