Blame | Letzte Änderung | Log anzeigen | RSS feed
<?php/*** TTabPanel class file.** @author Tomasz Wolny <tomasz.wolny@polecam.to.pl> and Qiang Xue <qiang.xue@gmail.com>* @link http://www.pradosoft.com/* @copyright Copyright © 2005-2008 PradoSoft* @license http://www.pradosoft.com/license/* @version $Id: TTabPanel.php 2501 2008-08-18 23:00:14Z knut $* @package System.Web.UI.WebControls* @since 3.1.1*//*** Class TTabPanel.** TTabPanel displays a tabbed panel. Users can click on the tab bar to switching among* different tab views. Each tab view is an independent panel that can contain arbitrary content.** A TTabPanel control consists of one or several {@link TTabView} controls representing the possible* tab views. At any time, only one tab view is visible (active), which is specified by any of* the following properties:* - {@link setActiveViewIndex ActiveViewIndex} - the zero-based integer index of the view in the view collection.* - {@link setActiveViewID ActiveViewID} - the text ID of the visible view.* - {@link setActiveView ActiveView} - the visible view instance.* If both {@link setActiveViewIndex ActiveViewIndex} and {@link setActiveViewID ActiveViewID}* are set, the latter takes precedence.** TTabPanel uses CSS to specify the appearance of the tab bar and panel. By default,* an embedded CSS file will be published which contains the default CSS for TTabPanel.* You may also use your own CSS file by specifying the {@link setCssUrl CssUrl} property.* The following properties specify the CSS classes used for elements in a TTabPanel:* - {@link setCssClass CssClass} - the CSS class name for the outer-most div element (defaults to 'tab-panel');* - {@link setTabCssClass TabCssClass} - the CSS class name for nonactive tab div elements (defaults to 'tab-normal');* - {@link setActiveTabCssClass ActiveTabCssClass} - the CSS class name for the active tab div element (defaults to 'tab-active');* - {@link setViewCssClass ViewCssClass} - the CSS class for the div element enclosing view content (defaults to 'tab-view');** To use TTabPanel, write a template like following:* <code>* <com:TTabPanel>* <com:TTabView Caption="View 1">* content for view 1* </com:TTabView>* <com:TTabView Caption="View 2">* content for view 2* </com:TTabView>* <com:TTabView Caption="View 3">* content for view 3* </com:TTabView>* </com:TTabPanel>* </code>** @author Tomasz Wolny <tomasz.wolny@polecam.to.pl> and Qiang Xue <qiang.xue@gmail.com>* @version $Id: TTabPanel.php 2501 2008-08-18 23:00:14Z knut $* @since 3.1.1*/class TTabPanel extends TWebControl implements IPostBackDataHandler{private $_dataChanged=false;/*** @return string tag name for the control*/protected function getTagName(){return 'div';}/*** Adds object parsed from template to the control.* This method adds only {@link TTabView} objects into the {@link getViews Views} collection.* All other objects are ignored.* @param mixed object parsed from template*/public function addParsedObject($object){if($object instanceof TTabView)$this->getControls()->add($object);}/*** Returns the index of the active tab view.* Note, this property may not return the correct index.* To ensure the correctness, call {@link getActiveView()} first.* @return integer the zero-based index of the active tab view. If -1, it means no active tab view. Default is 0 (the first view is active).*/public function getActiveViewIndex(){return $this->getViewState('ActiveViewIndex',0);}/*** @param integer the zero-based index of the current view in the view collection. -1 if no active view.* @throws TInvalidDataValueException if the view index is invalid*/public function setActiveViewIndex($value){$this->setViewState('ActiveViewIndex',TPropertyValue::ensureInteger($value),0);}/*** Returns the ID of the active tab view.* Note, this property may not return the correct ID.* To ensure the correctness, call {@link getActiveView()} first.* @return string The ID of the active tab view. Defaults to '', meaning not set.*/public function getActiveViewID(){return $this->getViewState('ActiveViewID','');}/*** @param string The ID of the active tab view.*/public function setActiveViewID($value){$this->setViewState('ActiveViewID',$value,'');}/*** Returns the currently active view.* This method will examin the ActiveViewID, ActiveViewIndex and Views collection to* determine which view is currently active. It will update ActiveViewID and ActiveViewIndex accordingly.* @return TTabView the currently active view, null if no active view* @throws TInvalidDataValueException if the active view ID or index set previously is invalid*/public function getActiveView(){$activeView=null;$views=$this->getViews();if(($id=$this->getActiveViewID())!==''){if(($index=$views->findIndexByID($id))>=0)$activeView=$views->itemAt($index);elsethrow new TInvalidDataValueException('tabpanel_activeviewid_invalid',$id);}else if(($index=$this->getActiveViewIndex())>=0){if($index<$views->getCount())$activeView=$views->itemAt($index);elsethrow new TInvalidDataValueException('tabpanel_activeviewindex_invalid',$index);}else{foreach($views as $index=>$view){if($view->getActive()){$activeView=$view;break;}}}if($activeView!==null)$this->activateView($activeView);return $activeView;}/*** @param TTabView the view to be activated* @throws TInvalidOperationException if the view is not in the view collection*/public function setActiveView($view){if($this->getViews()->indexOf($view)>=0)$this->activateView($view);elsethrow new TInvalidOperationException('tabpanel_view_inexistent');}/*** @return string URL for the CSS file including all relevant CSS class definitions. Defaults to ''.*/public function getCssUrl(){return $this->getViewState('CssUrl','default');}/*** @param string URL for the CSS file including all relevant CSS class definitions.*/public function setCssUrl($value){$this->setViewState('CssUrl',TPropertyValue::ensureString($value),'');}/*** @return string CSS class for the whole tab control div. Defaults to 'tab-panel'.*/public function getCssClass(){$cssClass=parent::getCssClass();return $cssClass===''?'tab-panel':$cssClass;}/*** @return string CSS class for the currently displayed view div. Defaults to 'tab-view'.*/public function getViewCssClass(){return $this->getViewStyle()->getCssClass();}/*** @param string CSS class for the currently displayed view div.*/public function setViewCssClass($value){$this->getViewStyle()->setCssClass($value);}/*** @return TStyle the style for all the view div*/public function getViewStyle(){if(($style=$this->getViewState('ViewStyle',null))===null){$style=new TStyle;$style->setCssClass('tab-view');$this->setViewState('ViewStyle',$style,null);}return $style;}/*** @return string CSS class for non-active tabs. Defaults to 'tab-normal'.*/public function getTabCssClass(){return $this->getTabStyle()->getCssClass();}/*** @param string CSS class for non-active tabs.*/public function setTabCssClass($value){$this->getTabStyle()->setCssClass($value);}/*** @return TStyle the style for all the inactive tab div*/public function getTabStyle(){if(($style=$this->getViewState('TabStyle',null))===null){$style=new TStyle;$style->setCssClass('tab-normal');$this->setViewState('TabStyle',$style,null);}return $style;}/*** @return string CSS class for the active tab. Defaults to 'tab-active'.*/public function getActiveTabCssClass(){return $this->getActiveTabStyle()->getCssClass();}/*** @param string CSS class for the active tab.*/public function setActiveTabCssClass($value){$this->getActiveTabStyle()->setCssClass($value);}/*** @return TStyle the style for the active tab div*/public function getActiveTabStyle(){if(($style=$this->getViewState('ActiveTabStyle',null))===null){$style=new TStyle;$style->setCssClass('tab-active');$this->setViewState('ActiveTabStyle',$style,null);}return $style;}/*** Activates the specified view.* If there is any other view currently active, it will be deactivated.* @param TTabView the view to be activated. If null, all views will be deactivated.*/protected function activateView($view){$this->setActiveViewIndex(-1);$this->setActiveViewID('');foreach($this->getViews() as $index=>$v){if($view===$v){$this->setActiveViewIndex($index);$this->setActiveViewID($view->getID(false));$view->setActive(true);}else$v->setActive(false);}}/*** 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 control has been changed*/public function loadPostData($key,$values){if(($index=$values[$this->getClientID().'_1'])!==null){$index=(int)$index;$currentIndex=$this->getActiveViewIndex();if($currentIndex!==$index){$this->setActiveViewID(''); // clear up view ID$this->setActiveViewIndex($index);return $this->_dataChanged=true;}}return false;}/*** Raises postdata changed event.* This method is required by {@link IPostBackDataHandler} interface.* It is invoked by the framework when {@link getActiveViewIndex ActiveViewIndex} property* is changed on postback.* This method is primarly used by framework developers.*/public function raisePostDataChangedEvent(){// do nothing}/*** 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;}/*** Adds attributes to renderer.* @param THtmlWriter the renderer*/protected function addAttributesToRender($writer){$writer->addAttribute('id',$this->getClientID());$this->setCssClass($this->getCssClass());parent::addAttributesToRender($writer);}/*** Registers CSS and JS.* This method is invoked right before the control rendering, if the control is visible.* @param mixed event parameter*/public function onPreRender($param){parent::onPreRender($param);$this->getActiveView(); // determine the active view$this->registerStyleSheet();$this->registerClientScript();}/*** Registers the CSS relevant to the TTabControl.* It will register the CSS file specified by {@link getCssUrl CssUrl}.* If that is not set, it will use the default CSS.*/protected function registerStyleSheet(){$url = $this->getCssUrl();if($url === '') {return;}if($url === 'default') {$url = $this->getApplication()->getAssetManager()->publishFilePath(dirname(__FILE__).DIRECTORY_SEPARATOR.'assets'.DIRECTORY_SEPARATOR.'tabpanel.css');}if($url !== '') {$this->getPage()->getClientScript()->registerStyleSheetFile($url, $url);}}/*** Registers the relevant JavaScript.*/protected function registerClientScript(){$id=$this->getClientID();$options=TJavaScript::encode($this->getClientOptions());$className=$this->getClientClassName();$page=$this->getPage();$cs=$page->getClientScript();$cs->registerPradoScript('tabpanel');$code="new $className($options);";$cs->registerEndScript("prado:$id", $code);$cs->registerHiddenField($id.'_1',$this->getActiveViewIndex());$page->registerRequiresPostData($this);}/*** 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.TTabPanel';}/*** @return array the options for JavaScript*/protected function getClientOptions(){$options['ID']=$this->getClientID();$options['ActiveCssClass']=$this->getActiveTabCssClass();$options['NormalCssClass']=$this->getTabCssClass();$viewIDs=array();foreach($this->getViews() as $view){if($view->getVisible())$viewIDs[]=$view->getClientID();}$options['Views']='[\''.implode('\',\'',$viewIDs).'\']';return $options;}/*** Creates a control collection object that is to be used to hold child controls* @return TTabViewCollection control collection*/protected function createControlCollection(){return new TTabViewCollection($this);}/*** @return TTabViewCollection list of {@link TTabView} controls*/public function getViews(){return $this->getControls();}/*** Renders body contents of the tab control.* @param THtmlWriter the writer used for the rendering purpose.*/public function renderContents($writer){$views=$this->getViews();if($views->getCount()>0){$writer->writeLine();// render tab barforeach($views as $view){$view->renderTab($writer);$writer->writeLine();}// render tab viewsforeach($views as $view){$view->renderControl($writer);$writer->writeLine();}}}}/*** TTabView class.** TTabView represents a view in a {@link TTabPanel} control.** The content in a TTabView can be specified by the {@link setText Text} property* or its child controls. In template syntax, the latter means enclosing the content* within the TTabView component element. If both are set, {@link getText Text} takes precedence.** Each TTabView is associated with a tab in the tab bar of the TTabPanel control.* The tab caption is specified by {@link setCaption Caption}. If {@link setNavigateUrl NavigateUrl}* is set, the tab will contain a hyperlink pointing to the specified URL. In this case,* clicking on the tab will redirect the browser to the specified URL.** TTabView may be toggled between visible (active) and invisible (inactive) by* setting the {@link setActive Active} property.** @author Tomasz Wolny <tomasz.wolny@polecam.to.pl> and Qiang Xue <qiang.xue@gmail.com>* @version $Id: TTabPanel.php 2501 2008-08-18 23:00:14Z knut $* @since 3.1.1*/class TTabView extends TWebControl{private $_active=false;/*** @return the tag name for the view element*/protected function getTagName(){return 'div';}/*** Adds attributes to renderer.* @param THtmlWriter the renderer*/protected function addAttributesToRender($writer){if(!$this->getActive() && $this->getPage()->getClientSupportsJavaScript())$this->getStyle()->setStyleField('display','none');$this->getStyle()->mergeWith($this->getParent()->getViewStyle());parent::addAttributesToRender($writer);$writer->addAttribute('id',$this->getClientID());}/*** @return string the caption displayed on this tab. Defaults to ''.*/public function getCaption(){return $this->getViewState('Caption','');}/*** @param string the caption displayed on this tab*/public function setCaption($value){$this->setViewState('Caption',TPropertyValue::ensureString($value),'');}/*** @return string the URL of the target page. Defaults to ''.*/public function getNavigateUrl(){return $this->getViewState('NavigateUrl','');}/*** Sets the URL of the target page.* If not empty, clicking on this tab will redirect the browser to the specified URL.* @param string the URL of the target page.*/public function setNavigateUrl($value){$this->setViewState('NavigateUrl',TPropertyValue::ensureString($value),'');}/*** @return string the text content displayed on this view. Defaults to ''.*/public function getText(){return $this->getViewState('Text','');}/*** Sets the text content to be displayed on this view.* If this is not empty, the child content of the view will be ignored.* @param string the text content displayed on this view*/public function setText($value){$this->setViewState('Text',TPropertyValue::ensureString($value),'');}/*** @return boolean whether this tab view is active. Defaults to false.*/public function getActive(){return $this->_active;}/*** @param boolean whether this tab view is active.*/public function setActive($value){$this->_active=TPropertyValue::ensureBoolean($value);}/*** Renders body contents of the tab view.* @param THtmlWriter the writer used for the rendering purpose.*/public function renderContents($writer){if(($text=$this->getText())!=='')$writer->write($text);else if($this->getHasControls())parent::renderContents($writer);}/*** Renders the tab associated with the tab view.* @param THtmlWriter the writer for rendering purpose.*/public function renderTab($writer){if($this->getVisible(false) && $this->getPage()->getClientSupportsJavaScript()){$writer->addAttribute('id',$this->getClientID().'_0');$style=$this->getActive()?$this->getParent()->getActiveTabStyle():$this->getParent()->getTabStyle();$style->addAttributesToRender($writer);$writer->renderBeginTag($this->getTagName());$this->renderTabContent($writer);$writer->renderEndTag();}}/*** Renders the content in the tab.* By default, a hyperlink is displayed.* @param THtmlWriter the HTML writer*/protected function renderTabContent($writer){if(($url=$this->getNavigateUrl())==='')$url='javascript://';if(($caption=$this->getCaption())==='')$caption=' ';$writer->write("<a href=\"{$url}\">{$caption}</a>");}}/*** TTabViewCollection class.** TTabViewCollection is used to maintain a list of views belong to a {@link TTabPanel}.** @author Tomasz Wolny <tomasz.wolny@polecam.to.pl> and Qiang Xue <qiang.xue@gmail.com>* @version $Id: TTabPanel.php 2501 2008-08-18 23:00:14Z knut $* @since 3.1.1*/class TTabViewCollection extends TControlCollection{/*** Inserts an item at the specified position.* This overrides the parent implementation by performing sanity check on the type of new item.* @param integer the speicified position.* @param mixed new item* @throws TInvalidDataTypeException if the item to be inserted is not a {@link TTabView} object.*/public function insertAt($index,$item){if($item instanceof TTabView)parent::insertAt($index,$item);elsethrow new TInvalidDataTypeException('tabviewcollection_tabview_required');}/*** Finds the index of the tab view whose ID is the same as the one being looked for.* @param string the explicit ID of the tab view to be looked for* @return integer the index of the tab view found, -1 if not found.*/public function findIndexByID($id){foreach($this as $index=>$view){if($view->getID(false)===$id)return $index;}return -1;}}?>