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/TDataBoundControl.php | 260 +++++++++++++++++++++ 1 file changed, 260 insertions(+) create mode 100644 framework/Web/UI/WebControls/TDataBoundControl.php (limited to 'framework/Web/UI/WebControls/TDataBoundControl.php') 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 -- cgit v1.2.3