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.  * It also demonstrates how to plug in element's javascript and how to use
  10.  * client-side validation with custom element.
  11.  */
  12.  
  13. require_once 'HTML/QuickForm2.php';
  14. require_once 'HTML/QuickForm2/Element/Select.php';
  15. require_once 'HTML/QuickForm2/Renderer.php';
  16. require_once 'HTML/QuickForm2/Renderer/Plugin.php';
  17.  
  18. /**
  19.  * "Dualselect" element
  20.  *
  21.  * This element can be used instead of a normal multiple select. It renders as
  22.  * two multiple selects and two buttons for moving options between them.
  23.  * The values that end up in the "to" select are considered selected.
  24.  */
  25. {
  26.     protected $attributes = array('multiple' => 'multiple');
  27.  
  28.     protected $watchedAttributes = array('id''name''multiple');
  29.  
  30.     protected function onAttributeChange($name$value = null)
  31.     {
  32.         if ('multiple' == $name && 'multiple' != $value{
  33.             throw new HTML_QuickForm2_InvalidArgumentException(
  34.                 "Required 'multiple' attribute cannot be changed"
  35.             );
  36.         }
  37.         parent::onAttributeChange($name$value);
  38.     }
  39.  
  40.     public function __toString()
  41.     {
  42.         if ($this->frozen{
  43.             return $this->getFrozenHtml();
  44.  
  45.         else {
  46.             return $this->render(
  47.                 HTML_QuickForm2_Renderer::factory('default')
  48.                     ->setTemplateForId(
  49.                         $this->getId(),
  50.                         "<table class=\"dualselect\" id=\"{id}\">\n" .
  51.                         "    <tr>\n" .
  52.                         "       <td style=\"vertical-align: top;\">{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.             $jsBuilder $renderer->getJavascriptBuilder();
  69.             $this->renderClientRules($jsBuilder);
  70.             $jsBuilder->addLibrary('dualselect''dualselect.js''js/',
  71.                                    dirname(__FILE__. DIRECTORY_SEPARATOR . 'js' . DIRECTORY_SEPARATOR);
  72.             $keepSorted = empty($this->data['keepSorted'])'false''true';
  73.             $jsBuilder->addElementJavascript("qf.elements.dualselect.init('{$this->getId()}', {$keepSorted});");
  74.             // Fall back to using the Default renderer if custom one does not have a plugin
  75.             if ($renderer->methodExists('renderDualSelect')) {
  76.                 $renderer->renderDualSelect($this);
  77.             else {
  78.                 $renderer->renderElement($this);
  79.             }
  80.         }
  81.         return $renderer;
  82.     }
  83.  
  84.     public function toArray()
  85.     {
  86.         $id    $this->getId();
  87.         $name $this->getName();
  88.  
  89.         $selectFrom = new HTML_QuickForm2_Element_Select(
  90.             "_{$name}"array('id' => "{$id}-from"$this->attributes
  91.         );
  92.         $selectTo   = new HTML_QuickForm2_Element_Select(
  93.             $namearray('id' => "{$id}-to"$this->attributes
  94.         );
  95.         $strValues array_map('strval'$this->values);
  96.         foreach ($this->optionContainer as $option{
  97.             // We don't do optgroups here
  98.             if (!is_array($option)) {
  99.                 continue;
  100.             }
  101.             $value $option['attr']['value'];
  102.             unset($option['attr']['value']);
  103.             if (in_array($value$strValuestrue)) {
  104.                 $selectTo->addOption($option['text']$value,
  105.                                      empty($option['attr'])? null: $option['attr']);
  106.             else {
  107.                 $selectFrom->addOption($option['text']$value,
  108.                                        empty($option['attr'])? null: $option['attr']);
  109.             }
  110.         }
  111.  
  112.         $buttonFromTo HTML_QuickForm2_Factory::createElement(
  113.             'button'"{$name}_fromto",
  114.             array('type' => 'button''id' => "{$id}-fromto"+
  115.                 (empty($this->data['from_to']['attributes'])? array(): self::prepareAttributes($this->data['from_to']['attributes'])),
  116.             array('content' => (empty($this->data['from_to']['content'])' &gt;&gt; '$this->data['from_to']['content']))
  117.         );
  118.         $buttonToFrom HTML_QuickForm2_Factory::createElement(
  119.             'button'"{$name}_tofrom",
  120.             array('type' => 'button''id' => "{$id}-tofrom"+
  121.                 (empty($this->data['to_from']['attributes'])? array(): self::prepareAttributes($this->data['to_from']['attributes'])),
  122.             array('content' => (empty($this->data['to_from']['content'])' &lt;&lt; '$this->data['to_from']['content']))
  123.         );
  124.         return array(
  125.             'select_from'    => $selectFrom->__toString(),   'select_to'      => $selectTo->__toString(),
  126.             'button_from_to' => $buttonFromTo->__toString()'button_to_from' => $buttonToFrom->__toString()
  127.         );
  128.     }
  129.  
  130.    /**
  131.     * Returns Javascript code for getting the element's value
  132.     *
  133.     * All options in "to" select are considered dualselect's values,
  134.     * we need to use an implementation different from that for a standard
  135.     * select-multiple. When returning a parameter for getContainerValue()
  136.     * we should also provide the element's name.
  137.     *
  138.     * @param  bool  Whether it should return a parameter for qf.form.getContainerValue()
  139.     * @return   string 
  140.     */
  141.     public function getJavascriptValue($inContainer = false)
  142.     {
  143.         if ($inContainer{
  144.             return "{name: '{$this->getName()}[]', value: qf.elements.dualselect.getValue('{$this->getId()}-to')}";
  145.         else {
  146.             return "qf.elements.dualselect.getValue('{$this->getId()}-to')";
  147.         }
  148.     }
  149.  
  150.     public function getJavascriptTriggers()
  151.     {
  152.         $id $this->getId();
  153.         return array("{$id}-from""{$id}-to""{$id}-fromto""{$id}-tofrom");
  154.     }
  155. }
  156.  
  157. /**
  158.  * Renderer plugin for outputting dualselect
  159.  *
  160.  * A plugin is needed since we want to control outputting the selects and
  161.  * buttons via the template. Also default template contains placeholders for
  162.  * two additional labels.
  163.  */
  164. {
  165.     public function setRenderer(HTML_QuickForm2_Renderer $renderer)
  166.     {
  167.         parent::setRenderer($renderer);
  168.         if (empty($this->renderer->templatesForClass['html_quickform2_element_dualselect'])) {
  169.             $this->renderer->templatesForClass['html_quickform2_element_dualselect'= <<<TPL
  170. <div class="row">
  171.     <p class="label">
  172.         <qf:required><span class="required">* </span></qf:required>
  173.         <qf:label><label for="{id}-from" class="element">{label}</label></qf:label>
  174.     </p>
  175.     <div class="element<qf:error> error</qf:error>">
  176.         <qf:error><span class="error">{error}<br /></span></qf:error>
  177.         <table class="dualselect" id="{id}">
  178.             <tr>
  179.                 <td style="vertical-align: top;">{select_from}</td>
  180.                 <td style="vertical-align: middle;">{button_from_to}<br />{button_to_from}</td>
  181.                 <td style="vertical-align: top;">{select_to}</td>
  182.             </tr>
  183.             <qf:label_2>
  184.             <qf:label_3>
  185.             <tr>
  186.                 <th>{label_2}</th>
  187.                 <th>&nbsp;</th>
  188.                 <th>{label_3}</th>
  189.             </tr>
  190.             </qf:label_3>
  191.             </qf:label_2>
  192.         </table>
  193.     </div>
  194. </div>
  195. TPL;
  196.         }
  197.     }
  198.  
  199.     public function renderDualSelect(HTML_QuickForm2_Node $element)
  200.     {
  201.         $elTpl $this->renderer->prepareTemplate($this->renderer->findTemplate($element)$element);
  202.         foreach ($element->toArray(as $k => $v{
  203.             $elTpl str_replace('{' $k '}'$v$elTpl);
  204.         }
  205.         $this->renderer->html[count($this->renderer->html- 1][str_replace('{id}'$element->getId()$elTpl);
  206.     }
  207. }
  208.  
  209. // Now we register both the element and the renderer plugin
  210. HTML_QuickForm2_Factory::registerElement('dualselect''HTML_QuickForm2_Element_DualSelect');
  211. HTML_QuickForm2_Renderer::registerPlugin('default''HTML_QuickForm2_Renderer_Default_DualSelectPlugin');
  212. ?>
  213. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  214.     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  215. <html xmlns="http://www.w3.org/1999/xhtml">
  216.   <head>
  217.     <style type="text/css">
  218. /* Set up custom font and form width */
  219. body {
  220.     margin-left: 10px;
  221.     font-family: Arial,sans-serif;
  222.     font-size: small;
  223. }
  224.  
  225. .quickform {
  226.     min-width: 700px;
  227.     max-width: 800px;
  228.     width: 760px;
  229. }
  230.  
  231. /* Use default styles included with the package */
  232.  
  233. <?php
  234. if ('@data_dir@' != '@' 'data_dir@'{
  235.     $filename '@data_dir@/HTML_QuickForm2/quickform.css';
  236. else {
  237.     $filename dirname(dirname(dirname(__FILE__))) '/data/quickform.css';
  238. }
  239. readfile($filename);
  240. ?>
  241.     </style>
  242.     <title>HTML_QuickForm2 dualselect example: custom element and renderer plugin</title>
  243. </head>
  244. <body>
  245. <?php
  246.  
  247. $options = array(
  248.       4 => "Afghanistan",                              8 => "Albania",                 12 => "Algeria",                   20 => "Andorra",                        24 => "Angola",             28 => "Antigua and Barbuda",             32 => "Argentina",             51 => "Armenia",                                       36 => "Australia",                 40 => "Austria",
  249.      31 => "Azerbaijan",                              44 => "Bahamas",                 48 => "Bahrain",                   50 => "Bangladesh",                     52 => "Barbados",          112 => "Belarus",                         56 => "Belgium",               84 => "Belize",                                       204 => "Benin",                     64 => "Bhutan",
  250.      68 => "Bolivia",                                 70 => "Bosnia and Herzegovina",  72 => "Botswana",                  76 => "Brazil",                         96 => "Brunei Darussalam"100 => "Bulgaria",                       854 => "Burkina Faso",         108 => "Burundi",                                      116 => "Cambodia",                 120 => "Cameroon",
  251.     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",
  252.     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",
  253.     214 => "Dominican Republic",                     218 => "Ecuador",                818 => "Egypt",                    222 => "El Salvador",                   226 => "Equatorial Guinea"232 => "Eritrea",                        233 => "Estonia",              231 => "Ethiopia",                                     242 => "Fiji",                     246 => "Finland",
  254.     250 => "France",                                 266 => "Gabon",                  270 => "Gambia",                   268 => "Georgia",                       276 => "Germany",           288 => "Ghana",                          300 => "Greece",               308 => "Grenada",                                      320 => "Guatemala",                324 => "Guinea",
  255.     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",
  256.     368 => "Iraq",                                   372 => "Ireland",                376 => "Israel",                   380 => "Italy",                         388 => "Jamaica",           392 => "Japan",                          400 => "Jordan",               398 => "Kazakhstan",                                   404 => "Kenya",                    296 => "Kiribati",
  257.     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",
  258.     438 => "Liechtenstein",                          440 => "Lithuania",              442 => "Luxembourg",               807 => "Macedonia",                     450 => "Madagascar",        454 => "Malawi",                         458 => "Malaysia",             462 => "Maldives",                                     466 => "Mali",                     470 => "Malta",
  259.     584 => "Marshall Islands",                       474 => "Martinique",             478 => "Mauritania",               480 => "Mauritius",                     484 => "Mexico",            583 => "Micronesia",                     498 => "Moldova",              492 => "Monaco",                                       496 => "Mongolia",                 499 => "Montenegro",
  260.     504 => "Morocco",                                508 => "Mozambique",             104 => "Myanmar",                  516 => "Namibia",                       520 => "Nauru",             524 => "Nepal",                          528 => "Netherlands",          554 => "New Zealand",                                  558 => "Nicaragua",                562 => "Niger",
  261.     566 => "Nigeria",                                570 => "Niue",                   578 => "Norway",                   512 => "Oman",                          586 => "Pakistan",          585 => "Palau",                          591 => "Panama",               598 => "Papua New Guinea",                             600 => "Paraguay",                 604 => "Peru",
  262.     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",
  263.     682 => "Saudi Arabia",                           686 => "Senegal",                688 => "Serbia",                   690 => "Seychelles",                    694 => "Sierra Leone",      702 => "Singapore",                      703 => "Slovakia",             705 => "Slovenia",                                      90 => "Solomon Islands",          706 => "Somalia",
  264.     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",
  265.     756 => "Switzerland",                            760 => "Syria",                  158 => "Taiwan",                   762 => "Tajikistan",                    834 => "Tanzania",          764 => "Thailand",                       626 => "Timor-Leste",          768 => "Togo",                                         776 => "Tonga",                    780 => "Trinidad and Tobago",
  266.     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",
  267.     860 => "Uzbekistan",                             548 => "Vanuatu",                862 => "Venezuela",                704 => "Viet Nam",                      732 => "Western Sahara",    887 => "Yemen",                          894 => "Zambia",               716 => "Zimbabwe"
  268. );
  269.  
  270. $form = new HTML_QuickForm2('dualselect');
  271. $form->addDataSource(new HTML_QuickForm2_DataSource_Array(array(
  272.     'destinations' => array(4148180368706736716)
  273. )));
  274.  
  275. $fs $form->addElement('fieldset')
  276.         ->setLabel('A custom "dualselect" element using a renderer plugin for output');
  277.  
  278. $ds $fs->addElement(
  279.     'dualselect''destinations',
  280.     array('size' => 10'style' => 'width: 215px; font-size: 90%'),
  281.     array(
  282.         'options'    => $options,
  283.         'keepSorted' => true,
  284.         'from_to'    => array('content' => ' &gt;&gt; ''attributes' => array('style' => 'font-size: 90%')),
  285.         'to_from'    => array('content' => ' &lt&lt; ''attributes' => array('style' => 'font-size: 90%')),
  286.     )
  287. )->setLabel(array(
  288.     'Popular travel destinations:',
  289.     'Available',
  290.     'Chosen'
  291. ));
  292.  
  293. $ds->addRule('required''Select at least two destinations'2,
  294.              HTML_QuickForm2_Rule::ONBLUR_CLIENT_SERVER);
  295.  
  296. $fs->addElement('checkbox''doFreeze'nullarray('content' => 'Freeze dualselect on form submit'));
  297.  
  298. $fs->addElement('submit''testSubmit'array('value' => 'Submit form'));
  299.  
  300. // outputting form values
  301. if ('POST' == $_SERVER['REQUEST_METHOD']{
  302.     $value $form->getValue();
  303.     echo "<pre>\n";
  304.     var_dump($value);
  305.     echo "</pre>\n<hr />";
  306.  
  307.     if (!empty($value['doFreeze'])) {
  308.         $ds->toggleFrozen(true);
  309.     }
  310. }
  311.  
  312. $renderer HTML_QuickForm2_Renderer::factory('default');
  313.  
  314. $form->render($renderer);
  315. echo $renderer->getJavascriptBuilder()->getLibraries(truetrue);
  316. echo $renderer;
  317. ?>
  318. </body>
  319. </html>

Documentation generated on Wed, 10 Apr 2019 08:56:08 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.