From 3751bed4e3b40adb98949b85b47daf2cfaac29db Mon Sep 17 00:00:00 2001 From: xue <> Date: Wed, 14 Dec 2005 18:52:04 +0000 Subject: Added TDataBoundControl, TDropDownList and TListBox. Note, they're not done yet. --- framework/Web/UI/WebControls/TCheckBox.php | 2 - framework/Web/UI/WebControls/TDataBoundControl.php | 260 +++++++++++++++++++++ framework/Web/UI/WebControls/TDropDownList.php | 42 ++++ framework/Web/UI/WebControls/TListBox.php | 86 +++++++ 4 files changed, 388 insertions(+), 2 deletions(-) create mode 100644 framework/Web/UI/WebControls/TDataBoundControl.php create mode 100644 framework/Web/UI/WebControls/TDropDownList.php create mode 100644 framework/Web/UI/WebControls/TListBox.php (limited to 'framework/Web') diff --git a/framework/Web/UI/WebControls/TCheckBox.php b/framework/Web/UI/WebControls/TCheckBox.php index 2f51d8f5..72d15822 100644 --- a/framework/Web/UI/WebControls/TCheckBox.php +++ b/framework/Web/UI/WebControls/TCheckBox.php @@ -102,8 +102,6 @@ class TCheckBox extends TWebControl implements IPostBackDataHandler, IValidatabl * This is necessary because a checkbox if unchecked, when postback, * does not have direct mapping between post data and the checkbox name. * - * Auto-postback javascript code is also registered here. - * * This method overrides the parent implementation and is invoked before render. * @param mixed event parameter */ diff --git a/framework/Web/UI/WebControls/TDataBoundControl.php b/framework/Web/UI/WebControls/TDataBoundControl.php new file mode 100644 index 00000000..032370f7 --- /dev/null +++ b/framework/Web/UI/WebControls/TDataBoundControl.php @@ -0,0 +1,260 @@ +_dataSource; + } + + /** + * @param Traversable|array|string data source object + */ + public function setDataSource($value) + { + if($value!==null) + $this->validateDataSource($value); + $this->_dataSource=$value; + $this->onDataPropertyChanged(); + } + + /** + * @return string ID path to the data source control. Defaults to empty. + */ + public function getDataSourceID() + { + return $this->getViewState('DataSourceID',''); + } + + /** + * @param string ID path to the data source control. The data source + * control must be locatable via {@link TControl::findControl} call. + */ + public function setDataSourceID($value) + { + $dsid=$this->getViewState('DataSourceID',''); + if($dsid!=='' && $value==='') + $this->_requiresBindToNull=true; + $this->setViewState('DataSourceID',$value,''); + $this->onDataPropertyChanged(); + } + + /** + * This method is invoked when either {@link setDataSource} or {@link setDataSourceID} is changed. + */ + protected function onDataPropertyChanged() + { + if($this->_throwOnDataPropertyChanged) + throw new TInvalidOperationException('databoundcontrol_dataproperty_unchangeable'); + if($this->getInitialized()) + $this->setRequiresDataBinding(true); + } + + /** + * @return boolean whether the databound control has been initialized. + */ + protected function getInitialized() + { + return $this->_initialized; + } + + /** + * @param boolean a value indicating whether the databound control is initialized. + */ + protected function setInitialized($value) + { + $this->_initialized=TPropertyValue::ensureBoolean($value); + } + + /** + * @return boolean if the databound control uses the data source control specified + * by {@link setDataSourceID}, or it uses the data source object specified + * by {@link setDataSource}. + */ + protected function getUsingDataSourceID() + { + return $this->getDataSourceID()!==''; + } + + /** + * @return boolean whether a databind call is required (by the data bound control) + */ + protected function getRequiresDataBinding() + { + return $this->_requiresDataBinding; + } + + /** + * Sets a value indicating whether a databind call is required by the data bound control. + * If true and the control has been prerendered while it uses the data source + * specified by {@link setDataSourceID}, a databind call will be called by this method. + * @param boolean whether a databind call is required. + */ + protected function setRequiresDataBinding($value) + { + $value=TPropertyValue::ensureBoolean($value); + if($value && $this->_prerendered && $this->getUsingDataSourceID()) + { + $this->_requiresDataBinding=true; + $this->ensureDataBound(); + } + else + $this->_requiresDataBinding=$value; + } + + /** + * Performs databinding. + * This method overrides the parent implementation by calling + * {@link performSelect} which fetches data from data source and does + * the actual binding work. + * @param boolean whether to raise DataBind event. This parameter is ignored. + */ + public function dataBind($raiseDataBindingEvent=true) + { + $this->performSelect(); + } + + /** + * Ensures any pending {@link dataBind} is called. + * This method calls {@link dataBind} if the data source is specified + * by {@link setDataSourceID} or if {@link getRequiresDataBinding RequiresDataBinding} + * is true. + */ + protected function ensureDataBound() + { + try + { + $this->_throwOnDataPropertyChange=true; + if($this->_requiresDataBinding && ($this->getUsingDataSourceID() || $this->_requiresBindToNull)) + { + $this->dataBind(); + $this->_requiresBindToNull=false; + } + } + catch(Exception $e) + { + $this->_throwOnDataPropertyChange=false; + throw $e; + } + } + + /** + * Raises DataBound event. + * This method should be invoked after a databind is performed. + * It is mainly used by framework and component developers. + */ + public function onDataBound($param) + { + $this->raiseEvent('DataBound',$this,$param); + } + + /** + * Sets page's PreLoad event handler as {@link onPagePreLoad}. + * If viewstate is disabled and the current request is a postback, + * {@link setRequiresDataBinding RequiresDataBinding} will be set true. + * This method overrides the parent implementation. + * @param TEventParameter event parameter + */ + protected function onInit($param) + { + parent::onInit($param); + $page=$this->getPage(); + $page->attachEventHandler('PreLoad',array($this,'onPagePreLoad')); + if(!$this->getEnableViewState(true) && $page->getIsPostBack()) + $this->setRequiresDataBinding(true); + } + + /** + * Sets {@link getInitialized} as true. + * This method is invoked when page raises PreLoad event. + * @param mixed event sender + * @param TEventParameter event parameter + */ + protected function onPagePreLoad($sender,$param) + { + $this->_initialized=true; + } + + /** + * Ensures any pending databind is performed. + * This method overrides the parent implementation. + * @param TEventParameter event parameter + */ + protected function onPreRender($param) + { + $this->_prerendered=true; + $this->ensureDataBound(); + parent::onPreRender($param); + } + + /** + * Validates if the parameter is a valid data source. + * @return boolean if the parameter is a valid data source + */ + protected function validateDataSource($value) + { + if(!is_array($value) && !($value instanceof Traversable)) + throw new TInvalidDataTypeException('databoundcontrol_datasource_invalid'); + } + + /** + * @return ??? + */ + protected function performSelect() + { + if(!$this->getUsingDataSourceID()) + $this->onDataBinding(null); + $view=$this->getDataSourceView(); + $this->setRequiresDataBinding(false); + $this->setDataBound(true); + $data=$view->select($this->getSelectParameters()); + if($this->getUsingDataSourceID()) + $this->onDataBinding(null); + $this->performDataBinding($data); + $this->onDataBound(null); + } + + protected function getDataSourceView() + { + $source=$this->getDataSourceByID(); + return $source->getView($this->getDataMember()); + } + + protected function performDataBinding($data) + { + } + + public function getDataMember() + { + return $this->getViewState('DataMember',''); + } + + public function setDataMember($value) + { + $this->setViewState('DataMember',$value,''); + } + + public function getSelectParameters() + { + if(!$this->_parameters) + $this->_parameters=$this->createSelectParameters(); + return $this->_parameters; + } + + protected function createSelectParameters() + { + return new TDataSourceSelectParameters; + } +} + +?> \ No newline at end of file diff --git a/framework/Web/UI/WebControls/TDropDownList.php b/framework/Web/UI/WebControls/TDropDownList.php new file mode 100644 index 00000000..07549c6c --- /dev/null +++ b/framework/Web/UI/WebControls/TDropDownList.php @@ -0,0 +1,42 @@ +addAttribute('name',$this->getUniqueID()); + parent::addAttributesToRender($writer); + } + + public function loadPostData($key,$values) + { + if(!$this->getEnabled(true)) + return false; + // ensure DataBound??? + } + + public function raisePostDataChangedEvent() + { + $page=$this->getPage(); + if($this->getAutoPostBack() && !$page->getPostBackEventTarget()) + { + $page->setPostBackEventTarget($this); + if($this->getCausesValidation()) + $page->validate($this->getValidationGroup()); + } + $this->onSelectedIndexChanged(null); + } + + public function getSelectedIndex() + { + $index=parent::getSelectedIndex(); + if($index<0 && $this->getItems()->getCount()>0) + { + $this->setSelectedIndex(0); + return 0; + } + else + return $index; + } +} +?> \ No newline at end of file diff --git a/framework/Web/UI/WebControls/TListBox.php b/framework/Web/UI/WebControls/TListBox.php new file mode 100644 index 00000000..79afc133 --- /dev/null +++ b/framework/Web/UI/WebControls/TListBox.php @@ -0,0 +1,86 @@ +getRows(); + $writer->addAttribute('size',"$rows"); + $writer->addAttribute('name',$this->getUniqueID()); + parent::addAttributesToRender($writer); + } + + protected function onPreRender($param) + { + parent::onPreRender($param); + if($this->getSelectionMode()==='Multiple' && $this->getEnabled(true)) + $this->getPage()->registerRequiresPostData($this); + } + + public function loadPostData($key,$values) + { + if(!$this->getEnabled(true)) + return false; + // ensure DataBound??? + } + + public function raisePostDataChangedEvent() + { + $page=$this->getPage(); + if($this->getAutoPostBack() && !$page->getPostBackEventTarget()) + { + $page->setPostBackEventTarget($this); + if($this->getCausesValidation()) + $page->validate($this->getValidationGroup()); + } + $this->onSelectedIndexChanged(null); + } + + protected function getIsMultiSelect() + { + return $this->getSelectionMode()==='Multiple'; + } + + public function getSelectedIndices() + { + return parent::getSelectedIndices(); + } + + /** + * @return integer the number of rows to be displayed in the component + */ + public function getRows() + { + return $this->getViewState('Rows', 4); + } + + /** + * Sets the number of rows to be displayed in the component + * @param integer the number of rows + */ + public function setRows($value) + { + $value=TPropertyValue::ensureInteger($value); + if($value<=0) + $value=4; + $this->setViewState('Rows', $value, 4); + } + + /** + * @return string the selection mode (Single, Multiple ) + */ + public function getSelectionMode() + { + return $this->getViewState('SelectionMode', 'Single'); + } + + /** + * Sets the selection mode of the component (Single, Multiple) + * @param string the selection mode + */ + function setSelectionMode($value) + { + $this->setViewState('SelectionMode',TPropertyValue::ensureEnum($value,array('Single','Multiple')),'Single'); + } +} +?> \ No newline at end of file -- cgit v1.2.3