2 /* vim: set expandtab tabstop=4 shiftwidth=4: */
3 // +----------------------------------------------------------------------+
5 // +----------------------------------------------------------------------+
6 // | Copyright (c) 1997-2003 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: Adam Daniel <adaniel1@eesus.jnj.com> |
17 // | Bertrand Mansion <bmansion@mamasam.com> |
18 // +----------------------------------------------------------------------+
22 require_once('HTML/QuickForm/element.php');
25 * Class to dynamically create an HTML SELECT
27 * @author Adam Daniel <adaniel1@eesus.jnj.com>
28 * @author Bertrand Mansion <bmansion@mamasam.com>
33 class HTML_QuickForm_select
extends HTML_QuickForm_element
{
38 * Contains the select options
44 var $_options = array();
47 * Default values of the SELECT
61 * @param string Select name attribute
62 * @param mixed Label(s) for the select
63 * @param mixed Data to be used to populate options
64 * @param mixed Either a typical HTML attribute string or an associative array
69 function HTML_QuickForm_select($elementName=null, $elementLabel=null, $options=null, $attributes=null)
71 HTML_QuickForm_element
::HTML_QuickForm_element($elementName, $elementLabel, $attributes);
72 $this->_persistantFreeze
= true;
73 $this->_type
= 'select';
74 if (isset($options)) {
75 $this->load($options);
83 * Returns the current API version
92 } //end func apiVersion
98 * Sets the default values of the select box
100 * @param mixed $values Array or comma delimited string of selected values
105 function setSelected($values)
107 if (is_string($values) && $this->getMultiple()) {
108 $values = split("[ ]?,[ ]?", $values);
110 if (is_array($values)) {
111 $this->_values
= array_values($values);
113 $this->_values
= array($values);
115 } //end func setSelected
121 * Returns an array of the selected values
125 * @return array of selected values
127 function getSelected()
129 return $this->_values
;
130 } // end func getSelected
136 * Sets the input field name
138 * @param string $name Input field name attribute
143 function setName($name)
145 $this->updateAttributes(array('name' => $name));
152 * Returns the element name
160 return $this->getAttribute('name');
164 // {{{ getPrivateName()
167 * Returns the element name (possibly with brackets appended)
173 function getPrivateName()
175 if ($this->getAttribute('multiple')) {
176 return $this->getName() . '[]';
178 return $this->getName();
180 } //end func getPrivateName
186 * Sets the value of the form element
188 * @param mixed $values Array or comma delimited string of selected values
193 function setValue($value)
195 $this->setSelected($value);
196 } // end func setValue
202 * Returns an array of the selected values
206 * @return array of selected values
210 return $this->_values
;
211 } // end func getValue
217 * Sets the select field size, only applies to 'multiple' selects
219 * @param int $size Size of select field
224 function setSize($size)
226 $this->updateAttributes(array('size' => $size));
233 * Returns the select field size
241 return $this->getAttribute('size');
248 * Sets the select mutiple attribute
250 * @param bool $multiple Whether the select supports multi-selections
255 function setMultiple($multiple)
258 $this->updateAttributes(array('multiple' => 'multiple'));
260 $this->removeAttribute('multiple');
262 } //end func setMultiple
268 * Returns the select mutiple attribute
272 * @return bool true if multiple select, false otherwise
274 function getMultiple()
276 return (bool)$this->getAttribute('multiple');
277 } //end func getMultiple
283 * Adds a new OPTION to the SELECT
285 * @param string $text Display text for the OPTION
286 * @param string $value Value for the OPTION
287 * @param mixed $attributes Either a typical HTML attribute string
288 * or an associative array
293 function addOption($text, $value, $attributes=null)
295 if (null === $attributes) {
296 $attributes = array('value' => $value);
298 $attributes = $this->_parseAttributes($attributes);
299 if (isset($attributes['selected'])) {
300 // the 'selected' attribute will be set in toHtml()
301 $this->_removeAttr('selected', $attributes);
302 if (is_null($this->_values
)) {
303 $this->_values
= array($value);
304 } elseif (!in_array($value, $this->_values
)) {
305 $this->_values
[] = $value;
308 $this->_updateAttrArray($attributes, array('value' => $value));
310 $this->_options
[] = array('text' => $text, 'attr' => $attributes);
311 } // end func addOption
317 * Loads the options from an associative array
319 * @param array $arr Associative array of options
320 * @param mixed $values (optional) Array or comma delimited string of selected values
323 * @return PEAR_Error on error or true
326 function loadArray($arr, $values=null)
328 if (!is_array($arr)) {
329 return PEAR
::raiseError('Argument 1 of HTML_Select::loadArray is not a valid array');
331 if (isset($values)) {
332 $this->setSelected($values);
334 foreach ($arr as $key => $val) {
335 // Warning: new API since release 2.3
336 $this->addOption($val, $key);
339 } // end func loadArray
342 // {{{ loadDbResult()
345 * Loads the options from DB_result object
347 * If no column names are specified the first two columns of the result are
348 * used as the text and value columns respectively
349 * @param object $result DB_result object
350 * @param string $textCol (optional) Name of column to display as the OPTION text
351 * @param string $valueCol (optional) Name of column to use as the OPTION value
352 * @param mixed $values (optional) Array or comma delimited string of selected values
355 * @return PEAR_Error on error or true
358 function loadDbResult(&$result, $textCol=null, $valueCol=null, $values=null)
360 if (!is_object($result) ||
!is_a($result, 'db_result')) {
361 return PEAR
::raiseError('Argument 1 of HTML_Select::loadDbResult is not a valid DB_result');
363 if (isset($values)) {
364 $this->setValue($values);
366 $fetchMode = ($textCol && $valueCol) ? DB_FETCHMODE_ASSOC
: DB_FETCHMODE_ORDERED
;
367 while (is_array($row = $result->fetchRow($fetchMode)) ) {
368 if ($fetchMode == DB_FETCHMODE_ASSOC
) {
369 $this->addOption($row[$textCol], $row[$valueCol]);
371 $this->addOption($row[0], $row[1]);
375 } // end func loadDbResult
381 * Queries a database and loads the options from the results
383 * @param mixed $conn Either an existing DB connection or a valid dsn
384 * @param string $sql SQL query string
385 * @param string $textCol (optional) Name of column to display as the OPTION text
386 * @param string $valueCol (optional) Name of column to use as the OPTION value
387 * @param mixed $values (optional) Array or comma delimited string of selected values
393 function loadQuery(&$conn, $sql, $textCol=null, $valueCol=null, $values=null)
395 if (is_string($conn)) {
396 require_once('DB.php');
397 $dbConn = &DB
::connect($conn, true);
398 if (DB
::isError($dbConn)) {
401 } elseif (is_subclass_of($conn, "db_common")) {
404 return PEAR
::raiseError('Argument 1 of HTML_Select::loadQuery is not a valid type');
406 $result = $dbConn->query($sql);
407 if (DB
::isError($result)) {
410 $this->loadDbResult($result, $textCol, $valueCol, $values);
412 if (is_string($conn)) {
413 $dbConn->disconnect();
416 } // end func loadQuery
422 * Loads options from different types of data sources
424 * This method is a simulated overloaded method. The arguments, other than the
425 * first are optional and only mean something depending on the type of the first argument.
426 * If the first argument is an array then all arguments are passed in order to loadArray.
427 * If the first argument is a db_result then all arguments are passed in order to loadDbResult.
428 * If the first argument is a string or a DB connection then all arguments are
429 * passed in order to loadQuery.
430 * @param mixed $options Options source currently supports assoc array or DB_result
431 * @param mixed $param1 (optional) See function detail
432 * @param mixed $param2 (optional) See function detail
433 * @param mixed $param3 (optional) See function detail
434 * @param mixed $param4 (optional) See function detail
437 * @return PEAR_Error on error or true
440 function load(&$options, $param1=null, $param2=null, $param3=null, $param4=null)
443 case is_array($options):
444 return $this->loadArray($options, $param1);
446 case (is_a($options, 'db_result')):
447 return $this->loadDbResult($options, $param1, $param2, $param3);
449 case (is_string($options) && !empty($options) ||
is_subclass_of($options, "db_common")):
450 return $this->loadQuery($options, $param1, $param2, $param3, $param4);
459 * Returns the SELECT in HTML
467 if ($this->_flagFrozen
) {
468 return $this->getFrozenHtml();
470 $tabs = $this->_getTabs();
473 if ($this->getComment() != '') {
474 $strHtml .= $tabs . '<!-- ' . $this->getComment() . " //-->\n";
477 if (!$this->getMultiple()) {
478 $attrString = $this->_getAttrString($this->_attributes
);
480 $myName = $this->getName();
481 $this->setName($myName . '[]');
482 $attrString = $this->_getAttrString($this->_attributes
);
483 $this->setName($myName);
485 $strHtml .= $tabs . '<select' . $attrString . ">\n";
487 foreach ($this->_options
as $option) {
488 if (is_array($this->_values
) && in_array((string)$option['attr']['value'], $this->_values
)) {
489 $this->_updateAttrArray($option['attr'], array('selected' => 'selected'));
491 $strHtml .= $tabs . "\t<option" . $this->_getAttrString($option['attr']) . '>' .
492 $option['text'] . "</option>\n";
495 return $strHtml . $tabs . '</select>';
500 // {{{ getFrozenHtml()
503 * Returns the value of field without HTML tags
509 function getFrozenHtml()
512 if (is_array($this->_values
)) {
513 foreach ($this->_values
as $key => $val) {
514 for ($i = 0, $optCount = count($this->_options
); $i < $optCount; $i++
) {
515 if ((string)$val == (string)$this->_options
[$i]['attr']['value']) {
516 $value[$key] = $this->_options
[$i]['text'];
522 $html = empty($value)?
' ': join('<br />', $value);
523 if ($this->_persistantFreeze
) {
524 $name = $this->getPrivateName();
525 // Only use id attribute if doing single hidden input
526 if (1 == count($value)) {
527 $id = $this->getAttribute('id');
528 $idAttr = isset($id)?
array('id' => $id): array();
532 foreach ($value as $key => $item) {
533 $html .= '<input' . $this->_getAttrString(array(
536 'value' => $this->_values
[$key]
537 ) +
$idAttr) . ' />';
541 } //end func getFrozenHtml
547 * We check the options and return only the values that _could_ have been
548 * selected. We also return a scalar value if select is not "multiple"
550 function exportValue(&$submitValues, $assoc = false)
552 $value = $this->_findValue($submitValues);
553 if (is_null($value)) {
554 $value = $this->getValue();
555 } elseif(!is_array($value)) {
556 $value = array($value);
558 if (is_array($value) && !empty($this->_options
)) {
560 foreach ($value as $v) {
561 for ($i = 0, $optCount = count($this->_options
); $i < $optCount; $i++
) {
562 if ($v == $this->_options
[$i]['attr']['value']) {
569 $cleanValue = $value;
571 if (is_array($cleanValue) && !$this->getMultiple()) {
572 return $this->_prepareValue($cleanValue[0], $assoc);
574 return $this->_prepareValue($cleanValue, $assoc);
579 // {{{ onQuickFormEvent()
581 function onQuickFormEvent($event, $arg, &$caller)
583 if ('updateValue' == $event) {
584 $value = $this->_findValue($caller->_constantValues
);
585 if (null === $value) {
586 $value = $this->_findValue($caller->_submitValues
);
587 // Fix for bug #4465 & #5269
588 // XXX: should we push this to element::onQuickFormEvent()?
589 if (null === $value && (!$caller->isSubmitted() ||
!$this->getMultiple())) {
590 $value = $this->_findValue($caller->_defaultValues
);
593 if (null !== $value) {
594 $this->setValue($value);
598 return parent
::onQuickFormEvent($event, $arg, $caller);
603 } //end class HTML_QuickForm_select