| [ Index ] |
|
Code source de phpMyVisites 2.3 |
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 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Mon Nov 26 14:10:01 2007 | par Balluche grâce à PHPXref 0.7 |
|