/* The ButtonBar code was written by Andrew Houghton; it can be used and * modified freely, but this header message must be included in any source * (in particular you may want to remove all comments other than this one). * Please email me at 'aah@cmu.edu' with comments or suggestions. If you * make use of this code I would appreciate hearing about it. */ /* ButtonBar version 0.9 * * A generic button array holder.. called ButtonBar since it was originally * meant to handle multiple buttons in a row. The button images can be GIFS * or JPEGS, they can animate, etc. By default, the button bar only allows * a single button to be pressed, though you can toggle that and allow * multiple buttons to be selected at a time. * * In your JavaScript code: * 1) create a new object of type ButtonBar * 2) call addButton() for each button you want to add to the ButtonBar * 3) call asTable() to get the buttonset written out as a table * * Notes: * 1) all buttons start in the "unselected", or "up" mode * 2) if there is only one button, and you choose a ButtonBar of type * "SINGLE" (the default), that button can be pressed, but only * once -- you'll never be able to toggle it. */ /* ImageButton * * internal object to ButtonBar; holds a button's specific information * * Notes: * 1) an ImageButton's 'status' property reflects whether that button is * in a selected state: * true == selected * false == unselected */ function ImageButton(selectedName, unselectedName, selected, unselected, sScript, uScript) { this.status = false; this.selectedName = selectedName; this.unselectedName = unselectedName; this.selected = selected; this.unselected = unselected; this.sScript = sScript; this.uScript = uScript; } /* ButtonBar.addButton() * * Call this function to add a button to the ButtonBar. * * REQUIRED Arguments: * unselected: string representing the URL of an image to use when button * is "up" * selected: string representing the URL of an image to use when button * is "down" * * OPTIONAL Arguments: * uScript: string to be eval'd when button moves to "up" state * sScript: string to be eval'd when button moves to "down" state * * Notes: * 1) unselected and selected *must* be passed, though they can both be * the same * 2) uScript and sScript can be ignored, since JavaScript will consider * them to be null, and when they're evaluated nothing will happen.. * this will make for a functional, though useless, button bar. */ function ButtonBar_addButton(unselected, selected, uScript, sScript) { if ((unselected == null) || (selected == null)) { alert("ButtonBar ("+this.name+"): attempt to pass null values to addButton() failed"); return; } var sImage = new Image(); var uImage = new Image(); sImage.src = selected; uImage.src = unselected; var element = this.numButtons; this.buttonArray[element] = new ImageButton(selected, unselected, sImage, uImage, sScript, uScript); this.numButtons++; } /* ButtonBar.select() * * Internal function. Handles toggling a button from unselected to selected state. */ function ButtonBar_selectButton(element) { var tableElement = this.prefix + element; eval("document."+tableElement).src = this.buttonArray[element].selected.src; eval (this.buttonArray[element].sScript); this.buttonArray[element].status = true; } /* ButtonBar.unselect() * * Internal function. Handles toggling a button from selected to unselected state. */ function ButtonBar_unselectButton(element) { var tableElement = this.prefix + element; eval("document."+tableElement).src = this.buttonArray[element].unselected.src; eval (this.buttonArray[element].uScript); this.buttonArray[element].status = false; } /* ButtonBar.onClick() * * Internal function. Handles an onClick() event on a button. */ function ButtonBar_onClick(element) { if (this.type == "MULTI") { if (this.buttonArray[element].status == true) { this.unselectButton(element); } else { this.selectButton(element); } } else { if (this.selected == element) { return; } if (this.selected != null) { this.unselectButton(this.selected); this.selected = null; } this.selectButton(element); this.selected = element; } } /* ButtonBar.asTable() * * Returns: * a string representing the ButtonBar as a table. The table correctly * handles onClick() events and changing the button state, etc. * * REQUIRED Arguments: * None * * OPTIONAL Arguments: * tableOptions: string representing any table-wide options; this string is * dropped verbatim into the start tag. This defaults * to "NOPADDING CELLSPACING=0 CELLPADDING=0 NOWRAP" * tableSetup: string allowing control over table rows and columns; * accepted formats are: * * 1) "[n1,n2,n3,...,nn]" where 'n1' etc. represent the number * of buttons to drop into any given row. * 2) "rows,columns" * * Examples: * 1) asTable("[2,6,3,1]") would return a table with the first 2 buttons in * the first row, then next 6 in the second row, the next 3 in the third * row, and the next 1 in the last row. * 2) asTable("6,3") would return a table with three buttons in each row, * with a maximum of 6 rows. * * Notes: * 1) a ButtonBar will default to a single row, NOWRAP table with all * buttons visible. * 2) if there are more cells than buttons, excess cells are left empty. * 3) if there are fewer cells than buttons, only the specified * number of cells will be filled; excess buttons will not appear. * */ function ButtonBar_asTable(tableOptions, tableSetup) { var c, r, i=0; var rArray = new Array(); if (typeof(tableSetup) != "string") { rArray[0] = this.numButtons; } else { if ((tableSetup.charAt(0) == "[") && (tableSetup.charAt(tableSetup.length - 1) == "]")) { var tempString = tableSetup.substring(1, tableSetup.length -1); rArray = tempString.split(","); } else { var tempArray = new Array(); tempArray = tableSetup.split(","); if ((tempArray.length > 2) || (parseInt(tempArray[0]) == 0) || (parseInt(tempArray[1]) == 0)) { rArray[0] = this.numButtons; } else { var j; for (j = 0; j < parseInt(tempArray[0]); j++) { rArray[j] = parseInt(tempArray[1]); } } } } var tableSet = "
= this.numButtons) { continue; } tableData += "" i++; } tableData += ""; tableSet += tableData; } tableSet += "
"; return tableSet; } /* ButtonBar() * * Returns: * a ButtonBar object * * REQUIRED Arguments: * name: the ButtonBar must know it's own name; if you create a ButtonBar * object named 'foo', pass "foo" as the first argument. * * OPTIONAL Arguments: * type: the type of ButtonBar. Defined types: * MULTI: allow multiple buttons to be depressed at the same time. * SINGLE: allow only a single button to be depressed at a time. * prefix: every button is named; the button number is added to the * prefix to form that name. * * Examples: * 1) var bBar = new ButtonBar("bBar") would return a new, default * ButtonBar object. * 2) var foo = new ButtonBar("foo", "MULTI") would return a new * ButtonBar object which would allow multiple buttons to be selected * at a time. * 3) var test = new ButtonBar("test", "SINGLE", "foo") would return a * new ButtonBar object which would only allow a single button to * be selected at a time, and where the buttons would be named 'foo0', * 'foo1', 'foo2', etc. * * Notes: * 1) ButtonBar objects default to 'SINGLE' mode; if a string is passed * as type which doesn't match 'MULTI', type defaults top 'SINGLE'. * 1) You should change the default prefix if you have more than one * ButtonBar on a page.. results are undefined when you have more * than one button named 'default0'.. * 2) ButtonBar.selected holds the index of the currently selected * button in 'SINGLE' mode; in 'MULTI' it doesn't reflect anything. */ function ButtonBar(name, type, prefix) { if (typeof(name) != "string") { alert("ButtonBar object *MUST* know it's own name") } else { this.name = name; } this.selected = null; this.buttonArray = new Array(); if (typeof(type) == "string") { this.type = type.toUpperCase(); } else { this.type = "SINGLE"; } if (typeof(prefix) == "string") { this.prefix = prefix; } else { this.prefix = "default"; } this.numButtons = 0; this.addButton = ButtonBar_addButton; this.onClick = ButtonBar_onClick; this.selectButton = ButtonBar_selectButton; this.unselectButton = ButtonBar_unselectButton; this.asTable = ButtonBar_asTable; }