* @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);
}
}