* @link http://www.pradosoft.com/ * @copyright Copyright © 2005-2014 PradoSoft * @license http://www.pradosoft.com/license/ * @package Prado\Web\UI\WebControls */ namespace Prado\Web\UI\WebControls; /** * Includes TListControl class */ Prado::using('System.Web.UI.WebControls.TListControl'); /** * TListBox class * * TListBox displays a list box on a Web page that allows single or multiple selection. * The list box allows multiple selections if {@link setSelectionMode SelectionMode} * is TListSelectionMode::Multiple. It takes single selection only if Single. * The property {@link setRows Rows} specifies how many rows of options are visible * at a time. See {@link TListControl} for inherited properties. * * Since v3.0.3, TListBox starts to support optgroup. To specify an option group for * a list item, set a Group attribute with it, * * $listitem->Attributes->Group="Group Name"; * // or in template * * * @author Qiang Xue * @package Prado\Web\UI\WebControls * @since 3.0 */ class TListBox extends TListControl implements IPostBackDataHandler, IValidatable { private $_dataChanged=false; private $_isValid=true; /** * Adds attribute name-value pairs to renderer. * This method overrides the parent implementation with additional list box specific attributes. * @param THtmlWriter the writer used for the rendering purpose */ protected function addAttributesToRender($writer) { $rows=$this->getRows(); $writer->addAttribute('size',"$rows"); if($this->getSelectionMode()===TListSelectionMode::Multiple) $writer->addAttribute('name',$this->getUniqueID().'[]'); else $writer->addAttribute('name',$this->getUniqueID()); parent::addAttributesToRender($writer); } /** * Gets the name of the javascript class responsible for performing postback for this control. * This method overrides the parent implementation. * @return string the javascript class name */ protected function getClientClassName() { return 'Prado.WebUI.TListBox'; } /** * Registers the list control to load post data on postback. * This method overrides the parent implementation. * @param mixed event parameter */ public function onPreRender($param) { parent::onPreRender($param); if($this->getEnabled(true)) $this->getPage()->registerRequiresPostData($this); } /** * Loads user input data. * This method is primarly used by framework developers. * @param string the key that can be used to retrieve data from the input data collection * @param array the input data collection * @return boolean whether the data of the component has been changed */ public function loadPostData($key,$values) { if(!$this->getEnabled(true)) return false; $this->ensureDataBound(); $selections=isset($values[$key])?$values[$key]:null; if($selections!==null) { $items=$this->getItems(); if($this->getSelectionMode()===TListSelectionMode::Single) { $selection=is_array($selections)?$selections[0]:$selections; $index=$items->findIndexByValue($selection,false); if($this->getSelectedIndex()!==$index) { $this->setSelectedIndex($index); return $this->_dataChanged=true; } else return false; } if(!is_array($selections)) $selections=array($selections); $list=array(); foreach($selections as $selection) $list[]=$items->findIndexByValue($selection,false); $list2=$this->getSelectedIndices(); $n=count($list); $flag=false; if($n===count($list2)) { sort($list,SORT_NUMERIC); for($i=0;$i<$n;++$i) { if($list[$i]!==$list2[$i]) { $flag=true; break; } } } else $flag=true; if($flag) { $this->setSelectedIndices($list); $this->_dataChanged=true; } return $flag; } else if($this->getSelectedIndex()!==-1) { $this->clearSelection(); return $this->_dataChanged=true; } else return false; } /** * Raises postdata changed event. * This method is required by {@link IPostBackDataHandler} interface. * It is invoked by the framework when {@link getSelectedIndices SelectedIndices} property * is changed on postback. * This method is primarly used by framework developers. */ public function raisePostDataChangedEvent() { if($this->getAutoPostBack() && $this->getCausesValidation()) $this->getPage()->validate($this->getValidationGroup()); $this->onSelectedIndexChanged(null); } /** * Returns a value indicating whether postback has caused the control data change. * This method is required by the IPostBackDataHandler interface. * @return boolean whether postback has caused the control data change. False if the page is not in postback mode. */ public function getDataChanged() { return $this->_dataChanged; } /** * @return boolean whether this control allows multiple selection */ protected function getIsMultiSelect() { return $this->getSelectionMode()===TListSelectionMode::Multiple; } /** * @return integer the number of rows to be displayed in the list control */ public function getRows() { return $this->getViewState('Rows', 4); } /** * @param integer the number of rows to be displayed in the list control */ public function setRows($value) { $value=TPropertyValue::ensureInteger($value); if($value<=0) $value=4; $this->setViewState('Rows', $value, 4); } /** * @return TListSelectionMode the selection mode (Single, Multiple). Defaults to TListSelectionMode::Single. */ public function getSelectionMode() { return $this->getViewState('SelectionMode', TListSelectionMode::Single); } /** * @param TListSelectionMode the selection mode */ public function setSelectionMode($value) { $this->setViewState('SelectionMode',TPropertyValue::ensureEnum($value,'TListSelectionMode'),TListSelectionMode::Single); } /** * Returns the value to be validated. * This methid is required by IValidatable interface. * @return mixed the value of the property to be validated. */ public function getValidationPropertyValue() { return $this->getSelectedValue(); } /** * Returns true if this control validated successfully. * Defaults to true. * @return bool wether this control validated successfully. */ public function getIsValid() { return $this->_isValid; } /** * @param bool wether this control is valid. */ public function setIsValid($value) { $this->_isValid=TPropertyValue::ensureBoolean($value); } }