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

Source for file dualselect.php

Documentation is available at dualselect.php

  1. <?php
  2. /*
  3.  * Usage example for HTML_QuickForm2 package: custom element and renderer plugin
  4.  *
  5.  * The example demonstrates a custom element with special rendering needs and
  6.  * shows how it can be output via a renderer plugin. The example element is
  7.  * a (much) simpler version of HTML_QuickForm_advmultiselect.
  8.  *
  9.  * $Id: dualselect.php 289051 2009-10-01 14:41:53Z avb $
  10.  */
  11.  
  12. require_once 'HTML/QuickForm2.php';
  13. require_once 'HTML/QuickForm2/Element/Select.php';
  14. require_once 'HTML/QuickForm2/Renderer.php';
  15. require_once 'HTML/QuickForm2/Renderer/Plugin.php';
  16.  
  17. /**
  18.  * "Dualselect" element
  19.  *
  20.  * This element can be used instead of a normal multiple select. It renders as
  21.  * two multiple selects and two buttons for moving options between them.
  22.  * The values that end up in the "to" select are considered selected.
  23.  */
  24. {
  25.     protected $attributes = array('multiple' => 'multiple');
  26.  
  27.     protected $watchedAttributes = array('id''name''multiple');
  28.  
  29.     protected function onAttributeChange($name$value = null)
  30.     {
  31.         if ('multiple' == $name && 'multiple' != $value{
  32.             throw new HTML_QuickForm2_InvalidArgumentException(
  33.                 "Required 'multiple' attribute cannot be changed"
  34.             );
  35.         }
  36.         parent::onAttributeChange($name$value);
  37.     }
  38.  
  39.     public function __toString()
  40.     {
  41.         if ($this->frozen{
  42.             return $this->getFrozenHtml();
  43.         else {
  44.             require_once 'HTML/QuickForm2/Renderer.php';
  45.  
  46.             return $this->render(
  47.                 HTML_QuickForm2_Renderer::factory('default')
  48.                     ->setTemplateForId(
  49.                         $this->getId(),
  50.                         "<table class=\"dualselect\">\n" .
  51.                         "    <tr>\n" .
  52.                         "       <td style=\"vertical-align: top;\">{js}{select_from}</td>\n" .
  53.                         "       <td style=\"vertical-align: middle;\">{button_from_to}<br />{button_to_from}</td>\n" .
  54.                         "       <td style=\"vertical-align: top;\">{select_to}</td>\n" .
  55.                         "    </tr>\n" .
  56.                         "</table>"
  57.                     )
  58.             )->__toString();
  59.         }
  60.     }
  61.  
  62.     public function render(HTML_QuickForm2_Renderer $renderer)
  63.     {
  64.         // render as a normal select when frozen
  65.         if ($this->frozen{
  66.             $renderer->renderElement($this);
  67.         else {
  68.             $renderer->renderDualSelect($this);
  69.         }
  70.         return $renderer;
  71.     }
  72.  
  73.     public function toArray()
  74.     {
  75.         $id    $this->getId();
  76.         $name $this->getName();
  77.  
  78.         $selectFrom = new HTML_QuickForm2_Element_Select(
  79.             "_{$name}"array('id' => "{$id}-from"$this->attributes
  80.         );
  81.         $selectTo   = new HTML_QuickForm2_Element_Select(
  82.             $namearray('id' => "{$id}-to"$this->attributes
  83.         );
  84.         $strValues array_map('strval'$this->values);
  85.         foreach ($this->optionContainer as $option{
  86.             // We don't do optgroups here
  87.             if (!is_array($option)) {
  88.                 continue;
  89.             }
  90.             $value $option['attr']['value'];
  91.             unset($option['attr']['value']);
  92.             if (in_array($value$strValuestrue)) {
  93.                 $selectTo->addOption($option['text']$value,
  94.                                      empty($option['attr'])? null: $option['attr']);
  95.             else {
  96.                 $selectFrom->addOption($option['text']$value,
  97.                                        empty($option['attr'])? null: $option['attr']);
  98.             }
  99.         }
  100.  
  101.         $keepSorted = empty($this->data['keepSorted'])'false''true';
  102.         $buttonFromTo HTML_QuickForm2_Factory::createElement(
  103.             'button'"{$name}_fromto",
  104.             array('type' => 'button''onclick' => "qf.moveOptions('{$id}-from', '{$id}-to', {$keepSorted})"+
  105.                 (empty($this->data['from_to']['attributes'])? array(): self::prepareAttributes($this->data['from_to']['attributes'])),
  106.             array('content' => (empty($this->data['from_to']['content'])' >> '$this->data['from_to']['content']))
  107.         );
  108.         $buttonToFrom HTML_QuickForm2_Factory::createElement(
  109.             'button'"{$name}_tofrom",
  110.             array('type' => 'button''onclick' => "qf.moveOptions('{$id}-to', '{$id}-from', {$keepSorted})"+
  111.                 (empty($this->data['to_from']['attributes'])? array(): self::prepareAttributes($this->data['to_from']['attributes'])),
  112.             array('content' => (empty($this->data['to_from']['content'])' << '$this->data['to_from']['content']))
  113.         );
  114.         return array(
  115.             'select_from'    => $selectFrom->__toString(),   'select_to'      => $selectTo->__toString(),
  116.             'button_from_to' => $buttonFromTo->__toString()'button_to_from' => $buttonToFrom->__toString(),
  117.             'js'             => "<script type=\"text/javascript\">qf.dualselects['{$id}-to'] = true;</script>"
  118.         );
  119.     }
  120. }
  121.  
  122. /**
  123.  * Renderer plugin for outputting dualselect
  124.  *
  125.  * A plugin is needed since we want to control outputting the selects and
  126.  * buttons via the template. Also default template contains placeholders for
  127.  * two additional labels.
  128.  */
  129. {
  130.     public function setRenderer(HTML_QuickForm2_Renderer $renderer)
  131.     {
  132.         parent::setRenderer($renderer);
  133.         if (empty($this->renderer->templatesForClass['html_quickform2_element_dualselect'])) {
  134.             $this->renderer->templatesForClass['html_quickform2_element_dualselect'= <<<TPL
  135. <div class="row">
  136.     <label for="{id}-from" class="element"><qf:required><span class="required">* </span></qf:required>{label}</label>
  137.     <div class="element<qf:error> error</qf:error>">
  138.         {js}
  139.         <qf:error><span class="error">{error}</span><br /></qf:error>
  140.         <table class="dualselect">
  141.             <tr>
  142.                 <td style="vertical-align: top;">{select_from}</td>
  143.                 <td style="vertical-align: middle;">{button_from_to}<br />{button_to_from}</td>
  144.                 <td style="vertical-align: top;">{select_to}</td>
  145.             </tr>
  146.             <qf:label_2>
  147.             <qf:label_3>
  148.             <tr>
  149.                 <th>{label_2}</th>
  150.                 <th>&nbsp;</th>
  151.                 <th>{label_3}</th>
  152.             </tr>
  153.             </qf:label_3>
  154.             </qf:label_2>
  155.         </table>
  156.     </div>
  157. </div>
  158. TPL;
  159.         }
  160.     }
  161.  
  162.     public function renderDualSelect(HTML_QuickForm2_Node $element)
  163.     {
  164.         $elTpl $this->renderer->prepareTemplate($this->renderer->findTemplate($element)$element);
  165.         foreach ($element->toArray(as $k => $v{
  166.             $elTpl str_replace('{' $k '}'$v$elTpl);
  167.         }
  168.         $this->renderer->html[count($this->renderer->html- 1][str_replace('{id}'$element->getId()$elTpl);
  169.     }
  170. }
  171.  
  172. // Now we register both the element and the renderer plugin
  173. HTML_QuickForm2_Factory::registerElement('dualselect''HTML_QuickForm2_Element_DualSelect');
  174. HTML_QuickForm2_Renderer::registerPlugin('default''HTML_QuickForm2_Renderer_Default_DualSelectPlugin');
  175. ?>
  176. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  177.     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  178. <html>
  179.   <head>
  180.     <style type="text/css">
  181. /* Set up custom font and form width */
  182. body {
  183.     margin-left: 10px;
  184.     font-family: Arial,sans-serif;
  185.     font-size: small;
  186. }
  187.  
  188. .quickform {
  189.     min-width: 700px;
  190.     max-width: 800px;
  191.     width: 760px;
  192. }
  193.  
  194. /* Use default styles included with the package */
  195.  
  196. <?php
  197. if ('@data_dir@' != '@' 'data_dir@'{
  198.     $filename '@data_dir@/HTML_QuickForm2/data/quickform.css';
  199. else {
  200.     $filename dirname(dirname(dirname(__FILE__))) '/data/quickform.css';
  201. }
  202. readfile($filename);
  203. ?>
  204.     </style>
  205.     <script type="text/javascript">
  206. // <![CDATA[
  207. /**
  208.  * Javascript for dualselect element handling
  209.  *
  210.  * Contains methods for moving options between selects and also for selecting
  211.  * all options of 'to' select on form submit. This is necessary since
  212.  * unselected options obviously won't send any values.
  213.  */
  214.  
  215. var qf = {
  216.     dualselects: {}
  217. };
  218.  
  219. qf.moveOptions = function(srcId, destId, keepSorted) {
  220.     var src  = document.getElementById(srcId);
  221.     var dest = document.getElementById(destId);
  222.  
  223.     for (var i = src.options.length - 1; i >= 0; i--) {
  224.         if (src.options[i].selected) {
  225.             var option = src.options[i];
  226.             src.remove(i);
  227.             option.selected = false;
  228.             qf.addOption(dest, option, keepSorted);
  229.         }
  230.     }
  231. };
  232.  
  233. qf.addOption = function(box, option, keepSorted) {
  234.     /*@cc_on
  235.     return qf.addOptionIE(box, option, keepSorted);
  236.     @*/
  237.     return qf.addOptionDOM(box, option, keepSorted);
  238. };
  239.  
  240. qf.addOptionIE = function(box, option, keepSorted) {
  241.     if (box.options.length <= 0 || (keepSorted && option.text < box.options[0].text))  {
  242.         box.add(option, 0);
  243.  
  244.     } else if (!keepSorted || (option.text > box.options[box.options.length - 1].text)) {
  245.         box.add(option);
  246.  
  247.     } else {
  248.         for (var i = box.options.length; i >= 0; i--) {
  249.             if (option.text >= box.options[i-1].text) {
  250.                 box.add(option, i);
  251.                 break;
  252.             }
  253.         }
  254.     }
  255.     return true;
  256. };
  257.  
  258. qf.addOptionDOM = function(box, option, keepSorted) {
  259.     if (!keepSorted || 0 == box.options.length ||
  260.         option.text > box.options[box.options.length-1].text
  261.     ) {
  262.         box.add(option, null);
  263.  
  264.     } else if (option.text < box.options[0].text) {
  265.         box.add(option, box.options[0]);
  266.  
  267.     } else {
  268.         for (var i = box.options.length - 1; i >= 0; i--) {
  269.             if (option.text >= box.options[i].text) {
  270.                 box.add(option, box.options[i + 1]);
  271.                 break;
  272.             }
  273.         }
  274.     }
  275.     return true;
  276. };
  277.  
  278. qf.selectAll = function(event) {
  279.     for (var i in qf.dualselects) {
  280.         var select = document.getElementById(i);
  281.         for (var j = 0; j < select.options.length; j++) {
  282.             select.options[j].selected = true;
  283.         }
  284.     }
  285. };
  286.  
  287. qf.addOnSubmitHandler = function() {
  288.     var forms = document.getElementsByTagName('form');
  289.     for (var i = 0; i < forms.length; i++) {
  290.         if (forms[i].addEventListener) {
  291.             forms[i].addEventListener('submit', qf.selectAll, false);
  292.         } else if (forms[i].attachEvent) {
  293.             forms[i].attachEvent('onsubmit', qf.selectAll);
  294.         }
  295.     }
  296. };
  297.  
  298. window.onload = qf.addOnSubmitHandler;
  299. // ]]>
  300.     </script>
  301.     <title>HTML_QuickForm2 dualselect example: custom element and renderer plugin</title>
  302. </head>
  303. <body>
  304. <?php
  305.  
  306. $options = array(
  307.       4 => "Afghanistan",                              8 => "Albania",                 12 => "Algeria",                   20 => "Andorra",                        24 => "Angola",             28 => "Antigua and Barbuda",             32 => "Argentina",             51 => "Armenia",                                       36 => "Australia",                 40 => "Austria",
  308.      31 => "Azerbaijan",                              44 => "Bahamas",                 48 => "Bahrain",                   50 => "Bangladesh",                     52 => "Barbados",          112 => "Belarus",                         56 => "Belgium",               84 => "Belize",                                       204 => "Benin",                     64 => "Bhutan",
  309.      68 => "Bolivia",                                 70 => "Bosnia and Herzegovina",  72 => "Botswana",                  76 => "Brazil",                         96 => "Brunei Darussalam"100 => "Bulgaria",                       854 => "Burkina Faso",         108 => "Burundi",                                      116 => "Cambodia",                 120 => "Cameroon",
  310.     124 => "Canada",                                 132 => "Cape Verde",             140 => "Central African Republic"148 => "Chad",                          152 => "Chile",             156 => "China",                          170 => "Colombia",             174 => "Comoros",                                      178 => "Congo",                    180 => "Congo, Democratic Republic of",
  311.     184 => "Cook Islands",                           188 => "Costa Rica",             384 => "Cote D'Ivoire",            191 => "Croatia",                       192 => "Cuba",              196 => "Cyprus",                         203 => "Czech Republic",       208 => "Denmark",                                      262 => "Djibouti",                 212 => "Dominica",
  312.     214 => "Dominican Republic",                     218 => "Ecuador",                818 => "Egypt",                    222 => "El Salvador",                   226 => "Equatorial Guinea"232 => "Eritrea",                        233 => "Estonia",              231 => "Ethiopia",                                     242 => "Fiji",                     246 => "Finland",
  313.     250 => "France",                                 266 => "Gabon",                  270 => "Gambia",                   268 => "Georgia",                       276 => "Germany",           288 => "Ghana",                          300 => "Greece",               308 => "Grenada",                                      320 => "Guatemala",                324 => "Guinea",
  314.     624 => "Guinea-Bissau",                          328 => "Guyana",                 332 => "Haiti",                    336 => "Holy See (Vatican City State)"340 => "Honduras",          348 => "Hungary",                        352 => "Iceland",              356 => "India",                                        360 => "Indonesia",                364 => "Iran",
  315.     368 => "Iraq",                                   372 => "Ireland",                376 => "Israel",                   380 => "Italy",                         388 => "Jamaica",           392 => "Japan",                          400 => "Jordan",               398 => "Kazakhstan",                                   404 => "Kenya",                    296 => "Kiribati",
  316.     408 => "Korea, Democratic People's Republic of"410 => "Korea, Republic of",     414 => "Kuwait",                   417 => "Kyrgyz Republic",               418 => "Laos",              428 => "Latvia",                         422 => "Lebanon",              426 => "Lesotho",                                      430 => "Liberia",                  434 => "Libya",
  317.     438 => "Liechtenstein",                          440 => "Lithuania",              442 => "Luxembourg",               807 => "Macedonia",                     450 => "Madagascar",        454 => "Malawi",                         458 => "Malaysia",             462 => "Maldives",                                     466 => "Mali",                     470 => "Malta",
  318.     584 => "Marshall Islands",                       474 => "Martinique",             478 => "Mauritania",               480 => "Mauritius",                     484 => "Mexico",            583 => "Micronesia",                     498 => "Moldova",              492 => "Monaco",                                       496 => "Mongolia",                 499 => "Montenegro",
  319.     504 => "Morocco",                                508 => "Mozambique",             104 => "Myanmar",                  516 => "Namibia",                       520 => "Nauru",             524 => "Nepal",                          528 => "Netherlands",          554 => "New Zealand",                                  558 => "Nicaragua",                562 => "Niger",
  320.     566 => "Nigeria",                                570 => "Niue",                   578 => "Norway",                   512 => "Oman",                          586 => "Pakistan",          585 => "Palau",                          591 => "Panama",               598 => "Papua New Guinea",                             600 => "Paraguay",                 604 => "Peru",
  321.     608 => "Philippines",                            616 => "Poland",                 620 => "Portugal",                 634 => "Qatar",                         642 => "Romania",           643 => "Russian Federation",             646 => "Rwanda",               882 => "Samoa",                                        674 => "San Marino",               678 => "Sao Tome and Principe",
  322.     682 => "Saudi Arabia",                           686 => "Senegal",                688 => "Serbia",                   690 => "Seychelles",                    694 => "Sierra Leone",      702 => "Singapore",                      703 => "Slovakia",             705 => "Slovenia",                                      90 => "Solomon Islands",          706 => "Somalia",
  323.     710 => "South Africa",                           724 => "Spain",                  144 => "Sri Lanka",                659 => "St. Kitts and Nevis",           662 => "St. Lucia",         670 => "St. Vincent and the Grenadines"736 => "Sudan",                740 => "Suriname",                                     748 => "Swaziland",                752 => "Sweden",
  324.     756 => "Switzerland",                            760 => "Syria",                  158 => "Taiwan",                   762 => "Tajikistan",                    834 => "Tanzania",          764 => "Thailand",                       626 => "Timor-Leste",          768 => "Togo",                                         776 => "Tonga",                    780 => "Trinidad and Tobago",
  325.     788 => "Tunisia",                                792 => "Turkey",                 795 => "Turkmenistan",             798 => "Tuvalu",                        800 => "Uganda",            804 => "Ukraine",                        784 => "United Arab Emirates"826 => "United Kingdom of Great Britain & N. Ireland"840 => "United States of America"858 => "Uruguay",
  326.     860 => "Uzbekistan",                             548 => "Vanuatu",                862 => "Venezuela",                704 => "Viet Nam",                      732 => "Western Sahara",    887 => "Yemen",                          894 => "Zambia",               716 => "Zimbabwe"
  327. );
  328.  
  329. $form = new HTML_QuickForm2('dualselect');
  330. $form->addDataSource(new HTML_QuickForm2_DataSource_Array(array(
  331.     'destinations' => array(4148180368706736716)
  332. )));
  333.  
  334. $fs $form->addElement('fieldset')
  335.         ->setLabel('A custom "dualselect" element using a renderer plugin for output');
  336.  
  337. $ds $fs->addElement(
  338.     'dualselect''destinations',
  339.     array('size' => 10'style' => 'width: 225px; font-size: 90%'),
  340.     array(
  341.         'options'    => $options,
  342.         'keepSorted' => true,
  343.         'from_to'    => array('content' => ' >> ''attributes' => array('style' => 'font-size: 90%')),
  344.         'to_from'    => array('content' => ' << ''attributes' => array('style' => 'font-size: 90%')),
  345.     )
  346. )->setLabel(array(
  347.     'Popular travel destinations:',
  348.     'Available',
  349.     'Chosen'
  350. ));
  351.  
  352. $fs->addElement('checkbox''doFreeze'nullarray('content' => 'Freeze dualselect on form submit'));
  353.  
  354. $fs->addElement('submit''testSubmit'array('value' => 'Submit form'));
  355.  
  356. // outputting form values
  357. if ('POST' == $_SERVER['REQUEST_METHOD']{
  358.     $value $form->getValue();
  359.     echo "<pre>\n";
  360.     var_dump($value);
  361.     echo "</pre>\n<hr />";
  362.  
  363.     if (!empty($value['doFreeze'])) {
  364.         $ds->toggleFrozen(true);
  365.     }
  366. }
  367.  
  368. echo $form;
  369. ?>
  370. </body>
  371. </html>

Documentation generated on Mon, 11 Mar 2019 15:34:59 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.