[ Index ]
 

Code source de phpMyVisites 2.3

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/libs/Html/QuickForm/ -> hierselect.php (source)

   1  <?php
   2  /* vim: set expandtab tabstop=4 shiftwidth=4: */
   3  // +----------------------------------------------------------------------+
   4  // | PHP version 4.0                                                      |
   5  // +----------------------------------------------------------------------+
   6  // | Copyright (c) 1997-2004 The PHP Group                                |
   7  // +----------------------------------------------------------------------+
   8  // | This source file is subject to version 2.0 of the PHP license,       |
   9  // | that is bundled with this package in the file LICENSE, and is        |
  10  // | available at through the world-wide-web at                           |
  11  // | http://www.php.net/license/2_02.txt.                                 |
  12  // | If you did not receive a copy of the PHP license and are unable to   |
  13  // | obtain it through the world-wide-web, please send a note to          |
  14  // | license@php.net so we can mail you a copy immediately.               |
  15  // +----------------------------------------------------------------------+
  16  // | Authors: Herim Vasquez <vasquezh@iro.umontreal.ca>                   |
  17  // |          Bertrand Mansion <bmansion@mamasam.com>                     |
  18  // |          Alexey Borzov <avb@php.net>
  19  // +----------------------------------------------------------------------+
  20  //
  21  // $Id: hierselect.php,v 1.1 2005/12/06 01:50:39 matthieu_ Exp $
  22  
  23  require_once('Html/QuickForm/group.php');
  24  require_once('Html/QuickForm/select.php');
  25  
  26  /**
  27   * Class to dynamically create two or more HTML Select elements
  28   * The first select changes the content of the second select and so on.
  29   * This element is considered as a group. Selects will be named
  30   * groupName[0], groupName[1], groupName[2]...
  31   *
  32   * @author       Herim Vasquez <vasquezh@iro.umontreal.ca>
  33   * @author       Bertrand Mansion <bmansion@mamasam.com>
  34   * @version      1.0
  35   * @since        PHP4.04pl1
  36   * @access       public
  37   */
  38  class HTML_QuickForm_hierselect extends HTML_QuickForm_group
  39  {   
  40      // {{{ properties
  41  
  42      /**
  43       * Options for all the select elements
  44       *
  45       * Format is a bit more complex as we need to know which options
  46       * are related to the ones in the previous select:
  47       *
  48       * Ex:
  49       * // first select
  50       * $select1[0] = 'Pop';
  51       * $select1[1] = 'Classical';
  52       * $select1[2] = 'Funeral doom';
  53       *
  54       * // second select
  55       * $select2[0][0] = 'Red Hot Chil Peppers';
  56       * $select2[0][1] = 'The Pixies';
  57       * $select2[1][0] = 'Wagner';
  58       * $select2[1][1] = 'Strauss';
  59       * $select2[2][0] = 'Pantheist';
  60       * $select2[2][1] = 'Skepticism';
  61       *
  62       * // If only need two selects 
  63       * //     - and using the depracated functions
  64       * $sel =& $form->addElement('hierselect', 'cds', 'Choose CD:');
  65       * $sel->setMainOptions($select1);
  66       * $sel->setSecOptions($select2);
  67       *
  68       * //     - and using the new setOptions function
  69       * $sel =& $form->addElement('hierselect', 'cds', 'Choose CD:');
  70       * $sel->setOptions(array($select1, $select2));
  71       *
  72       * // If you have a third select with prices for the cds
  73       * $select3[0][0][0] = '15.00$';
  74       * $select3[0][0][1] = '17.00$';
  75       * etc
  76       *
  77       * // You can now use
  78       * $sel =& $form->addElement('hierselect', 'cds', 'Choose CD:');
  79       * $sel->setOptions(array($select1, $select2, $select3));
  80       * 
  81       * @var       array
  82       * @access    private
  83       */
  84      var $_options = array();
  85      
  86      /**
  87       * Number of select elements on this group
  88       *
  89       * @var       int
  90       * @access    private
  91       */
  92      var $_nbElements = 0;
  93  
  94      /**
  95       * The javascript used to set and change the options
  96       *
  97       * @var       string
  98       * @access    private
  99       */
 100      var $_js = '';
 101  
 102      // }}}
 103      // {{{ constructor
 104  
 105      /**
 106       * Class constructor
 107       * 
 108       * @param     string    $elementName    (optional)Input field name attribute
 109       * @param     string    $elementLabel   (optional)Input field label in form
 110       * @param     mixed     $attributes     (optional)Either a typical HTML attribute string 
 111       *                                      or an associative array. Date format is passed along the attributes.
 112       * @param     mixed     $separator      (optional)Use a string for one separator,
 113       *                                      use an array to alternate the separators.
 114       * @access    public
 115       * @return    void
 116       */
 117      function HTML_QuickForm_hierselect($elementName=null, $elementLabel=null, $attributes=null, $separator=null)
 118      {
 119          $this->HTML_QuickForm_element($elementName, $elementLabel, $attributes);
 120          $this->_persistantFreeze = true;
 121          if (isset($separator)) {
 122              $this->_separator = $separator;
 123          }
 124          $this->_type = 'hierselect';
 125          $this->_appendName = true;
 126      } //end constructor
 127  
 128      // }}}
 129      // {{{ setOptions()
 130  
 131      /**
 132       * Initialize the array structure containing the options for each select element.
 133       * Call the functions that actually do the magic.
 134       *
 135       * @param     array    $options    Array of options defining each element
 136       *
 137       * @access    public
 138       * @return    void
 139       */
 140      function setOptions($options)
 141      {
 142          $this->_options = $options;
 143  
 144          if (empty($this->_elements)) {
 145              $this->_nbElements = count($this->_options);
 146              $this->_createElements();
 147          } else {
 148              // setDefaults has probably been called before this function
 149              // check if all elements have been created
 150              $totalNbElements = count($this->_options);
 151              for ($i = $this->_nbElements; $i < $totalNbElements; $i ++) {
 152                  $this->_elements[] =& new HTML_QuickForm_select($i, null, array(), $this->getAttributes());
 153                  $this->_nbElements++;
 154              }
 155          }
 156          
 157          $this->_setOptions();
 158      } // end func setMainOptions
 159  
 160      // }}}
 161      // {{{ setMainOptions()
 162      
 163      /**
 164       * Sets the options for the first select element. Deprecated. setOptions() should be used.
 165       *
 166       * @param     array     $array    Options for the first select element
 167       *
 168       * @access    public
 169       * @return    void
 170       */
 171      function setMainOptions($array)
 172      {
 173          $this->_options[0] = $array;
 174  
 175          if (empty($this->_elements)) {
 176              $this->_nbElements = 2;
 177              $this->_createElements();
 178          }
 179      } // end func setMainOptions
 180      
 181      // }}}
 182      // {{{ setSecOptions()
 183      
 184      /**
 185       * Sets the options for the second select element. Deprecated. setOptions() should be used.
 186       * The main _options array is initialized and the _setOptions function is called.
 187       *
 188       * @param     array     $array    Options for the second select element
 189       *
 190       * @access    public
 191       * @return    void
 192       */
 193      function setSecOptions($array)
 194      {
 195          $this->_options[1] = $array;
 196  
 197          if (empty($this->_elements)) {
 198              $this->_nbElements = 2;
 199              $this->_createElements();
 200          } else {
 201              // setDefaults has probably been called before this function
 202              // check if all elements have been created
 203              $totalNbElements = 2;
 204              for ($i = $this->_nbElements; $i < $totalNbElements; $i ++) {
 205                  $this->_elements[] =& new HTML_QuickForm_select($i, null, array(), $this->getAttributes());
 206                  $this->_nbElements++;
 207              }
 208          }
 209          
 210          $this->_setOptions();
 211      } // end func setSecOptions
 212      
 213      // }}}
 214      // {{{ _setOptions()
 215      
 216      /**
 217       * Sets the options for each select element
 218       *
 219       * @access    private
 220       * @return    void
 221       */
 222      function _setOptions()
 223      {
 224          $toLoad = '';
 225          foreach (array_keys($this->_elements) AS $key) {
 226              $array = eval("return isset(\$this->_options[{$key}]{$toLoad})? \$this->_options[{$key}]{$toLoad}: null;");
 227              if (is_array($array)) {
 228                  $select =& $this->_elements[$key];
 229                  $select->_options = array();
 230                  $select->loadArray($array);
 231  
 232                  $value  = is_array($v = $select->getValue()) ? $v[0] : key($array);
 233                  $toLoad .= '[\'' . str_replace(array('\\', '\''), array('\\\\', '\\\''), $value) . '\']';
 234              }
 235          }
 236      } // end func _setOptions
 237      
 238      // }}}
 239      // {{{ setValue()
 240  
 241      /**
 242       * Sets values for group's elements
 243       * 
 244       * @param     array     $value    An array of 2 or more values, for the first,
 245       *                                the second, the third etc. select
 246       *
 247       * @access    public
 248       * @return    void
 249       */
 250      function setValue($value)
 251      {
 252          $this->_nbElements = count($value);
 253          parent::setValue($value);
 254          $this->_setOptions();
 255      } // end func setValue
 256      
 257      // }}}
 258      // {{{ _createElements()
 259  
 260      /**
 261       * Creates all the elements for the group
 262       * 
 263       * @access    private
 264       * @return    void
 265       */
 266      function _createElements()
 267      {
 268          for ($i = 0; $i < $this->_nbElements; $i++) {
 269              $this->_elements[] =& new HTML_QuickForm_select($i, null, array(), $this->getAttributes());
 270          }
 271      } // end func _createElements
 272  
 273      // }}}
 274      // {{{ toHtml()
 275  
 276      function toHtml()
 277      {
 278          $this->_js = '';
 279          if (!$this->_flagFrozen) {
 280              // set the onchange attribute for each element except last
 281              $keys     = array_keys($this->_elements);
 282              $onChange = array();
 283              for ($i = 0; $i < count($keys) - 1; $i++) {
 284                  $select =& $this->_elements[$keys[$i]];
 285                  $onChange[$i] = $select->getAttribute('onchange');
 286                  $select->updateAttributes(
 287                      array('onchange' => '_hs_swapOptions(this.form, \'' . $this->_escapeString($this->getName()) . '\', ' . $keys[$i] . ');' . $onChange[$i])
 288                  );
 289              }
 290              
 291              // create the js function to call
 292              if (!defined('HTML_QUICKFORM_HIERSELECT_EXISTS')) {
 293                  $this->_js .= <<<JAVASCRIPT
 294  function _hs_findOptions(ary, keys)
 295  {
 296      var key = keys.shift();
 297      if (!key in ary) {
 298          return {};
 299      } else if (0 == keys.length) {
 300          return ary[key];
 301      } else {
 302          return _hs_findOptions(ary[key], keys);
 303      }
 304  }
 305  
 306  function _hs_findSelect(form, groupName, selectIndex)
 307  {
 308      if (groupName+'['+ selectIndex +']' in form) {
 309          return form[groupName+'['+ selectIndex +']']; 
 310      } else {
 311          return form[groupName+'['+ selectIndex +'][]']; 
 312      }
 313  }
 314  
 315  function _hs_replaceOptions(ctl, optionList)
 316  {
 317      var j = 0;
 318      ctl.options.length = 0;
 319      for (i in optionList) {
 320          ctl.options[j++] = new Option(optionList[i], i, false, false);
 321      }
 322  }
 323  
 324  function _hs_setValue(ctl, value)
 325  {
 326      var testValue = {};
 327      if (value instanceof Array) {
 328          for (var i = 0; i < value.length; i++) {
 329              testValue[value[i]] = true;
 330          }
 331      } else {
 332          testValue[value] = true;
 333      }
 334      for (var i = 0; i < ctl.options.length; i++) {
 335          if (ctl.options[i].value in testValue) {
 336              ctl.options[i].selected = true;
 337          }
 338      }
 339  }
 340  
 341  function _hs_swapOptions(form, groupName, selectIndex)
 342  {
 343      var hsValue = [];
 344      for (var i = 0; i <= selectIndex; i++) {
 345          hsValue[i] = _hs_findSelect(form, groupName, i).value;
 346      }
 347  
 348      _hs_replaceOptions(_hs_findSelect(form, groupName, selectIndex + 1), 
 349                         _hs_findOptions(_hs_options[groupName][selectIndex], hsValue));
 350      if (selectIndex + 1 < _hs_options[groupName].length) {
 351          _hs_swapOptions(form, groupName, selectIndex + 1);
 352      }
 353  }
 354  
 355  function _hs_onReset(form, groupNames)
 356  {
 357      for (var i = 0; i < groupNames.length; i++) {
 358          try {
 359              for (var j = 0; j <= _hs_options[groupNames[i]].length; j++) {
 360                  _hs_setValue(_hs_findSelect(form, groupNames[i], j), _hs_defaults[groupNames[i]][j]);
 361                  if (j < _hs_options[groupNames[i]].length) {
 362                      _hs_replaceOptions(_hs_findSelect(form, groupNames[i], j + 1), 
 363                                         _hs_findOptions(_hs_options[groupNames[i]][j], _hs_defaults[groupNames[i]].slice(0, j + 1)));
 364                  }
 365              }
 366          } catch (e) {
 367              if (!(e instanceof TypeError)) {
 368                  throw e;
 369              }
 370          }
 371      }
 372  }
 373  
 374  function _hs_setupOnReset(form, groupNames)
 375  {
 376      setTimeout(function() { _hs_onReset(form, groupNames); }, 25);
 377  }
 378  
 379  function _hs_onReload()
 380  {
 381      var ctl;
 382      for (var i = 0; i < document.forms.length; i++) {
 383          for (var j in _hs_defaults) {
 384              if (ctl = _hs_findSelect(document.forms[i], j, 0)) {
 385                  for (var k = 0; k < _hs_defaults[j].length; k++) {
 386                      _hs_setValue(_hs_findSelect(document.forms[i], j, k), _hs_defaults[j][k]);
 387                  }
 388              }
 389          }
 390      }
 391  
 392      if (_hs_prevOnload) {
 393          _hs_prevOnload();
 394      }
 395  }
 396  
 397  var _hs_prevOnload = null;
 398  if (window.onload) {
 399      _hs_prevOnload = window.onload;
 400  }
 401  window.onload = _hs_onReload;
 402  
 403  var _hs_options = {};
 404  var _hs_defaults = {};
 405  
 406  JAVASCRIPT;
 407                  define('HTML_QUICKFORM_HIERSELECT_EXISTS', true);
 408              }
 409              // option lists
 410              $jsParts = array();
 411              for ($i = 1; $i < $this->_nbElements; $i++) {
 412                  $jsParts[] = $this->_convertArrayToJavascript($this->_options[$i]);
 413              }
 414              $this->_js .= "\n_hs_options['" . $this->_escapeString($this->getName()) . "'] = [\n" .
 415                            implode(",\n", $jsParts) .
 416                            "\n];\n";
 417              // default value; if we don't actually have any values yet just use
 418              // the first option (for single selects) or empty array (for multiple)
 419              $values = array();
 420              foreach (array_keys($this->_elements) as $key) {
 421                  if (is_array($v = $this->_elements[$key]->getValue())) {
 422                      $values[] = count($v) > 1? $v: $v[0];
 423                  } else {
 424                      // XXX: accessing the supposedly private _options array
 425                      $values[] = $this->_elements[$key]->getMultiple() || empty($this->_elements[$key]->_options[0])?
 426                                  array():
 427                                  $this->_elements[$key]->_options[0]['attr']['value'];
 428                  }
 429              }
 430              $this->_js .= "_hs_defaults['" . $this->_escapeString($this->getName()) . "'] = " .
 431                            $this->_convertArrayToJavascript($values, false) . ";\n";
 432          }
 433          include_once('Html/QuickForm/Renderer/Default.php');
 434          $renderer =& new HTML_QuickForm_Renderer_Default();
 435          $renderer->setElementTemplate('{element}');
 436          parent::accept($renderer);
 437  
 438          if (!empty($onChange)) {
 439              $keys     = array_keys($this->_elements);
 440              for ($i = 0; $i < count($keys) - 1; $i++) {
 441                  $this->_elements[$keys[$i]]->updateAttributes(array('onchange' => $onChange[$i]));
 442              }
 443          }
 444          return (empty($this->_js)? '': "<script type=\"text/javascript\">\n//<![CDATA[\n" . $this->_js . "//]]>\n</script>") .
 445                 $renderer->toHtml();
 446      } // end func toHtml
 447  
 448      // }}}
 449      // {{{ accept()
 450  
 451      function accept(&$renderer, $required = false, $error = null)
 452      {
 453          $renderer->renderElement($this, $required, $error);
 454      } // end func accept
 455  
 456      // }}}
 457      // {{{ onQuickFormEvent()
 458  
 459      function onQuickFormEvent($event, $arg, &$caller)
 460      {
 461          if ('updateValue' == $event) {
 462              // we need to call setValue() so that the secondary option
 463              // matches the main option
 464              return HTML_QuickForm_element::onQuickFormEvent($event, $arg, $caller);
 465          } else {
 466              $ret = parent::onQuickFormEvent($event, $arg, $caller);
 467              // add onreset handler to form to properly reset hierselect (see bug #2970)
 468              if ('addElement' == $event) {
 469                  $onReset = $caller->getAttribute('onreset');
 470                  if (strlen($onReset)) {
 471                      if (strpos($onReset, '_hs_setupOnReset')) {
 472                          $caller->updateAttributes(array('onreset' => str_replace('_hs_setupOnReset(this, [', "_hs_setupOnReset(this, ['" . $this->_escapeString($this->getName()) . "', ", $onReset)));
 473                      } else {
 474                          $caller->updateAttributes(array('onreset' => "var temp = function() { {$onReset} } ; if (!temp()) { return false; } ; if (typeof _hs_setupOnReset != 'undefined') { return _hs_setupOnReset(this, ['" . $this->_escapeString($this->getName()) . "']); } "));
 475                      }
 476                  } else {
 477                      $caller->updateAttributes(array('onreset' => "if (typeof _hs_setupOnReset != 'undefined') { return _hs_setupOnReset(this, ['" . $this->_escapeString($this->getName()) . "']); } "));
 478                  }
 479              }
 480              return $ret;
 481          }
 482      } // end func onQuickFormEvent
 483  
 484      // }}}
 485      // {{{ _convertArrayToJavascript()
 486  
 487     /**
 488      * Converts PHP array to its Javascript analog
 489      *
 490      * @access private
 491      * @param  array     PHP array to convert
 492      * @param  bool      Generate Javascript object literal (default, works like PHP's associative array) or array literal
 493      * @return string    Javascript representation of the value
 494      */
 495      function _convertArrayToJavascript($array, $assoc = true)
 496      {
 497          if (!is_array($array)) {
 498              return $this->_convertScalarToJavascript($array);
 499          } else {
 500              $items = array();
 501              foreach ($array as $key => $val) {
 502                  $item = $assoc? "'" . $this->_escapeString($key) . "': ": '';
 503                  if (is_array($val)) {
 504                      $item .= $this->_convertArrayToJavascript($val, $assoc);
 505                  } else {
 506                      $item .= $this->_convertScalarToJavascript($val);
 507                  }
 508                  $items[] = $item;
 509              }
 510          }
 511          $js = implode(', ', $items);
 512          return $assoc? '{ ' . $js . ' }': '[' . $js . ']';
 513      }
 514      
 515      // }}}
 516      // {{{ _convertScalarToJavascript()
 517  
 518     /**
 519      * Converts PHP's scalar value to its Javascript analog
 520      *
 521      * @access private
 522      * @param  mixed     PHP value to convert
 523      * @return string    Javascript representation of the value
 524      */
 525      function _convertScalarToJavascript($val)
 526      {
 527          if (is_bool($val)) {
 528              return $val ? 'true' : 'false';
 529          } elseif (is_int($val) || is_double($val)) {
 530              return $val;
 531          } elseif (is_string($val)) {
 532              return "'" . $this->_escapeString($val) . "'";
 533          } elseif (is_null($val)) {
 534              return 'null';
 535          } else {
 536              // don't bother
 537              return '{}';
 538          }
 539      }
 540  
 541      // }}}
 542      // {{{ _escapeString()
 543  
 544     /**
 545      * Quotes the string so that it can be used in Javascript string constants   
 546      *
 547      * @access private
 548      * @param  string
 549      * @return string
 550      */
 551      function _escapeString($str)
 552      {
 553          return strtr($str,array(
 554              "\r"    => '\r',
 555              "\n"    => '\n',
 556              "\t"    => '\t',
 557              "'"     => "\\'",
 558              '"'     => '\"',
 559              '\\'    => '\\\\'
 560          ));
 561      }
 562  
 563      // }}}
 564  } // end class HTML_QuickForm_hierselect
 565  ?>


Généré le : Mon Nov 26 14:10:01 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics