home *** CD-ROM | disk | FTP | other *** search
/ H4CK3R 5 / hacker05 / 05_HACK_05.ISO / programacao / freewrap / TCLLIBsampleApp.exe / sample / tcllib / tcllib1.0 / javascript / javascript.tcl next >
Encoding:
Text File  |  2001-08-17  |  13.3 KB  |  454 lines

  1. # javascript.tcl --
  2. #
  3. #    This file contains procedures that create HTML and Java Script
  4. #    functions that implement objects such as:
  5. #
  6. #        paired multi-selection boxes
  7. #        guarded submit buttons
  8. #        parent and child checkboxes
  9. #
  10. # Copyright (c) 1998-2000 by Ajuba Solutions.
  11. #
  12. # See the file "license.terms" for information on usage and redistribution
  13. # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  14. #
  15. # RCS: @(#) $Id: javascript.tcl,v 1.2 2001/08/02 16:38:06 andreas_kupries Exp $
  16.  
  17. package require Tcl 8
  18. package require ncgi 1
  19. package provide javascript 1.0
  20.  
  21.  
  22. namespace eval javascript {
  23.  
  24.     # The SelectionObjList namespace variable is used to keep the list of
  25.     # selection boxes that were created as parts of paired multi-selection
  26.     # boxes.  When a submit button is made for pages that have paired
  27.     # multi-selection boxes, we set a hidden field to store the initial values
  28.     # in the box.
  29.  
  30.     variable SelectionObjList {}
  31. }
  32.  
  33. # javascript::BeginJS --
  34. #
  35. #    Create HTML code to begin a java script program.
  36. #
  37. # Arguments:
  38. #    none.
  39. #
  40. # Results:
  41. #    Returns HTML code.
  42.  
  43. proc javascript::BeginJS {} {
  44.     return "\n<SCRIPT LANGUAGE=\"JavaScript\">\n"
  45. }
  46.  
  47. # javascript::EndJS --
  48. #
  49. #    Create HTML code to end a java script program.
  50. #
  51. # Arguments:
  52. #    none.
  53. #
  54. # Results:
  55. #    Returns HTML code.
  56.  
  57. proc javascript::EndJS {} {
  58.     return "\n</SCRIPT>\n"
  59. }
  60.  
  61. # javascript::MakeMultiSel --
  62. #
  63. #    Construct HTML code to create a multi-selection box.
  64. #
  65. # Arguments:
  66. #    id        The suffix of all HTML objects in this megawidget.
  67. #    side        Either "left" or "right".
  68. #    eltValues    The values to populate the selection box with.
  69. #    eltNames    The values to populate the selection box with.
  70. #    emptyElts    The number of empty box entry to stuff in the
  71. #            Selection box as placeholders for elts to be added.
  72. #    length        The number of elts to show before adding a vertical
  73. #            scrollbar.
  74. #    minWidth    Number of spaces to determin the minimum box width.
  75. #
  76. # Results:
  77. #    Returns HTML to show the selection box.
  78.  
  79. proc javascript::MakeMultiSel {id side eltValues eltNames emptyElts \
  80.     length minWidth} {
  81.  
  82.     variable SelectionObjList
  83.  
  84.     # Add this selection box to the list.
  85.  
  86.     set name "$side$id"
  87.     lappend SelectionObjList $name
  88.  
  89.     # Create the selection box and populate it with elts.
  90.  
  91.     set html ""
  92.     append html "<select name=$name multiple size=$length>"
  93.     foreach elt $eltValues name $eltNames {
  94.     set encodedElt [ncgi::encode $elt]
  95.     append html "<option value=$encodedElt>$name"
  96.     }
  97.  
  98.     # Add empty values for the remaining elements.
  99.  
  100.     for {set i 0} {$i < $emptyElts} {incr i} {
  101.     append html "<option value=\"\"> "
  102.     }
  103.  
  104.     # Add an empty value with text that is as wide as the minWidth.
  105.  
  106.     set filler ""
  107.     for {set i 0} {$i < $minWidth} {incr i} {
  108.     append filler "  "
  109.     }
  110.     append html "<option value=\"\">$filler"
  111.  
  112.     append html "</select>"
  113.     return $html
  114. }
  115.  
  116. # javascript::MakeClickProc --
  117. #
  118. #    Create a "moveSelected$id" java script procedure to move selected items
  119. #    from one selection box to the other.
  120. #
  121. # Arguments:
  122. #    id    The suffix of all objects in this multiselection megawidget.
  123. #
  124. # Results:
  125. #    Returns java script code.
  126.  
  127. proc javascript::MakeClickProc {id} {
  128.  
  129.     set result "\nfunction moveSelected${id}(fromObj,toObj) \{\n"
  130.  
  131.     # If nothing is selected, do nothing.
  132.  
  133.     append result "\n    if (fromObj.selectedIndex > -1) \{"
  134.  
  135.     # Find the first empty element in the toObj.
  136.  
  137.     append result {
  138.         for (var k = 0; toObj.options[k].value != ""; k++) {}
  139. }
  140.  
  141.     # Move the selected elements from the fromObj to the end of the toObj.
  142.     # Shift the objects in the fromObj to fill any empty spots.
  143.     # Clear out any extra slots in the fromObj.
  144.     # Deselect any selected elements (deselect with both 'selected = false'
  145.     # and by setting selectedIndex to -1, because setting selectedIndex to
  146.     # -1 didn't seem to clear selection on all windows browsers.
  147.  
  148.     append result {
  149.         for (var i = fromObj.selectedIndex, j = fromObj.selectedIndex; fromObj.options[i].value != ""; i++) {
  150.             if (fromObj.options[i].selected) {
  151.                 toObj.options[k].text = fromObj.options[i].text
  152.                 toObj.options[k++].value = fromObj.options[i].value
  153.                 fromObj.options[i].selected = false
  154.             } else {
  155.                 fromObj.options[j].text = fromObj.options[i].text
  156.                 fromObj.options[j++].value = fromObj.options[i].value
  157.             }
  158.         }
  159.         for (; j < i; j++) {
  160.             fromObj.options[j].text = ""
  161.             fromObj.options[j].value = ""
  162.         }
  163.         fromObj.selectedIndex = -1
  164. }
  165.  
  166.     # Close the if statement and the function
  167.  
  168.     append result "    \}
  169. \}
  170. "
  171.     return $result
  172. }
  173.  
  174. # javascript::makeSelectorWidget --
  175. #
  176. #    Construct HTML code to create a dual-multi-selection megawidget.  This
  177. #    megawidget consists of two side-by-side multi-selection boxes
  178. #    separated by a left arrow and a right arrow button.  The right arrow
  179. #    button moves all items selected in the left box to the right box.  The
  180. #    left arrow button moves all items selected in the right box to the left
  181. #    box.
  182. #
  183. # Arguments:
  184. #    id        The suffix of all HTML objects in this megawidget.
  185. #    leftLabel    The text that appears above the left selection box.
  186. #    leftValueList    The values of items in the left selection box.
  187. #    leftNameList    The names to appear in the left selection box.
  188. #    rightLabel    The text that appears above the right selection box.
  189. #    rightValueList    The values of items in the right selection box.
  190. #    rightNameList    The names to appear in the right selection box.
  191. #    length        (optional) The number of elts to show before adding a
  192. #            vertical scrollbar.  Defaults to 8.
  193. #    minWidth    (optional) The number of spaces to determin the
  194. #            minimum box width.  Defaults to 32.
  195. #
  196. # Results:
  197. #    Returns HTML to show the dual-multi-selection megawidget.
  198.  
  199. proc javascript::makeSelectorWidget {id leftLabel leftValueList leftNameList \
  200.     rightLabel rightValueList rightNameList {length 8} {minWidth 32}} {
  201.  
  202.     set html ""
  203.     append html [BeginJS] \
  204.         [MakeClickProc $id] \
  205.         [EndJS]
  206.  
  207.     append html "<table border=0 cellspacing=0 cellpadding=2>\n<tr><th>" \
  208.         $leftLabel "</th><th></th><th>" $rightLabel "</th></tr>\n<tr>"
  209.  
  210.     set leftLen [llength $leftValueList]
  211.     set rightLen [llength $rightValueList]
  212.     set len [expr {$leftLen + $rightLen}]
  213.  
  214.     append html "<td valign=top colspan=1>" \
  215.         [MakeMultiSel $id "left" $leftValueList $leftNameList \
  216.         $rightLen $length $minWidth] \
  217.         "  </td>\n"
  218.  
  219.     append html "<td>" \
  220.         "<table border=0 cellspacing=0 cellpadding=2>\n"
  221.  
  222.     set args "this.form.left${id},this.form.right${id}"
  223.  
  224.     append html "<tr><td><input type=button name=left${id}Button
  225.     onClick=\"moveSelected${id}(${args})\" value=\" >> \"></td></tr>"
  226.  
  227.     set args "this.form.right${id},this.form.left${id}"
  228.  
  229.     append html "<tr><td><input type=button name=right${id}Button
  230.     onClick=\"moveSelected${id}(${args})\" value=\" << \"></td></tr>"
  231.  
  232.     append html "</table>\n" \
  233.         "</td>\n"
  234.  
  235.     append html "<td valign=top colspan=1>" \
  236.         [MakeMultiSel $id "right" $rightValueList $rightNameList \
  237.         $leftLen $length $minWidth] \
  238.         "  </td>\n"
  239.  
  240.     append html "</tr>\n" \
  241.         "</table>\n"
  242.  
  243.     # Add a hidden field to collect the data.
  244.  
  245.     append html "<input type=hidden name=valleft${id} " \
  246.         "value=\"$leftValueList\">\n" \
  247.         "<input type=hidden name=valright${id} " \
  248.         "value=\"$rightValueList\">\n"
  249.  
  250.     return $html
  251. }
  252.  
  253. # javascript::makeSubmitButton --
  254. #
  255. #    Create an HTML submit button that resets a hidden field for each
  256. #    registered multi-selection box.
  257. #
  258. # Arguments:
  259. #    name    the name of the HTML button object to create.
  260. #    value    the label of the HTML button object to create.
  261. #
  262. # Results:
  263. #    Returns HTML submit button code.
  264.  
  265. proc javascript::makeSubmitButton {name value} {
  266.     variable SelectionObjList
  267.     set html ""
  268.  
  269.     # Create the java script procedure that gathers the current values for each
  270.     # registered multi-selection box.
  271.  
  272.     append html [BeginJS]
  273.     append html "\nfunction getSelections(form) \{\n"
  274.  
  275.     # For each registered selection box, reset hidden field to
  276.     # store nonempty values.
  277.  
  278.     foreach obj $SelectionObjList {
  279.     set selObj "form.$obj"
  280.     set hiddenObj "form.val$obj"
  281.     append html "    var tmp$obj = \"\"\n"
  282.     append html "    for (var i$obj = 0; i$obj < $selObj.length; i$obj++) {\n"
  283.     append html "        if ($selObj.options\[i$obj\].value == \"\") {\n"
  284.     append html "            break\n"
  285.     append html "        }\n"
  286.     append html "        tmp$obj += \" \" + $selObj.options\[i$obj\].value\n"
  287.     append html "    }\n"
  288.     append html "    $hiddenObj.value = tmp$obj \n"
  289.     }
  290.     append html "\}\n"
  291.     append html [EndJS]
  292.  
  293.     # Empty the selection box for the next page.
  294.  
  295.     set SelectionObjList {}
  296.  
  297.     # Create the HTML submit button.
  298.  
  299.     append html "<input type=submit name=\"$name\" value=\"$value\" 
  300.     onClick=\"getSelections(this.form)\">"
  301.  
  302.     return $html
  303. }
  304.  
  305. # javascript::makeProtectedSubmitButton --
  306. #
  307. #    Create an HTML submit button that prompts the user with a
  308. #    continue/cancel shutdown warning before the form is submitted.
  309. #
  310. # Arguments:
  311. #    name    the name of the HTML button object to create.
  312. #    value    the label of the HTML button object to create.
  313. #    msg    The message to display when the button is pressed.
  314. #
  315. # Results:
  316. #    Returns HTML submit button code.
  317.  
  318. proc javascript::makeProtectedSubmitButton {name value msg} {
  319.     set html ""
  320.  
  321.     # Create the java script procedure that gives the user the option to cancel
  322.     # the server shutdown request.
  323.  
  324.     append html [BeginJS]
  325.     append html "\nfunction areYouSure${name}(form) \{\n"
  326.     append html "    if (confirm(\"$msg\")) \{\n"
  327.     append html "        return true\n"
  328.     append html "    \} else \{\n"
  329.     append html "        return false\n"
  330.     append html "    \}\n"
  331.     append html "\}\n"
  332.     append html [EndJS]
  333.  
  334.     # Create the HTML submit button.
  335.  
  336.     append html "<input type=submit name=\"$name\" value=\"$value\" 
  337.     onClick=\"return areYouSure${name}(this.form)\">"
  338.  
  339.     return $html
  340. }
  341.  
  342. # javascript::makeMasterButton --
  343. #
  344. #    Create an HTML button that sets it's slave checkboxs to the boolean
  345. #    value.
  346. #
  347. # Arguments:
  348. #    master    the name of the child's parent html checkbox object.
  349. #    value    the value of the master.
  350. #    slaves    the name of child html checkbox object to create.
  351. #    boolean    the java script boolean value that will be given to all the
  352. #        slaves.  Must be true or false.
  353. #
  354. # Results:
  355. #    Returns HTML code to create the child checkbox.
  356.  
  357. proc javascript::makeMasterButton {master value slavePattern boolean} {
  358.     set html ""
  359.  
  360.     # Create the java script "checkMaster$name" proc that gets called when the
  361.     # master checkbox is selected or de-selected.
  362.  
  363.     append html [BeginJS]
  364.     append html "\nfunction checkMaster${master}(form) \{\n"
  365.     append html "    for (var i = 0; i < form.elements.length; i++) \{\n"
  366.     append html "        if (form.elements\[i\].name.match('$slavePattern')) \{\n"
  367.     append html "            form.elements\[i\].checked = $boolean \n"
  368.     append html "        \}\n"
  369.     append html "    \}\n"
  370.  
  371.     append html "\}\n"
  372.     append html [EndJS]
  373.     
  374.     # Create the HTML button object.
  375.  
  376.     append html "<input type=button name=\"$master\" value=\"$value\" " \
  377.         "onClick=\"checkMaster${master}(this.form)\">\n"
  378.  
  379.     return $html
  380. }
  381.  
  382. # javascript::makeParentCheckbox --
  383. #
  384. #    Create an HTML checkbox and tie its value to that of it's child
  385. #    checkbox.  If the parent is unchecked, the child is automatically
  386. #    unchecked.
  387. #
  388. # Arguments:
  389. #    parentName    the name of parent html checkbox object to create.
  390. #    childName    the name of the parent's child html checkbox object
  391. # Results:
  392. #    Returns HTML code to create the child checkbox.
  393.  
  394. proc javascript::makeParentCheckbox {parentName childName} {
  395.     set parentObj "form.$parentName"
  396.     set childObj "form.$childName"
  397.     set html ""
  398.  
  399.     # Create the java script "checkParent$name" proc that gets called when the
  400.     # parent checkbox is selected or de-selected.
  401.  
  402.     append html [BeginJS]
  403.     append html "\nfunction checkParent${parentName}(form) \{\n"
  404.     append html "    if (!$parentObj.checked && $childObj.checked) \{\n"
  405.     append html "        $childObj.checked = false\n"
  406.     append html "    \}\n"
  407.     append html "\}\n"
  408.     append html [EndJS]
  409.  
  410.     # Create the HTML checkbox object.
  411.  
  412.     append html "<input type=checkbox name=$parentName value=1 " \
  413.         "onClick=\"checkParent${parentName}(this.form)\">"
  414.  
  415.     return $html
  416. }
  417.  
  418. # javascript::makeChildCheckbox --
  419. #
  420. #    Create an HTML checkbox and tie its value to that of it's parent
  421. #    checkbox.  If the child is checked, the parent is automatically
  422. #    checked.
  423. #
  424. # Arguments:
  425. #    parentName    the name of the child's parent html checkbox object
  426. #    childName    the name of child html checkbox object to create.
  427. #
  428. # Results:
  429. #    Returns HTML code to create the child checkbox.
  430.  
  431. proc javascript::makeChildCheckbox {parentName childName} {
  432.     set parentObj "form.$parentName"
  433.     set childObj "form.$childName"
  434.     set html ""
  435.  
  436.     # Create the java script "checkChild$name" proc that gets called when the
  437.     # child checkbox is selected or de-selected.
  438.  
  439.     append html [BeginJS]
  440.     append html "\nfunction checkChild${childName}(form) \{\n"
  441.     append html "    if ($childObj.checked && !$parentObj.checked) \{\n"
  442.     append html "        $parentObj.checked = true\n"
  443.     append html "    \}\n"
  444.     append html "\}\n"
  445.     append html [EndJS]
  446.  
  447.     # Create the HTML checkbox object.
  448.  
  449.     append html "<input type=checkbox name=$childName value=1 " \
  450.         "onClick=\"checkChild${childName}(this.form)\">"
  451.  
  452.     return $html
  453. }
  454.