HTML_QuickForm_advmultiselect
[ class tree: HTML_QuickForm_advmultiselect ] [ index: HTML_QuickForm_advmultiselect ] [ all elements ]

Source for file advmultiselect.php

Documentation is available at advmultiselect.php

  1. <?php
  2. /**
  3. * Element for HTML_QuickForm that emulate a multi-select.
  4. *
  5. * The HTML_QuickForm_advmultiselect package adds an element to the
  6. * HTML_QuickForm package that is two select boxes next to each other
  7. * emulating a multi-select.
  8. *
  9. * PHP versions 4 and 5
  10. *
  11. * LICENSE: This source file is subject to version 3.0 of the PHP license
  12. * that is available through the world-wide-web at the following URI:
  13. * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  14. * the PHP License and are unable to obtain it through the web, please
  15. * send a note to license@php.net so we can mail you a copy immediately.
  16. *
  17. @category   HTML
  18. @package    HTML_QuickForm_advmultiselect
  19. @author     Laurent Laville <pear@laurent-laville.org>
  20. @copyright  1997-2005 The PHP Group
  21. @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  22. @version    CVS: $Id: advmultiselect.php 7739 2006-02-12 17:21:34Z turboke $
  23. @link       http://pear.php.net/package/HTML_QuickForm_advmultiselect
  24. */
  25.  
  26. require_once 'HTML/QuickForm/select.php';
  27.  
  28. /**
  29. * Replace PHP_EOL constant
  30. *
  31. *  category    PHP
  32. *  package     PHP_Compat
  33. @link        http://php.net/reserved.constants.core
  34. @author      Aidan Lister <aidan@php.net>
  35. @since       PHP 5.0.2
  36. */
  37. if (!defined('PHP_EOL')) {
  38.     switch (strtoupper(substr(PHP_OS03))) {
  39.         // Windows
  40.         case 'WIN':
  41.             define('PHP_EOL'"\r\n");
  42.             break;
  43.  
  44.         // Mac
  45.         case 'DAR':
  46.             define('PHP_EOL'"\r");
  47.             break;
  48.  
  49.         // Unix
  50.         default:
  51.             define('PHP_EOL'"\n");
  52.     }
  53. }
  54.  
  55. /**
  56. * Element for HTML_QuickForm that emulate a multi-select.
  57. *
  58. * The HTML_QuickForm_advmultiselect package adds an element to the
  59. * HTML_QuickForm package that is two select boxes next to each other
  60. * emulating a multi-select.
  61. *
  62. * PHP versions 4 and 5
  63. *
  64. * LICENSE: This source file is subject to version 3.0 of the PHP license
  65. * that is available through the world-wide-web at the following URI:
  66. * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  67. * the PHP License and are unable to obtain it through the web, please
  68. * send a note to license@php.net so we can mail you a copy immediately.
  69. *
  70. @category   HTML
  71. @package    HTML_QuickForm_advmultiselect
  72. @author     Laurent Laville <pear@laurent-laville.org>
  73. @copyright  1997-2005 The PHP Group
  74. @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  75. @version    Release: 0.5.1
  76. @link       http://pear.php.net/package/HTML_QuickForm_advmultiselect
  77. */
  78. {
  79.     /**
  80.      * Prefix function name in javascript move selections
  81.      *
  82.      * @var        string 
  83.      * @access     private
  84.      * @since      0.4.0
  85.      */
  86.     var $_jsPrefix;
  87.  
  88.     /**
  89.      * Postfix function name in javascript move selections
  90.      *
  91.      * @var        string 
  92.      * @access     private
  93.      * @since      0.4.0
  94.      */
  95.     var $_jsPostfix;
  96.  
  97.     /**
  98.      * Associative array of the multi select container attributes
  99.      *
  100.      * @var        array 
  101.      * @access     private
  102.      * @since      0.4.0
  103.      */
  104.     var $_tableAttributes;
  105.  
  106.     /**
  107.      * Associative array of the add button attributes
  108.      *
  109.      * @var        array 
  110.      * @access     private
  111.      * @since      0.4.0
  112.      */
  113.     var $_addButtonAttributes;
  114.  
  115.     /**
  116.      * Associative array of the remove button attributes
  117.      *
  118.      * @var        array 
  119.      * @access     private
  120.      * @since      0.4.0
  121.      */
  122.  
  123.     /**
  124.      * Associative array of the move up button attributes
  125.      *
  126.      * @var        array 
  127.      * @access     private
  128.      * @since      0.5.0
  129.      */
  130.     var $_upButtonAttributes;
  131.  
  132.     /**
  133.      * Associative array of the move up button attributes
  134.      *
  135.      * @var        array 
  136.      * @access     private
  137.      * @since      0.5.0
  138.      */
  139.  
  140.     /**
  141.      * Defines if both list (unselected, selected) will have their elements be
  142.      * arranged from lowest to highest (or reverse) depending on comparaison function.
  143.      *
  144.      * SORT_ASC  is used to sort in ascending order
  145.      * SORT_DESC is used to sort in descending order
  146.      *
  147.      * @var        integer 
  148.      * @access     private
  149.      * @since      0.5.0
  150.      */
  151.     var $_sort;
  152.  
  153.     /**
  154.      * Associative array of the unselected item box attributes
  155.      *
  156.      * @var        array 
  157.      * @access     private
  158.      * @since      0.4.0
  159.      */
  160.  
  161.     /**
  162.      * Associative array of the selected item box attributes
  163.      *
  164.      * @var        array 
  165.      * @access     private
  166.      * @since      0.4.0
  167.      */
  168.     var $_attributesSelected;
  169.  
  170.     /**
  171.      * Associative array of the internal hidden box attributes
  172.      *
  173.      * @var        array 
  174.      * @access     private
  175.      * @since      0.4.0
  176.      */
  177.     var $_attributesHidden;
  178.  
  179.     /**
  180.      * Default Element template string
  181.      *
  182.      * @var        string 
  183.      * @access     private
  184.      * @since      0.4.0
  185.      */
  186.     var $_elementTemplate = '
  187. {javascript}
  188. <table{class}>
  189. <!-- BEGIN label_2 --><tr><th>{label_2}</th><!-- END label_2 -->
  190. <!-- BEGIN label_3 --><th>&nbsp;</th><th>{label_3}</th></tr><!-- END label_3 -->
  191. <tr>
  192.   <td valign="top">{unselected}</td>
  193.   <td align="center">{add}{remove}</td>
  194.   <td valign="top">{selected}</td>
  195. </tr>
  196. </table>
  197. ';
  198.  
  199.     /**
  200.      * Default Element stylesheet string
  201.      *
  202.      * @var        string 
  203.      * @access     private
  204.      * @since      0.4.0
  205.      */
  206.     var $_elementCSS = '
  207. #{id}amsSelected {
  208.   font: 13.3px sans-serif;
  209.   background-color: #fff;
  210.   overflow: auto;
  211.   height: 14.3em;
  212.   width: 12em;
  213.   border-left:   1px solid #404040;
  214.   border-top:    1px solid #404040;
  215.   border-bottom: 1px solid #d4d0c8;
  216.   border-right:  1px solid #d4d0c8;
  217. }
  218. #{id}amsSelected label {
  219.   padding-right: 3px;
  220.   display: block;
  221. }
  222. ';
  223.  
  224.     /**
  225.      * Class constructor
  226.      *
  227.      * @param      string    $elementName   Dual Select name attribute
  228.      * @param      mixed     $elementLabel  Label(s) for the select boxes
  229.      * @param      mixed     $options       Data to be used to populate options
  230.      * @param      mixed     $attributes    Either a typical HTML attribute string or an associative array
  231.      * @param      integer   $sortOptions   Either SORT_ASC for auto ascending arrange,
  232.      *                                              SORT_DESC for auto descending arrange, or
  233.      *                                              NULL for no sort (append at end: default)
  234.      *
  235.      * @access     public
  236.      * @return     void 
  237.      * @since      0.4.0
  238.      */
  239.     function HTML_QuickForm_advmultiselect($elementName null$elementLabel null,
  240.                                            $options null$attributes null,
  241.                                            $sortOptions null)
  242.     {
  243.         $this->HTML_QuickForm_select($elementName$elementLabel$options$attributes);
  244.  
  245.         // add multiple selection attribute by default if missing
  246.         $this->updateAttributes(array('multiple' => 'multiple'));
  247.  
  248.         if (is_null($this->getAttribute('size'))) {
  249.             // default size is ten item on each select box (left and right)
  250.             $this->updateAttributes(array('size' => 10));
  251.         }
  252.         if (is_null($this->getAttribute('style'))) {
  253.             // default width of each select box
  254.             $this->updateAttributes(array('style' => 'width:100px;'));
  255.         }
  256.         $this->_tableAttributes = $this->getAttribute('class');
  257.         if (is_null($this->_tableAttributes)) {
  258.             // default table layout
  259.             $attr array('border' => '0''cellpadding' => '10''cellspacing' => '0');
  260.         else {
  261.             $attr array('class' => $this->_tableAttributes);
  262.             $this->_removeAttr('class'$this->_attributes);
  263.         }
  264.         $this->_tableAttributes = $this->_getAttrString($attr);
  265.  
  266.         // set default add button attributes
  267.         $this->setButtonAttributes('add');
  268.         // set default remove button attributes
  269.         $this->setButtonAttributes('remove');
  270.         // set default move up button attributes
  271.         $this->setButtonAttributes('moveup');
  272.         // set default move up button attributes
  273.         $this->setButtonAttributes('movedown');
  274.         // defines javascript functions names
  275.         $this->setJsElement();
  276.  
  277.         // set select boxes sort order (none by default)
  278.         if (isset($sortOptions)) {
  279.             $this->_sort = $sortOptions;
  280.         else {
  281.             $this->_sort = false;
  282.         }
  283.     }
  284.  
  285.     /**
  286.      * Sets the button attributes
  287.      *
  288.      * In <b>custom example 1</b>, the <i>add</i> and <i>remove</i> buttons have look set
  289.      * by the css class <i>inputCommand</i>. See especially lines 43-48 and 98-103.
  290.      *
  291.      * In <b>custom example 2</b>, the basic text <i>add</i> and <i>remove</i> buttons
  292.      * are now replaced by images. See lines 43-44.
  293.      *
  294.      * In <b>custom example 5</b>, we have ability to sort the selection list (on right side)
  295.      * by :
  296.      * <pre>
  297.      *  - <b>user-end</b>: with <i>Up</i> and <i>Down</i> buttons
  298.      *    (see lines 65,65,76 and 128-130)
  299.      *  - <b>programming</b>: with the QF element constructor $sort option
  300.      *    (see lines 34,36,38 and 59)
  301.      * </pre>
  302.      *
  303.      * @example    examples/qfams_custom_5.php                                      Custom example 5: source code
  304.      * @link       http://www.laurent-laville.org/img/qfams/screenshot/custom5.png  Custom example 5: screenshot
  305.      *
  306.      * @example    examples/qfams_custom_2.php                                      Custom example 2: source code
  307.      * @link       http://www.laurent-laville.org/img/qfams/screenshot/custom2.png  Custom example 2: screenshot
  308.      *
  309.      * @example    examples/qfams_custom_1.php                                      Custom example 1: source code
  310.      * @link       http://www.laurent-laville.org/img/qfams/screenshot/custom1.png  Custom example 1: screenshot
  311.      *
  312.      * @param      string    $button        Button identifier, either 'add', 'remove', 'moveup' or 'movedown'
  313.      * @param      mixed     $attributes    (optional) Either a typical HTML attribute string
  314.      *                                       or an associative array
  315.      * @access     public
  316.      * @since      0.4.0
  317.      */
  318.     function setButtonAttributes($button$attributes null)
  319.     {
  320.         if (!is_string($button)) {
  321.             return PEAR::raiseError('Argument 1 of advmultiselect::setButtonAttributes'
  322.                                    .' is not a string');
  323.         }
  324.  
  325.         switch ($button{
  326.             case 'add':
  327.                 if (is_null($attributes)) {
  328.                     $this->_addButtonAttributes = array('name'  => 'add',
  329.                                                         'value' => ' >> ',
  330.                                                         'type'  => 'button'
  331.                                                        );
  332.                 else {
  333.                     $this->_updateAttrArray($this->_addButtonAttributes,
  334.                                             $this->_parseAttributes($attributes)
  335.                     );
  336.                 }
  337.                 break;
  338.             case 'remove':
  339.                 if (is_null($attributes)) {
  340.                     $this->_removeButtonAttributes = array('name'  => 'remove',
  341.                                                            'value' => ' << ',
  342.                                                            'type'  => 'button'
  343.                                                           );
  344.                 else {
  345.                     $this->_updateAttrArray($this->_removeButtonAttributes,
  346.                                             $this->_parseAttributes($attributes)
  347.                     );
  348.                 }
  349.                 break;
  350.             case 'moveup':
  351.                 if (is_null($attributes)) {
  352.                     $this->_upButtonAttributes = array('name'  => 'up',
  353.                                                        'value' => ' Up ',
  354.                                                        'type'  => 'button'
  355.                                                       );
  356.                 else {
  357.                     $this->_updateAttrArray($this->_upButtonAttributes,
  358.                                             $this->_parseAttributes($attributes)
  359.                     );
  360.                 }
  361.                 break;
  362.             case 'movedown':
  363.                 if (is_null($attributes)) {
  364.                     $this->_downButtonAttributes = array('name'  => 'down',
  365.                                                          'value' => ' Down ',
  366.                                                          'type'  => 'button'
  367.                                                         );
  368.                 else {
  369.                     $this->_updateAttrArray($this->_downButtonAttributes,
  370.                                             $this->_parseAttributes($attributes)
  371.                     );
  372.                 }
  373.                 break;
  374.             default;
  375.                 return PEAR::raiseError('Argument 1 of advmultiselect::setButtonAttributes'
  376.                                        .' has unexpected value');
  377.         }
  378.     }
  379.  
  380.     /**
  381.      * Sets element template
  382.      *
  383.      * @param      string    $html          The HTML surrounding select boxes and buttons
  384.      *
  385.      * @access     public
  386.      * @return     void 
  387.      * @since      0.4.0
  388.      */
  389.     function setElementTemplate($html)
  390.     {
  391.         $this->_elementTemplate = $html;
  392.     }
  393.  
  394.     /**
  395.      * Sets JavaScript function name parts. Maybe usefull to avoid conflict names
  396.      *
  397.      * In <b>multiple example 1</b>, the javascript function prefix is set to not null
  398.      * (see line 60).
  399.      *
  400.      * @example    examples/qfams_multiple_1.php                                      Multiple example 1: source code
  401.      * @link       http://www.laurent-laville.org/img/qfams/screenshot/multiple1.png  Multiple example 1: screenshot
  402.      *
  403.      * @param      string    $pref          (optional) Prefix name
  404.      * @param      string    $post          (optional) Postfix name
  405.      *
  406.      * @access     public
  407.      * @return     void 
  408.      * @see        getElementJs()
  409.      * @since      0.4.0
  410.      */
  411.     function setJsElement($pref null$post 'moveSelections')
  412.     {
  413.         $this->_jsPrefix  = $pref;
  414.         $this->_jsPostfix = $post;
  415.     }
  416.  
  417.     /**
  418.      * Gets default element stylesheet for a single multi-select shape render
  419.      *
  420.      * In <b>custom example 4</b>, the template defined lines 80-87 allows
  421.      * a single multi-select checkboxes shape. Useful when javascript is disabled
  422.      * (or when browser is not js compliant). In our example, no need to add javascript code
  423.      * (see lines 170-172), but css is mandatory (see line 142).
  424.      *
  425.      * @example    qfams_custom_4.php                                               Custom example 4: source code
  426.      * @link       http://www.laurent-laville.org/img/qfams/screenshot/custom4.png  Custom example 4: screenshot
  427.      *
  428.      * @param      boolean   $raw           (optional) html output with style tags or just raw data
  429.      *
  430.      * @access     public
  431.      * @return     string 
  432.      * @since      0.4.0
  433.      */
  434.     function getElementCss($raw true)
  435.     {
  436.         $id $this->getAttribute('id');
  437.         $css str_replace('{id}'$id$this->_elementCSS);
  438.  
  439.         if ($raw !== true{
  440.             $css '<style type="text/css">' PHP_EOL
  441.                  . '/*<![CDATA[*/' PHP_EOL
  442.                  . $css PHP_EOL
  443.                  . '/*]]>*/'  PHP_EOL
  444.                  . '</style>';
  445.         }
  446.         return $css;
  447.     }
  448.  
  449.     /**
  450.      * Returns the HTML generated for the advanced mutliple select component
  451.      *
  452.      * @access     public
  453.      * @return     string 
  454.      * @since      0.4.0
  455.      */
  456.     function toHtml()
  457.     {
  458.         if ($this->_flagFrozen{
  459.             return $this->getFrozenHtml();
  460.         }
  461.  
  462.         $tabs    $this->_getTabs();
  463.         $tab     $this->_getTab();
  464.         $strHtml '';
  465.  
  466.         if ($this->getComment(!= ''{
  467.             $strHtml .= $tabs '<!-- ' $this->getComment(" //-->" PHP_EOL;
  468.         }
  469.  
  470.         $selectName $this->getName('[]';
  471.  
  472.         // placeholder {unselected} existence determines if we will render
  473.         if (strpos($this->_elementTemplate'{unselected}'=== false{
  474.             // ... a single multi-select with checkboxes
  475.  
  476.             $id $this->getAttribute('id');
  477.  
  478.             $strHtmlSelected $tab '<div id="'.$id.'amsSelected">'  PHP_EOL;
  479.  
  480.             foreach ($this->_options as $option{
  481.  
  482.                 $_labelAttributes  array('style''class''onmouseover''onmouseout');
  483.                 $labelAttributes array();
  484.                 foreach ($_labelAttributes as $attr{
  485.                     if (isset($option['attr'][$attr])) {
  486.                         $labelAttributes[$attr$option['attr'][$attr];
  487.                         unset($option['attr'][$attr]);
  488.                     }
  489.                 }
  490.  
  491.                 if (is_array($this->_values&& in_array((string)$option['attr']['value']$this->_values)) {
  492.                     // The items is *selected*
  493.                     $checked ' checked="checked"';
  494.                 else {
  495.                     // The item is *unselected* so we want to put it
  496.                     $checked '';
  497.                 }
  498.                 $strHtmlSelected .= $tab
  499.                                  .  '<label'
  500.                                  .  $this->_getAttrString($labelAttributes.'>'
  501.                                  .  '<input type="checkbox"'
  502.                                  .  ' name="'.$selectName.'"'
  503.                                  .  $checked
  504.                                  .  $this->_getAttrString($option['attr'])
  505.                                  .  ' />' .  $option['text''</label>'
  506.                                  .  PHP_EOL;
  507.             }
  508.             $strHtmlSelected    .= $tab '</div>'PHP_EOL;
  509.  
  510.             $strHtmlHidden '';
  511.             $strHtmlUnselected '';
  512.             $strHtmlAdd '';
  513.             $strHtmlRemove '';
  514.             $strHtmlMoveUp '';
  515.             $strHtmlMoveDown '';
  516.  
  517.         else {
  518.             // ... or a dual multi-select
  519.  
  520.             // set name of Select From Box
  521.             $this->_attributesUnselected = array('name' => '__'.$selectName'ondblclick' => "{$this->_jsPrefix}{$this->_jsPostfix}(this.form.elements['__" . $selectName . "'], this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "'], 'add')");
  522.             $this->_attributesUnselected = array_merge($this->_attributes$this->_attributesUnselected);
  523.             $attrUnselected $this->_getAttrString($this->_attributesUnselected);
  524.  
  525.             // set name of Select To Box
  526.             $this->_attributesSelected = array('name' => '_'.$selectName'ondblclick' => "{$this->_jsPrefix}{$this->_jsPostfix}(this.form.elements['__" . $selectName . "'], this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "'], 'remove')");
  527.             $this->_attributesSelected = array_merge($this->_attributes$this->_attributesSelected);
  528.             $attrSelected $this->_getAttrString($this->_attributesSelected);
  529.  
  530.             // set name of Select hidden Box
  531.             $this->_attributesHidden = array('name' => $selectName'style' => 'overflow: hidden; visibility: hidden; width: 1px; height: 0;');
  532.             $this->_attributesHidden = array_merge($this->_attributes$this->_attributesHidden);
  533.             $attrHidden $this->_getAttrString($this->_attributesHidden);
  534.  
  535.             // prepare option tables to be displayed as in POST order
  536.             $append count($this->_values);
  537.             if ($append 0{
  538.                 $arrHtmlSelected = array_fill(0, $append, ' ');
  539.             }
  540.             $arrHtmlHidden = array_fill(0, count($this->_options)' ');
  541.  
  542.             foreach ($this->_options as $option{
  543.                 if (is_array($this->_values&&
  544.                     in_array((string)$option['attr']['value']$this->_values)) {
  545.                     // Get the post order
  546.                     $key = array_search($option['attr']['value'], $this->_values);
  547.  
  548.                     // The items is *selected* so we want to put it in the 'selected' multi-select
  549.                     $arrHtmlSelected[$key$option;
  550.                     // Add it to the 'hidden' multi-select and set it as 'selected'
  551.                     $option['attr']['selected''selected';
  552.                     $arrHtmlHidden[$key$option;
  553.                 } else {
  554.                     // The item is *unselected* so we want to put it in the 'unselected' multi-select
  555.                     $arrHtmlUnselected[] = $option;
  556.                     // Add it to the hidden multi-select as 'unselected'
  557.                     $arrHtmlHidden[$append] = $option;
  558.                     $append++;
  559.                 }
  560.             }
  561.  
  562.             // The 'unselected' multi-select which appears on the left
  563.             $strHtmlUnselected = "<select$attrUnselected>"PHP_EOL;
  564.             foreach ($arrHtmlUnselected as $data) {
  565.                 $strHtmlUnselected .= $tabs . $tab
  566.                                    . '<option' . $this->_getAttrString($data['attr']'>'
  567.                                    . $data['text''</option>' PHP_EOL;
  568.             }
  569.             $strHtmlUnselected .= '</select>';
  570.  
  571.             // The 'selected' multi-select which appears on the right
  572.             $strHtmlSelected = "<select$attrSelected>"PHP_EOL;
  573.             if (isset($arrHtmlSelected)) {
  574.                 foreach ($arrHtmlSelected as $data) {
  575.                     $strHtmlSelected .= $tabs . $tab
  576.                                      . '<option' . $this->_getAttrString($data['attr']'>'
  577.                                      . $data['text''</option>' PHP_EOL;
  578.                 }
  579.             }
  580.             $strHtmlSelected   .= '</select>';
  581.  
  582.             // The 'hidden' multi-select
  583.             $strHtmlHidden = "<select$attrHidden>"PHP_EOL;
  584.             foreach ($arrHtmlHidden as $data) {
  585.                 $strHtmlHidden .= $tabs . $tab
  586.                                . '<option' . $this->_getAttrString($data['attr']'>'
  587.                                . $data['text''</option>' PHP_EOL;
  588.             }
  589.             $strHtmlHidden     .= '</select>';
  590.  
  591.             // build the remove button with all its attributes
  592.             $attributes = array('onclick' => "{$this->_jsPrefix}{$this->_jsPostfix}(this.form.elements['__" . $selectName . "'], this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "'], 'remove'); return false;");
  593.             $this->_removeButtonAttributes = array_merge($this->_removeButtonAttributes$attributes);
  594.             $attrStrRemove $this->_getAttrString($this->_removeButtonAttributes);
  595.             $strHtmlRemove "<input$attrStrRemove />"PHP_EOL;
  596.  
  597.             // build the add button with all its attributes
  598.             $attributes = array('onclick' => "{$this->_jsPrefix}{$this->_jsPostfix}(this.form.elements['__" . $selectName . "'], this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "'], 'add'); return false;");
  599.             $this->_addButtonAttributes = array_merge($this->_addButtonAttributes$attributes);
  600.             $attrStrAdd $this->_getAttrString($this->_addButtonAttributes);
  601.             $strHtmlAdd "<input$attrStrAdd />"PHP_EOL;
  602.  
  603.             // build the move up button with all its attributes
  604.             $attributes = array('onclick' => "{$this->_jsPrefix}moveUp(this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "']); return false;");
  605.             $this->_upButtonAttributes = array_merge($this->_upButtonAttributes$attributes);
  606.             $attrStrUp $this->_getAttrString($this->_upButtonAttributes);
  607.             $strHtmlMoveUp "<input$attrStrUp />"PHP_EOL;
  608.  
  609.             // build the move down button with all its attributes
  610.             $attributes = array('onclick' => "{$this->_jsPrefix}moveDown(this.form.elements['_" . $selectName . "'], this.form.elements['" . $selectName . "']); return false;");
  611.             $this->_downButtonAttributes = array_merge($this->_downButtonAttributes$attributes);
  612.             $attrStrDown $this->_getAttrString($this->_downButtonAttributes);
  613.             $strHtmlMoveDown "<input$attrStrDown />"PHP_EOL;
  614.         }
  615.  
  616.         // render all part of the multi select component with the template
  617.         $strHtml = $this->_elementTemplate;
  618.  
  619.         // Prepare multiple labels
  620.         $labels $this->getLabel();
  621.         if (is_array($labels)) {
  622.             array_shift($labels);
  623.         }
  624.         // render extra labels, if any
  625.         if (is_array($labels)) {
  626.             foreach($labels as $key => $text) {
  627.                 $key  = is_int($key)$key + 2$key;
  628.                 $strHtml = str_replace("{label_{$key}}", $text, $strHtml);
  629.                 $strHtml = str_replace("<!-- BEGIN label_{$key} -->", '', $strHtml);
  630.                 $strHtml = str_replace("<!-- END label_{$key} -->", '', $strHtml);
  631.             }
  632.         }
  633.         // clean up useless label tags
  634.         if (strpos($strHtml, '{label_')) {
  635.             $strHtml = preg_replace('/\s*<!-- BEGIN label_(\S+) -->.*<!-- END label_\1 -->\s*/i', '', $strHtml);
  636.         }
  637.  
  638.         $placeHolders = array(
  639.             '{stylesheet}', '{javascript}', '{class}',
  640.             '{unselected}', '{selected}',
  641.             '{add}', '{remove}',
  642.             '{moveup}', '{movedown}'
  643.         );
  644.         $htmlElements = array(
  645.             $this->getElementCss(false)$this->getElementJs(false)$this->_tableAttributes,
  646.             $strHtmlUnselected$strHtmlSelected $strHtmlHidden,
  647.             $strHtmlAdd$strHtmlRemove,
  648.             $strHtmlMoveUp$strHtmlMoveDown
  649.         );
  650.  
  651.         $strHtml str_replace($placeHolders$htmlElements$strHtml);
  652.  
  653.         return $strHtml;
  654.     }
  655.  
  656.     /**
  657.      * Returns the javascript code generated to handle this element
  658.      *
  659.      * @param      boolean   $raw           (optional) html output with script tags or just raw data
  660.      *
  661.      * @access     public
  662.      * @return     string
  663.      * @see        setJsElement()
  664.      * @since      0.4.0
  665.      */
  666.     function getElementJs($raw = true)
  667.     {
  668.         $js = '';
  669.         $jsfuncName = $this->_jsPrefix . $this->_jsPostfix;
  670.         if (!defined('HTML_QUICKFORM_ADVMULTISELECT_'.$jsfuncName.'_EXISTS')) {
  671.              // We only want to include the javascript code once per form
  672.             define('HTML_QUICKFORM_ADVMULTISELECT_'.$jsfuncName.'_EXISTS', true);
  673.  
  674.             $js .= "
  675. /* begin javascript for HTML_QuickForm_advmultiselect */
  676. function {$jsfuncName}(selectLeft, selectRight, selectHidden, action) {
  677.     if (action == 'add') {
  678.         menuFrom = selectLeft;
  679.         menuTo = selectRight;
  680.     }
  681.     else {
  682.         menuFrom = selectRight;
  683.         menuTo = selectLeft;
  684.     }
  685.     // Don't do anything if nothing selected. Otherwise we throw javascript errors.
  686.     if (menuFrom.selectedIndex == -1) {
  687.         return;
  688.     }
  689.  
  690.     // Add items to the 'TO' list.
  691.     for (i=0; i < menuFrom.length; i++) {
  692.         if (menuFrom.options[i].selected == true ) {
  693.             menuTo.options[menuTo.length]= new Option(menuFrom.options[i].text, menuFrom.options[i].value);
  694.         }
  695.     }
  696.  
  697.     // Remove items from the 'FROM' list.
  698.     for (i=(menuFrom.length - 1); i>=0; i--){
  699.         if (menuFrom.options[i].selected == true ) {
  700.             menuFrom.options[i] = null;
  701.         }
  702.     }
  703. ";
  704.             if ($this->_sort === false{
  705.                 $js .= "
  706.     // Set the appropriate items as 'selected in the hidden select.
  707.     // These are the values that will actually be posted with the form.
  708.     {$this->_jsPrefix}updateHidden(selectHidden, selectRight);
  709. }
  710. ";
  711.             } else {
  712.                 $reverse = ($this->_sort === SORT_DESC'options.reverse();' '';
  713.  
  714.                 $js .= "
  715.     // Sort list if required
  716.     {$this->_jsPrefix}sortList(menuTo, {$this->_jsPrefix}compareText);
  717.  
  718.     // Set the appropriate items as 'selected in the hidden select.
  719.     // These are the values that will actually be posted with the form.
  720.     {$this->_jsPrefix}updateHidden(selectHidden, selectRight);
  721. }
  722.  
  723. function {$this->_jsPrefix}sortList(list, compareFunction) {
  724.     var options = new Array (list.options.length);
  725.     for (var i = 0; i < options.length; i++) {
  726.         options[i] = new Option (
  727.             list.options[i].text,
  728.             list.options[i].value,
  729.             list.options[i].defaultSelected,
  730.             list.options[i].selected
  731.         );
  732.     }
  733.     options.sort(compareFunction);
  734.     {$reverse}
  735.     list.options.length = 0;
  736.     for (var i = 0; i < options.length; i++) {
  737.         list.options[i] = options[i];
  738.     }
  739. }
  740.  
  741. function {$this->_jsPrefix}compareText(option1, option2) {
  742.     if (option1.text == option2.text) {
  743.         return 0;
  744.     }
  745.     return option1.text < option2.text ? -1 : 1;
  746. }
  747. ";
  748.             }
  749.  
  750.             $js .= "
  751. function {$this->_jsPrefix}updateHidden(h,r) {
  752.     for (i=0; i < h.length; i++) {
  753.         h.options[i].selected = false;
  754.     }
  755.  
  756.     for (i=0; i < r.length; i++) {
  757.         h.options[h.length] = new Option(r.options[i].text, r.options[i].value);
  758.         h.options[h.length-1].selected = true;
  759.     }
  760. }
  761.  
  762. function {$this->_jsPrefix}moveUp(l,h) {
  763.     var indice = l.selectedIndex;
  764.     if (indice < 0) {
  765.         return;
  766.     }
  767.     if (indice > 0) {
  768.         {$this->_jsPrefix}moveSwap(l, indice, indice-1);
  769.         {$this->_jsPrefix}updateHidden(h, l);
  770.     }
  771. }
  772.  
  773. function {$this->_jsPrefix}moveDown(l,h) {
  774.     var indice = l.selectedIndex;
  775.     if (indice < 0) {
  776.         return;
  777.     }
  778.     if (indice < l.options.length-1) {
  779.         {$this->_jsPrefix}moveSwap(l, indice, indice+1);
  780.         {$this->_jsPrefix}updateHidden(h, l);
  781.     }
  782. }
  783.  
  784. function {$this->_jsPrefix}moveSwap(l,i,j) {
  785.     var valeur = l.options[i].value;
  786.     var texte = l.options[i].text;
  787.     l.options[i].value = l.options[j].value;
  788.     l.options[i].text = l.options[j].text;
  789.     l.options[j].value = valeur;
  790.     l.options[j].text = texte;
  791.     l.selectedIndex = j
  792. }
  793.  
  794. /* end javascript for HTML_QuickForm_advmultiselect */
  795. ";
  796.             if ($raw !== true) {
  797.                 $js = '<script type="text/javascript">' . PHP_EOL
  798.                     . '/* <![CDATA[ */' . $js . '/* ]]> */' . PHP_EOL
  799.                     . '</script>';
  800.             }
  801.         }
  802.         return $js;
  803.     }
  804. }
  805.  
  806. if (class_exists('HTML_QuickForm')) {
  807.     HTML_QuickForm::registerElementType('advmultiselect', 'HTML/QuickForm/advmultiselect.php', 'HTML_QuickForm_advmultiselect');
  808. }

Documentation generated on Thu, 12 Jun 2008 12:55:12 -0500 by phpDocumentor 1.4.1