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.  * Copyright (c) 2005-2008, Laurent Laville <pear@laurent-laville.org>
  4.  *
  5.  * All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  *     * Redistributions of source code must retain the above copyright
  12.  *       notice, this list of conditions and the following disclaimer.
  13.  *     * Redistributions in binary form must reproduce the above copyright
  14.  *       notice, this list of conditions and the following disclaimer in the
  15.  *       documentation and/or other materials provided with the distribution.
  16.  *     * Neither the name of the authors nor the names of its contributors
  17.  *       may be used to endorse or promote products derived from this software
  18.  *       without specific prior written permission.
  19.  *
  20.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  21.  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23.  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
  24.  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  25.  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  26.  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  27.  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  28.  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  29.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  30.  * POSSIBILITY OF SUCH DAMAGE.
  31.  *
  32.  * PHP versions 4 and 5
  33.  *
  34.  * @category  HTML
  35.  * @package   HTML_QuickForm_advmultiselect
  36.  * @author    Laurent Laville <pear@laurent-laville.org>
  37.  * @copyright 2005-2008 Laurent Laville
  38.  * @license   http://www.opensource.org/licenses/bsd-license.php  BSD
  39.  * @version   CVS: $Id: advmultiselect.php,v 1.18 2008/04/26 17:37:00 farell Exp $
  40.  * @link      http://pear.php.net/package/HTML_QuickForm_advmultiselect
  41.  * @since     File available since Release 0.4.0
  42.  */
  43.  
  44. require_once 'HTML/QuickForm/select.php';
  45.  
  46. /**
  47.  * Element for HTML_QuickForm that emulate a multi-select.
  48.  *
  49.  * The HTML_QuickForm_advmultiselect package adds an element to the
  50.  * HTML_QuickForm package that is two select boxes next to each other
  51.  * emulating a multi-select.
  52.  *
  53.  * @category  HTML
  54.  * @package   HTML_QuickForm_advmultiselect
  55.  * @author    Laurent Laville <pear@laurent-laville.org>
  56.  * @copyright 2005-2008 Laurent Laville
  57.  * @license   http://www.opensource.org/licenses/bsd-license.php  BSD
  58.  * @version   Release: @package_version@
  59.  * @link      http://pear.php.net/package/HTML_QuickForm_advmultiselect
  60.  * @since     Class available since Release 0.4.0
  61.  */
  62. class HTML_QuickForm_advmultiselect extends HTML_QuickForm_select
  63. {
  64.     /**
  65.      * Prefix function name in javascript move selections
  66.      *
  67.      * @var        string 
  68.      * @access     private
  69.      * @since      0.4.0
  70.      */
  71.     var $_jsPrefix;
  72.  
  73.     /**
  74.      * Postfix function name in javascript move selections
  75.      *
  76.      * @var        string 
  77.      * @access     private
  78.      * @since      0.4.0
  79.      */
  80.     var $_jsPostfix;
  81.  
  82.     /**
  83.      * Associative array of the multi select container attributes
  84.      *
  85.      * @var        array 
  86.      * @access     private
  87.      * @since      0.4.0
  88.      */
  89.     var $_tableAttributes;
  90.  
  91.     /**
  92.      * Associative array of the add button attributes
  93.      *
  94.      * @var        array 
  95.      * @access     private
  96.      * @since      0.4.0
  97.      */
  98.     var $_addButtonAttributes;
  99.  
  100.     /**
  101.      * Associative array of the remove button attributes
  102.      *
  103.      * @var        array 
  104.      * @access     private
  105.      * @since      0.4.0
  106.      */
  107.     var $_removeButtonAttributes;
  108.  
  109.     /**
  110.      * Associative array of the select all button attributes
  111.      *
  112.      * @var        array 
  113.      * @access     private
  114.      * @since      1.1.0
  115.      */
  116.     var $_allButtonAttributes;
  117.  
  118.     /**
  119.      * Associative array of the select none button attributes
  120.      *
  121.      * @var        array 
  122.      * @access     private
  123.      * @since      1.1.0
  124.      */
  125.     var $_noneButtonAttributes;
  126.  
  127.     /**
  128.      * Associative array of the toggle selection button attributes
  129.      *
  130.      * @var        array 
  131.      * @access     private
  132.      * @since      1.1.0
  133.      */
  134.     var $_toggleButtonAttributes;
  135.  
  136.     /**
  137.      * Associative array of the move up button attributes
  138.      *
  139.      * @var        array 
  140.      * @access     private
  141.      * @since      0.5.0
  142.      */
  143.     var $_upButtonAttributes;
  144.  
  145.     /**
  146.      * Associative array of the move up button attributes
  147.      *
  148.      * @var        array 
  149.      * @access     private
  150.      * @since      0.5.0
  151.      */
  152.     var $_downButtonAttributes;
  153.  
  154.     /**
  155.      * Defines if both list (unselected, selected) will have their elements be
  156.      * arranged from lowest to highest (or reverse)
  157.      * depending on comparaison function.
  158.      *
  159.      * SORT_ASC  is used to sort in ascending order
  160.      * SORT_DESC is used to sort in descending order
  161.      *
  162.      * @var    string    ('none' == false, 'asc' == SORT_ASC, 'desc' == SORT_DESC)
  163.      * @access private
  164.      * @since  0.5.0
  165.      */
  166.     var $_sort;
  167.  
  168.     /**
  169.      * Associative array of the unselected item box attributes
  170.      *
  171.      * @var        array 
  172.      * @access     private
  173.      * @since      0.4.0
  174.      */
  175.     var $_attributesUnselected;
  176.  
  177.     /**
  178.      * Associative array of the selected item box attributes
  179.      *
  180.      * @var        array 
  181.      * @access     private
  182.      * @since      0.4.0
  183.      */
  184.     var $_attributesSelected;
  185.  
  186.     /**
  187.      * Associative array of the internal hidden box attributes
  188.      *
  189.      * @var        array 
  190.      * @access     private
  191.      * @since      0.4.0
  192.      */
  193.     var $_attributesHidden;
  194.  
  195.     /**
  196.      * Default Element template string
  197.      *
  198.      * @var        string 
  199.      * @access     private
  200.      * @since      0.4.0
  201.      */
  202.     var $_elementTemplate '
  203. {javascript}
  204. <table{class}>
  205. <!-- BEGIN label_2 --><tr><th>{label_2}</th><!-- END label_2 -->
  206. <!-- BEGIN label_3 --><th>&nbsp;</th><th>{label_3}</th></tr><!-- END label_3 -->
  207. <tr>
  208.   <td valign="top">{unselected}</td>
  209.   <td align="center">{add}{remove}</td>
  210.   <td valign="top">{selected}</td>
  211. </tr>
  212. </table>
  213. ';
  214.  
  215.     /**
  216.      * Default Element stylesheet string
  217.      *
  218.      * @var        string 
  219.      * @access     private
  220.      * @since      0.4.0
  221.      */
  222.     var $_elementCSS '
  223. #qfams_{id} {
  224.   font: 13.3px sans-serif;
  225.   background-color: #fff;
  226.   overflow: auto;
  227.   height: 14.3em;
  228.   width: 12em;
  229.   border-left:   1px solid #404040;
  230.   border-top:    1px solid #404040;
  231.   border-bottom: 1px solid #d4d0c8;
  232.   border-right:  1px solid #d4d0c8;
  233. }
  234. #qfams_{id} label {
  235.   padding-right: 3px;
  236.   display: block;
  237. }
  238. ';
  239.  
  240.     /**
  241.      * Class constructor
  242.      *
  243.      * Class constructors :
  244.      * Zend Engine 1 uses HTML_QuickForm_advmultiselect, while
  245.      * Zend Engine 2 uses __construct
  246.      *
  247.      * @param string  $elementName  Dual Select name attribute
  248.      * @param mixed   $elementLabel Label(s) for the select boxes
  249.      * @param mixed   $options      Data to be used to populate options
  250.      * @param mixed   $attributes   Either a typical HTML attribute string or
  251.      *                               an associative array
  252.      * @param integer $sort         Either SORT_ASC for auto ascending arrange,
  253.      *                                      SORT_DESC for auto descending arrange, or
  254.      *                                      NULL for no sort (append at end: default)
  255.      *
  256.      * @access     public
  257.      * @return     void 
  258.      * @since      0.4.0
  259.      */
  260.     function HTML_QuickForm_advmultiselect($elementName = null$elementLabel = null,
  261.                                            $options = null$attributes = null,
  262.                                            $sort = null)
  263.     {
  264.         $this->HTML_QuickForm_select($elementName$elementLabel,
  265.             $options$attributes);
  266.  
  267.         // add multiple selection attribute by default if missing
  268.         $this->updateAttributes(array('multiple' => 'multiple'));
  269.  
  270.         if (is_null($this->getAttribute('size'))) {
  271.             // default size is ten item on each select box (left and right)
  272.             $this->updateAttributes(array('size' => 10));
  273.         }
  274.         if (is_null($this->getAttribute('style'))) {
  275.             // default width of each select box
  276.             $this->updateAttributes(array('style' => 'width:100px;'));
  277.         }
  278.         $this->_tableAttributes $this->getAttribute('class');
  279.         if (is_null($this->_tableAttributes)) {
  280.             // default table layout
  281.             $attr = array('border' => '0',
  282.                           'cellpadding' => '10''cellspacing' => '0');
  283.         else {
  284.             $attr = array('class' => $this->_tableAttributes);
  285.             $this->_removeAttr('class'$this->_attributes);
  286.         }
  287.         $this->_tableAttributes $this->_getAttrString($attr);
  288.  
  289.         // set default add button attributes
  290.         $this->setButtonAttributes('add');
  291.         // set default remove button attributes
  292.         $this->setButtonAttributes('remove');
  293.         // set default selectall button attributes
  294.         $this->setButtonAttributes('all');
  295.         // set default selectnone button attributes
  296.         $this->setButtonAttributes('none');
  297.         // set default toggle selection button attributes
  298.         $this->setButtonAttributes('toggle');
  299.         // set default move up button attributes
  300.         $this->setButtonAttributes('moveup');
  301.         // set default move up button attributes
  302.         $this->setButtonAttributes('movedown');
  303.         // defines javascript functions names
  304.         $this->setJsElement();
  305.  
  306.         // set select boxes sort order (none by default)
  307.         if (!isset($sort)) {
  308.             $sort = false;
  309.         }
  310.         if ($sort === SORT_ASC{
  311.             $this->_sort 'asc';
  312.         elseif ($sort === SORT_DESC{
  313.             $this->_sort 'desc';
  314.         else {
  315.             $this->_sort 'none';
  316.         }
  317.     }
  318.  
  319.     /**
  320.      * Sets the button attributes
  321.      *
  322.      * In <b>custom example 1</b>, the <i>add</i> and <i>remove</i> buttons
  323.      * have look set by the css class <i>inputCommand</i>.
  324.      *
  325.      * In <b>custom example 2</b>, the basic text <i>add</i> and <i>remove</i>
  326.      * buttons are now replaced by images.
  327.      *
  328.      * In <b>custom example 5</b>, we have ability to sort the selection list
  329.      * (on right side) by :
  330.      * <pre>
  331.      *  - <b>user-end</b>: with <i>Up</i> and <i>Down</i> buttons
  332.      *  - <b>programming</b>: with the QF element constructor $sort option
  333.      * </pre>
  334.      *
  335.      * @param string $button     Button identifier, either 'add', 'remove',
  336.      *                                                      'all', 'none', 'toggle',
  337.      *                                                      'moveup' or 'movedown'
  338.      * @param mixed  $attributes (optional) Either a typical HTML attribute string
  339.      *                                       or an associative array
  340.      *
  341.      * @return     void 
  342.      * @throws     PEAR_Error   $button argument
  343.      *                           is not a string, or not in range
  344.      *                           (add, remove, all, none, toggle, moveup, movedown)
  345.      * @access     public
  346.      * @since      0.4.0
  347.      *
  348.      * @example    examples/qfams_custom_5.php
  349.      *              Custom example 5: source code
  350.      * @link       http://www.laurent-laville.org/img/qfams/screenshot/custom5.png
  351.      *              Custom example 5: screenshot
  352.      *
  353.      * @example    examples/qfams_custom_2.php
  354.      *              Custom example 2: source code
  355.      * @link       http://www.laurent-laville.org/img/qfams/screenshot/custom2.png
  356.      *              Custom example 2: screenshot
  357.      *
  358.      * @example    examples/qfams_custom_1.php
  359.      *              Custom example 1: source code
  360.      * @link       http://www.laurent-laville.org/img/qfams/screenshot/custom1.png
  361.      *              Custom example 1: screenshot
  362.      */
  363.     function setButtonAttributes($button$attributes = null)
  364.     {
  365.         if (!is_string($button)) {
  366.             return PEAR::raiseError('Argument 1 of ' .
  367.                        'advmultiselect::setButtonAttributes is not a string');
  368.         }
  369.  
  370.         switch ($button{
  371.         case 'add':
  372.             if (is_null($attributes)) {
  373.                 $this->_addButtonAttributes
  374.                     = array('name'  => 'add',
  375.                             'value' => ' >> ',
  376.                             'type'  => 'button');
  377.             else {
  378.                 $this->_updateAttrArray($this->_addButtonAttributes,
  379.                                         $this->_parseAttributes($attributes));
  380.             }
  381.             break;
  382.         case 'remove':
  383.             if (is_null($attributes)) {
  384.                 $this->_removeButtonAttributes
  385.                     = array('name'  => 'remove',
  386.                             'value' => ' << ',
  387.                             'type'  => 'button');
  388.             else {
  389.                 $this->_updateAttrArray($this->_removeButtonAttributes,
  390.                                         $this->_parseAttributes($attributes));
  391.             }
  392.             break;
  393.         case 'all':
  394.             if (is_null($attributes)) {
  395.                 $this->_allButtonAttributes
  396.                     = array('name'  => 'all',
  397.                             'value' => ' Select All ',
  398.                             'type'  => 'button');
  399.             else {
  400.                 $this->_updateAttrArray($this->_allButtonAttributes,
  401.                                         $this->_parseAttributes($attributes));
  402.             }
  403.             break;
  404.         case 'none':
  405.             if (is_null($attributes)) {
  406.                 $this->_noneButtonAttributes
  407.                     = array('name'  => 'none',
  408.                             'value' => ' Select None ',
  409.                             'type'  => 'button');
  410.             else {
  411.                 $this->_updateAttrArray($this->_noneButtonAttributes,
  412.                                         $this->_parseAttributes($attributes));
  413.             }
  414.             break;
  415.         case 'toggle':
  416.             if (is_null($attributes)) {
  417.                 $this->_toggleButtonAttributes
  418.                     = array('name'  => 'toggle',
  419.                             'value' => ' Toggle Selection ',
  420.                             'type'  => 'button');
  421.             else {
  422.                 $this->_updateAttrArray($this->_toggleButtonAttributes,
  423.                                         $this->_parseAttributes($attributes));
  424.             }
  425.             break;
  426.         case 'moveup':
  427.             if (is_null($attributes)) {
  428.                 $this->_upButtonAttributes
  429.                     = array('name'  => 'up',
  430.                             'value' => ' Up ',
  431.                             'type'  => 'button');
  432.             else {
  433.                 $this->_updateAttrArray($this->_upButtonAttributes,
  434.                                         $this->_parseAttributes($attributes));
  435.             }
  436.             break;
  437.         case 'movedown':
  438.             if (is_null($attributes)) {
  439.                 $this->_downButtonAttributes
  440.                     = array('name'  => 'down',
  441.                             'value' => ' Down ',
  442.                             'type'  => 'button');
  443.             else {
  444.                 $this->_updateAttrArray($this->_downButtonAttributes,
  445.                                         $this->_parseAttributes($attributes));
  446.             }
  447.             break;
  448.         default;
  449.             return PEAR::raiseError('Argument 1 of ' .
  450.                        'advmultiselect::setButtonAttributes has unexpected value');
  451.         }
  452.     }
  453.  
  454.     /**
  455.      * Sets element template
  456.      *
  457.      * @param string $html The HTML surrounding select boxes and buttons
  458.      *
  459.      * @access     public
  460.      * @return     void 
  461.      * @since      0.4.0
  462.      */
  463.     function setElementTemplate($html)
  464.     {
  465.         $this->_elementTemplate $html;
  466.     }
  467.  
  468.     /**
  469.      * Sets JavaScript function name parts. Maybe usefull to avoid conflict names
  470.      *
  471.      * In <b>multiple example 1</b>, the javascript function prefix
  472.      * is set to not null.
  473.      *
  474.      * @param string $pref (optional) Prefix name
  475.      * @param string $post (optional) Postfix name
  476.      *
  477.      * @access     public
  478.      * @return     void 
  479.      * @see        getElementJs()
  480.      * @since      0.4.0
  481.      * @deprecated since version 1.3.0
  482.      *
  483.      * @example    examples/qfams_multiple_1.php
  484.      *              Multiple example 1: source code
  485.      * @link       http://www.laurent-laville.org/img/qfams/screenshot/multiple1.png
  486.      *              Multiple example 1: screenshot
  487.      */
  488.     function setJsElement($pref = null$post 'moveSelections')
  489.     {
  490.         $this->_jsPrefix  'qfams';
  491.         $this->_jsPostfix 'MoveSelection';
  492.     }
  493.  
  494.     /**
  495.      * Gets default element stylesheet for a single multi-select shape render
  496.      *
  497.      * In <b>custom example 4</b>, the template defined allows
  498.      * a single multi-select checkboxes shape. Useful when javascript is disabled
  499.      * (or when browser is not js compliant). In our example, no need to add
  500.      * javascript code, but css is mandatory.
  501.      *
  502.      * @param boolean $raw (optional) html output with style tags or just raw data
  503.      *
  504.      * @access     public
  505.      * @return     string 
  506.      * @since      0.4.0
  507.      *
  508.      * @example    qfams_custom_4.php
  509.      *              Custom example 4: source code
  510.      * @link       http://www.laurent-laville.org/img/qfams/screenshot/custom4.png
  511.      *              Custom example 4: screenshot
  512.      */
  513.     function getElementCss($raw = true)
  514.     {
  515.         $id  $this->getAttribute('name');
  516.         $css str_replace('{id}'$id$this->_elementCSS);
  517.  
  518.         if ($raw !== true{
  519.             $css '<style type="text/css">' . PHP_EOL
  520.                  . '<!--' $css '// -->'  . PHP_EOL
  521.                  . '</style>';
  522.         }
  523.         return $css;
  524.     }
  525.  
  526.     /**
  527.      * Returns the HTML generated for the advanced mutliple select component
  528.      *
  529.      * @access     public
  530.      * @return     string 
  531.      * @since      0.4.0
  532.      */
  533.     function toHtml()
  534.     {
  535.         if ($this->_flagFrozen{
  536.             return $this->getFrozenHtml();
  537.         }
  538.  
  539.         $tabs    $this->_getTabs();
  540.         $tab     $this->_getTab();
  541.         $strHtml '';
  542.  
  543.         if ($this->getComment(!= ''{
  544.             $strHtml .= $tabs '<!-- ' $this->getComment(" //-->" . PHP_EOL;
  545.         }
  546.  
  547.         $selectId       $this->getName();
  548.         $selectName     $this->getName('[]';
  549.         $selectNameFrom $this->getName('-f[]';
  550.         $selectNameTo   $this->getName('-t[]';
  551.         $selected_count = 0;
  552.  
  553.         // placeholder {unselected} existence determines if we will render
  554.         if (strpos($this->_elementTemplate'{unselected}'=== false{
  555.             // ... a single multi-select with checkboxes
  556.             $this->_jsPostfix 'EditSelection';
  557.  
  558.             $id $this->getAttribute('name');
  559.  
  560.             $strHtmlSelected  $tab '<div id="qfams_'.$id.'">'  . PHP_EOL;
  561.             $unselected_count count($this->_options);
  562.  
  563.             $checkbox_id_suffix = 0;
  564.  
  565.             foreach ($this->_options as $option{
  566.                 $_labelAttributes
  567.                     = array('style''class''onmouseover''onmouseout');
  568.                 $labelAttributes = array();
  569.                 foreach ($_labelAttributes as $attr{
  570.                     if (isset($option['attr'][$attr])) {
  571.                         $labelAttributes[$attr$option['attr'][$attr];
  572.                         unset($option['attr'][$attr]);
  573.                     }
  574.                 }
  575.  
  576.                 if (is_array($this->_values)
  577.                     && in_array((string)$option['attr']['value']$this->_values)) {
  578.                     // The items is *selected*
  579.                     $checked ' checked="checked"';
  580.                     $selected_count++;
  581.                 else {
  582.                     // The item is *unselected* so we want to put it
  583.                     $checked '';
  584.                 }
  585.                 $checkbox_id_suffix++;
  586.                 $strHtmlSelected .= $tab
  587.                                  .  '<label'
  588.                                  .  $this->_getAttrString($labelAttributes.'>'
  589.                                  .  '<input type="checkbox"'
  590.                                  .  ' id="'.$selectId $checkbox_id_suffix.'"'
  591.                                  .  ' name="'.$selectName.'"'
  592.                                  .  $checked
  593.                                  .  $this->_getAttrString($option['attr'])
  594.                                  .  ' />' .  $option['text''</label>'
  595.                                  .  PHP_EOL;
  596.             }
  597.             $strHtmlSelected .= $tab '</div>'. PHP_EOL;
  598.  
  599.             $strHtmlHidden     '';
  600.             $strHtmlUnselected '';
  601.             $strHtmlAdd        '';
  602.             $strHtmlRemove     '';
  603.  
  604.             // build the select all button with all its attributes
  605.             $jsName     $this->_jsPrefix $this->_jsPostfix;
  606.             $attributes = array('onclick' => $jsName .
  607.                                              "('"$selectId ."', 1);");
  608.             $this->_allButtonAttributes
  609.                         = array_merge($this->_allButtonAttributes$attributes);
  610.             $attrStrAll $this->_getAttrString($this->_allButtonAttributes);
  611.             $strHtmlAll = "<input$attrStrAll />". PHP_EOL;
  612.  
  613.             // build the select none button with all its attributes
  614.             $attributes = array('onclick' => $jsName .
  615.                                              "('"$selectId ."', 0);");
  616.             $this->_noneButtonAttributes
  617.                          = array_merge($this->_noneButtonAttributes$attributes);
  618.             $attrStrNone $this->_getAttrString($this->_noneButtonAttributes);
  619.             $strHtmlNone = "<input$attrStrNone />". PHP_EOL;
  620.  
  621.             // build the toggle selection button with all its attributes
  622.             $attributes = array('onclick' => $jsName .
  623.                                              "('"$selectId ."', 2);");
  624.             $this->_toggleButtonAttributes
  625.                            = array_merge($this->_toggleButtonAttributes,
  626.                                  $attributes);
  627.             $attrStrToggle $this->_getAttrString($this->_toggleButtonAttributes);
  628.             $strHtmlToggle = "<input$attrStrToggle />". PHP_EOL;
  629.  
  630.             $strHtmlMoveUp   '';
  631.             $strHtmlMoveDown '';
  632.  
  633.             // default selection counters
  634.             $strHtmlSelectedCount $selected_count '/' $unselected_count;
  635.         else {
  636.             // ... or a dual multi-select
  637.             $this->_jsPostfix 'MoveSelection';
  638.             $jsName           $this->_jsPrefix $this->_jsPostfix;
  639.  
  640.             // set name of Select From Box
  641.             $this->_attributesUnselected
  642.                 = array('id' => $selectId '-f',
  643.                         'name' => $selectNameFrom,
  644.                         'ondblclick' => $jsName .
  645.                             "('{$selectId}', ".
  646.                             "this.form.elements['" $selectNameFrom "'], " .
  647.                             "this.form.elements['" $selectNameTo "'], " .
  648.                             "this.form.elements['" $selectName "'], " .
  649.                             "'add', '{$this->_sort}')");
  650.             $this->
  651. _attributesUnselected
  652.                 = array_merge($this->_attributes$this->_attributesUnselected);
  653.             $attrUnselected $this->_getAttrString($this->_attributesUnselected);
  654.  
  655.             // set name of Select To Box
  656.             $this->
  657. _attributesSelected
  658.                 = array('id' => $selectId '-t',
  659.                         'name' => $selectNameTo,
  660.                         'ondblclick' => $jsName .
  661.                             "('{$selectId}', " .
  662.                             "this.form.elements['" . $selectNameFrom . "'], " .
  663.                             "this.form.elements['" . $selectNameTo . "'], ".
  664.                             "this.form.elements['" . $selectName . "'], " .
  665.                             "'remove', '{$this->_sort}')");
  666.             $this->
  667. _attributesSelected
  668.                 = array_merge($this->_attributes$this->_attributesSelected);
  669.             $attrSelected $this->_getAttrString($this->_attributesSelected);
  670.  
  671.             // set name of Select hidden Box
  672.             $this->
  673. _attributesHidden
  674.                 = array('name' => $selectName,
  675.                         'style' => 'overflow: hidden; visibility: hidden; ' .
  676.                                    'width: 1px; height: 0;');
  677.             $this->
  678. _attributesHidden
  679.                 = array_merge($this->_attributes$this->_attributesHidden);
  680.             $attrHidden $this->_getAttrString($this->_attributesHidden);
  681.  
  682.             // prepare option tables to be displayed as in POST order
  683.             $append = count($this->_values);
  684.             if ($append > 0{
  685.                 $arrHtmlSelected = array_fill(0, $append, ' ');
  686.             } else {
  687.                 $arrHtmlSelected = array();
  688.             }
  689.  
  690.             $options           = count($this->_options);
  691.             $arrHtmlUnselected = array();
  692.             if ($options > 0{
  693.                 $arrHtmlHidden = array_fill(0, $options, ' ');
  694.  
  695.                 foreach ($this->_options as $option{
  696.                     if (is_array($this->_values)
  697.                         && in_array((string)$option['attr']['value'],
  698.                                $this->_values)) {
  699.                         // Get the post order
  700.                         $key = array_search($option['attr']['value'],
  701.                                    $this->_values);
  702.  
  703.                         /** The items is *selected* so we want to put it
  704.                             in the 'selected' multi-select */
  705.                         $arrHtmlSelected[$key$option;
  706.                         /** Add it to the 'hidden' multi-select
  707.                             and set it as 'selected' */
  708.                         $option['attr']['selected''selected';
  709.                         $arrHtmlHidden[$key]        $option;
  710.                     } else {
  711.                         /** The item is *unselected* so we want to put it
  712.                             in the 'unselected' multi-select */
  713.                         $arrHtmlUnselected[] = $option;
  714.                         // Add it to the hidden multi-select as 'unselected'
  715.                         $arrHtmlHidden[$append] = $option;
  716.                         $append++;
  717.                     }
  718.                 }
  719.             } else {
  720.                 $arrHtmlHidden = array();
  721.             }
  722.  
  723.             // The 'unselected' multi-select which appears on the left
  724.             $unselected_count = count($arrHtmlUnselected);
  725.  
  726.             if ($unselected_count == 0) {
  727.                 $this->_attributesUnselected['disabled''disabled';
  728.                 $this->
  729. _attributesUnselected
  730.                     = array_merge($this->_attributes$this->_attributesUnselected);
  731.                 $attrUnselected $this->_getAttrString($this->_attributesUnselected);
  732.             }
  733.             $strHtmlUnselected = "<select$attrUnselected>". PHP_EOL;
  734.             if ($unselected_count > 0) {
  735.                 foreach ($arrHtmlUnselected as $data) {
  736.                     $strHtmlUnselected
  737.                         .= $tabs . $tab
  738.                         . '<option' . $this->_getAttrString($data['attr']'>'
  739.                         . $data['text''</option>' . PHP_EOL;
  740.                 }
  741.             } else {
  742.                 $strHtmlUnselected .= '<option value="">&nbsp;</option>';
  743.             }
  744.             $strHtmlUnselected .= '</select>';
  745.  
  746.             // The 'selected' multi-select which appears on the right
  747.             $selected_count = count($arrHtmlSelected);
  748.  
  749.             if ($selected_count == 0) {
  750.                 $this->_attributesSelected['disabled''disabled';
  751.                 $this->
  752. _attributesSelected
  753.                     = array_merge($this->_attributes$this->_attributesSelected);
  754.                 $attrSelected $this->_getAttrString($this->_attributesSelected);
  755.             }
  756.             $strHtmlSelected = "<select$attrSelected>". PHP_EOL;
  757.             if ($selected_count > 0) {
  758.                 foreach ($arrHtmlSelected as $data) {
  759.                     $strHtmlSelected
  760.                         .= $tabs . $tab
  761.                         . '<option' . $this->_getAttrString($data['attr']'>'
  762.                         . $data['text''</option>' . PHP_EOL;
  763.                 }
  764.             } else {
  765.                 $strHtmlSelected .= '<option value="">&nbsp;</option>';
  766.             }
  767.             $strHtmlSelected .= '</select>';
  768.  
  769.             // The 'hidden' multi-select
  770.             $strHtmlHidden = "<select$attrHidden>". PHP_EOL;
  771.             if (count($arrHtmlHidden) > 0) {
  772.                 foreach ($arrHtmlHidden as $data) {
  773.                     $strHtmlHidden
  774.                         .= $tabs . $tab
  775.                         . '<option' . $this->_getAttrString($data['attr']'>'
  776.                         . $data['text''</option>' . PHP_EOL;
  777.                 }
  778.             }
  779.             $strHtmlHidden .= '</select>';
  780.  
  781.             // build the remove button with all its attributes
  782.             $attributes
  783.                 = array('onclick' => $jsName .
  784.                             "('{$selectId}', " .
  785.                             "this.form.elements['" . $selectNameFrom . "'], " .
  786.                             "this.form.elements['" . $selectNameTo . "'], " .
  787.                             "this.form.elements['" . $selectName . "'], " .
  788.                             "'remove', '{$this->_sort}'); return false;");
  789.             $this->
  790. _removeButtonAttributes
  791.                 = array_merge($this->_removeButtonAttributes$attributes);
  792.             $attrStrRemove $this->_getAttrString($this->_removeButtonAttributes);
  793.             $strHtmlRemove "<input$attrStrRemove />". PHP_EOL;
  794.  
  795.             // build the add button with all its attributes
  796.             $attributes
  797.                 = array('onclick' => $jsName .
  798.                             "('{$selectId}', " .
  799.                             "this.form.elements['" . $selectNameFrom . "'], " .
  800.                             "this.form.elements['" . $selectNameTo . "'], " .
  801.                             "this.form.elements['" . $selectName . "'], " .
  802.                             "'add', '{$this->_sort}'); return false;");
  803.             $this->
  804. _addButtonAttributes
  805.                 = array_merge($this->_addButtonAttributes$attributes);
  806.             $attrStrAdd $this->_getAttrString($this->_addButtonAttributes);
  807.             $strHtmlAdd "<input$attrStrAdd />". PHP_EOL;
  808.  
  809.             // build the select all button with all its attributes
  810.             $attributes
  811.                 = array('onclick' => $jsName .
  812.                             "('{$selectId}', " .
  813.                             "this.form.elements['" . $selectNameFrom . "'], " .
  814.                             "this.form.elements['" . $selectNameTo . "'], " .
  815.                             "this.form.elements['" . $selectName . "'], " .
  816.                             "'all', '{$this->_sort}'); return false;");
  817.             $this->
  818. _allButtonAttributes
  819.                 = array_merge($this->_allButtonAttributes$attributes);
  820.             $attrStrAll $this->_getAttrString($this->_allButtonAttributes);
  821.             $strHtmlAll "<input$attrStrAll />". PHP_EOL;
  822.  
  823.             // build the select none button with all its attributes
  824.             $attributes
  825.                 = array('onclick' => $jsName .
  826.                             "('{$selectId}', " .
  827.                             "this.form.elements['" . $selectNameFrom . "'], " .
  828.                             "this.form.elements['" . $selectNameTo . "'], " .
  829.                             "this.form.elements['" . $selectName . "'], " .
  830.                             "'none', '{$this->_sort}'); return false;");
  831.             $this->
  832. _noneButtonAttributes
  833.                 = array_merge($this->_noneButtonAttributes$attributes);
  834.             $attrStrNone $this->_getAttrString($this->_noneButtonAttributes);
  835.             $strHtmlNone "<input$attrStrNone />". PHP_EOL;
  836.  
  837.             // build the toggle button with all its attributes
  838.             $attributes
  839.                 = array('onclick' => $jsName .
  840.                             "('{$selectId}', " .
  841.                             "this.form.elements['" . $selectNameFrom . "'], " .
  842.                             "this.form.elements['" . $selectNameTo . "'], " .
  843.                             "this.form.elements['" . $selectName . "'], " .
  844.                             "'toggle', '{$this->_sort}'); return false;");
  845.             $this->
  846. _toggleButtonAttributes
  847.                 = array_merge($this->_toggleButtonAttributes$attributes);
  848.             $attrStrToggle $this->_getAttrString($this->_toggleButtonAttributes);
  849.             $strHtmlToggle "<input$attrStrToggle />". PHP_EOL;
  850.  
  851.             // build the move up button with all its attributes
  852.             $attributes
  853.                 = array('onclick' => "{$this->_jsPrefix}MoveUp" .
  854.                             "(this.form.elements['" . $selectNameTo . "'], " .
  855.                             "this.form.elements['" . $selectName . "']); " .
  856.                             "return false;");
  857.             $this->
  858. _upButtonAttributes
  859.                 = array_merge($this->_upButtonAttributes$attributes);
  860.             $attrStrUp     $this->_getAttrString($this->_upButtonAttributes);
  861.             $strHtmlMoveUp "<input$attrStrUp />". PHP_EOL;
  862.  
  863.             // build the move down button with all its attributes
  864.             $attributes
  865.                 = array('onclick' => "{$this->_jsPrefix}MoveDown" .
  866.                             "(this.form.elements['" . $selectNameTo . "'], " .
  867.                             "this.form.elements['" . $selectName . "']); " .
  868.                             "return false;");
  869.             $this->
  870. _downButtonAttributes
  871.                 = array_merge($this->_downButtonAttributes$attributes);
  872.             $attrStrDown     $this->_getAttrString($this->_downButtonAttributes);
  873.             $strHtmlMoveDown "<input$attrStrDown />". PHP_EOL;
  874.  
  875.             // default selection counters
  876.             $strHtmlSelectedCount = $selected_count;
  877.         }
  878.         $strHtmlUnselectedCount = $unselected_count;
  879.  
  880.         $strHtmlSelectedCountId   = $selectId .'_selected';
  881.         $strHtmlUnselectedCountId = $selectId .'_unselected';
  882.  
  883.         // render all part of the multi select component with the template
  884.         $strHtml = $this->_elementTemplate;
  885.  
  886.         // Prepare multiple labels
  887.         $labels $this->getLabel();
  888.         if (is_array($labels)) {
  889.             array_shift($labels);
  890.         }
  891.         // render extra labels, if any
  892.         if (is_array($labels)) {
  893.             foreach ($labels as $key => $text) {
  894.                 $key     = is_int($key)$key + 2: $key;
  895.                 $strHtml = str_replace("{label_{$key}}", $text, $strHtml);
  896.                 $strHtml = str_replace("<!-- BEGIN label_{$key} -->", '', $strHtml);
  897.                 $strHtml = str_replace("<!-- END label_{$key} -->", '', $strHtml);
  898.             }
  899.         }
  900.         // clean up useless label tags
  901.         if (strpos($strHtml, '{label_')) {
  902.             $strHtml = preg_replace('/\s*<!-- BEGIN label_(\S+) -->'.
  903.                            '.*<!-- END label_\1 -->\s*/i', '', $strHtml);
  904.         }
  905.  
  906.         $placeHolders = array(
  907.             '{stylesheet}', '{javascript}',
  908.             '{class}',
  909.             '{unselected_count_id}', '{selected_count_id}',
  910.             '{unselected_count}', '{selected_count}',
  911.             '{unselected}', '{selected}',
  912.             '{add}', '{remove}',
  913.             '{all}', '{none}', '{toggle}',
  914.             '{moveup}', '{movedown}'
  915.         );
  916.         $htmlElements = array(
  917.             $this->getElementCss(false)$this->getElementJs(false),
  918.             $this->_tableAttributes,
  919.             $strHtmlUnselectedCountId$strHtmlSelectedCountId,
  920.             $strHtmlUnselectedCount$strHtmlSelectedCount,
  921.             $strHtmlUnselected$strHtmlSelected $strHtmlHidden,
  922.             $strHtmlAdd$strHtmlRemove,
  923.             $strHtmlAll$strHtmlNone$strHtmlToggle,
  924.             $strHtmlMoveUp$strHtmlMoveDown
  925.         );
  926.  
  927.         $strHtml = str_replace($placeHolders$htmlElements$strHtml);
  928.  
  929.         return $strHtml;
  930.     }
  931.  
  932.     /**
  933.      * Returns the javascript code generated to handle this element
  934.      *
  935.      * @param boolean $raw (optional) html output with script tags or just raw data
  936.      *
  937.      * @access     public
  938.      * @return     string
  939.      * @see        setJsElement()
  940.      * @since      0.4.0
  941.      */
  942.     function getElementJs($raw = true)
  943.     {
  944.         $js = '@data_dir@' . DIRECTORY_SEPARATOR
  945.             . '@package_name@' . DIRECTORY_SEPARATOR
  946.             . 'qfamsHandler.js';
  947.  
  948.         if (file_exists($js)) {
  949.             $js = file_get_contents($js);
  950.         } else {
  951.             $js = '';
  952.         }
  953.  
  954.         if ($raw !== true) {
  955.             $js = '<script type="text/javascript">'
  956.                 . PHP_EOL . '//<![CDATA['
  957.                 . PHP_EOL . $js
  958.                 . PHP_EOL . '//]]>'
  959.                 . PHP_EOL . '</script>'
  960.                 . PHP_EOL;
  961.         }
  962.         return $js;
  963.     }
  964. }
  965.  
  966. if (class_exists('HTML_QuickForm')) {
  967.     HTML_QuickForm::registerElementType('advmultiselect',
  968.         'HTML/QuickForm/advmultiselect.php', 'HTML_QuickForm_advmultiselect');
  969. }

Documentation generated on Sat, 26 Apr 2008 14:30:06 -0400 by phpDocumentor 1.4.0. PEAR Logo Copyright © PHP Group 2004.