From 5c0a31f2407037665e8640e486c36d6c71c5ca90 Mon Sep 17 00:00:00 2001 From: "ctrlaltca@gmail.com" <> Date: Wed, 1 Jun 2011 09:39:26 +0000 Subject: backported active data controls + some other goodies from trunk/ ; updated docs --- .../Web/UI/ActiveControls/TActiveDataGrid.php | 753 +++++++++++++++++++++ .../Web/UI/ActiveControls/TActiveDataList.php | 117 ++++ framework/Web/UI/ActiveControls/TActiveLabel.php | 178 ++--- .../Web/UI/ActiveControls/TActiveMultiView.php | 110 +++ .../Web/UI/ActiveControls/TActiveRepeater.php | 113 ++++ .../Web/UI/ActiveControls/TActiveTableCell.php | 244 +++++++ .../Web/UI/ActiveControls/TActiveTableRow.php | 262 +++++++ framework/Web/UI/TTemplateControlInheritable.php | 116 ++++ 8 files changed, 1804 insertions(+), 89 deletions(-) create mode 100644 framework/Web/UI/ActiveControls/TActiveDataGrid.php create mode 100644 framework/Web/UI/ActiveControls/TActiveDataList.php create mode 100644 framework/Web/UI/ActiveControls/TActiveMultiView.php create mode 100644 framework/Web/UI/ActiveControls/TActiveRepeater.php create mode 100644 framework/Web/UI/ActiveControls/TActiveTableCell.php create mode 100644 framework/Web/UI/ActiveControls/TActiveTableRow.php create mode 100644 framework/Web/UI/TTemplateControlInheritable.php (limited to 'framework/Web') diff --git a/framework/Web/UI/ActiveControls/TActiveDataGrid.php b/framework/Web/UI/ActiveControls/TActiveDataGrid.php new file mode 100644 index 00000000..358bd414 --- /dev/null +++ b/framework/Web/UI/ActiveControls/TActiveDataGrid.php @@ -0,0 +1,753 @@ + + * @link http://www.landwehr-software.de/ + * @copyright Copyright © 2009 LANDWEHR Computer und Software GmbH + * @license http://www.pradosoft.com/license/ + * @package System.Web.UI.ActiveControls + */ + +/** + * Includes the following used classes + */ +Prado::using('System.Web.UI.ActiveControls.TActiveControlAdapter'); +Prado::using('System.Web.UI.ActiveControls.TActiveLinkButton'); +Prado::using('System.Web.UI.ActiveControls.TActiveImageButton'); +Prado::using('System.Web.UI.ActiveControls.TActiveButton'); +Prado::using('System.Web.UI.ActiveControls.TActiveImage'); +Prado::using('System.Web.UI.ActiveControls.TActiveCheckBox'); +Prado::using('System.Web.UI.WebControls.TDataGrid'); +Prado::using('System.Web.UI.WebControls.TBoundColumn'); +Prado::using('System.Web.UI.WebControls.TEditCommandColumn'); +Prado::using('System.Web.UI.WebControls.TButtonColumn'); +Prado::using('System.Web.UI.WebControls.THyperLinkColumn'); +Prado::using('System.Web.UI.WebControls.TCheckBoxColumn'); + +/** + * TActiveDataGrid class + * + * TActiveDataGrid represents a data bound and updatable grid control which is the + * active counterpart to the original {@link TDataGrid} control. + * + * This component can be used in the same way as the regular datagrid, the only + * difference is that the active datagrid uses callbacks instead of postbacks + * for interaction. + * + * There are also active datagrid columns to work with the TActiveDataGrid, which are + * - {@link TActiveBoundColumn}, the active counterpart to {@link TBoundColumn}. + * - {@link TActiveEditCommandColumn}, the active counterpart to {@link TEditCommandColumn}. + * - {@link TActiveButtonColumn}, the active counterpart to {@link TButtonColumn}. + * + * Please refer to the original documentation of the regular counterparts for usage. + * + * @author LANDWEHR Computer und Software GmbH + * @package System.Web.UI.ActiveControls + * @since 3.2 + */ +class TActiveDataGrid extends TDataGrid implements IActiveControl, ISurroundable { +/** + * Creates a new callback control, sets the adapter to + * TActiveControlAdapter. + */ + public function __construct() { + parent::__construct(); + $this->setAdapter(new TActiveControlAdapter($this)); + } + + /** + * @return TBaseActiveControl standard active control options. + */ + public function getActiveControl() { + return $this->getAdapter()->getBaseActiveControl(); + } + + /** + * Sets the data source object associated with the datagrid control. + * In addition, the render method of all connected pagers is called so they + * get updated when the data source is changed. Also the datagrid registers + * itself for rendering in order to get it's content replaced on client side. + * @param Traversable|array|string data source object + */ + public function setDataSource($value) { + parent::setDataSource($value); + if($this->getActiveControl()->canUpdateClientSide()) { + $this->renderPager(); + $this->getPage()->getAdapter()->registerControlToRender($this,$this->getResponse()->createHtmlWriter()); + } + } + + /** + * Returns the id of the surrounding container (span). + * @return string container id + */ + public function getSurroundingTagId() { + return $this->ClientID.'_Container'; + } + + /** + * Creates a pager button. + * Depending on the button type, a TActiveLinkButton or a TActiveButton may be created. + * If it is enabled (clickable), its command name and parameter will also be set. + * It overrides the datagrid's original method to create active controls instead, thus + * the pager will do callbacks instead of the regular postbacks. + * @param string button type, either LinkButton or PushButton + * @param boolean whether the button should be enabled + * @param string caption of the button + * @param string CommandName corresponding to the OnCommand event of the button + * @param string CommandParameter corresponding to the OnCommand event of the button + * @return mixed the button instance + */ + protected function createPagerButton($buttonType,$enabled,$text,$commandName,$commandParameter) { + if($buttonType===TDataGridPagerButtonType::LinkButton) { + if($enabled) + $button=new TActiveLinkButton; + else { + $button=new TLabel; + $button->setText($text); + return $button; + } + } + else { + $button=new TActiveButton; + if(!$enabled) + $button->setEnabled(false); + } + $button->setText($text); + $button->setCommandName($commandName); + $button->setCommandParameter($commandParameter); + $button->setCausesValidation(false); + return $button; + } + + /** + * Renders the datagrid. + * If the datagrid did not pass the prerender phase yet, it will register itself for rendering later. + * Else it will call the {@link renderDataGrid()} method which will do the rendering of the datagrid. + * @param THtmlWriter writer for the rendering purpose + */ + public function render($writer) { + if($this->getHasPreRendered()) { + $this->renderDataGrid($writer); + if($this->getActiveControl()->canUpdateClientSide()) $this->getPage()->getCallbackClient()->replaceContent($this->getSurroundingTagId(),$writer); + } + else { + $this->getPage()->getAdapter()->registerControlToRender($this,$writer); + } + } + + /** + * Loops through all {@link TActivePager} on the page and registers the ones which are set to paginate + * the datagrid for rendering. This is to ensure that the connected pagers are also rendered if the + * data source changed. + */ + private function renderPager() { + $pager=$this->getPage()->findControlsByType('TActivePager', false); + foreach($pager as $item) { + if($item->ControlToPaginate==$this->ID) { + $writer=$this->getResponse()->createHtmlWriter(); + $this->getPage()->getAdapter()->registerControlToRender($item,$writer); + } + } + } + + /** + * Renders the datagrid by writing a span tag with the container id obtained from {@link getSurroundingTagId()} + * which will be called by the replacement method of the client script to update it's content. + * @param THtmlWriter writer for the rendering purpose + */ + private function renderDataGrid($writer) { + $writer->write(''); + parent::render($writer); + $writer->write(''); + } +} + + +/** + * TActiveBoundColumn class + * + * TActiveBoundColumn represents a column that is bound to a field in a data source. + * The cells in the column will be displayed using the data indexed by + * {@link setDataField DataField}. You can customize the display by + * setting {@link setDataFormatString DataFormatString}. + * + * This is the active counterpart to the {@link TBoundColumn} control. For that purpose, + * if sorting is allowed, the header links/buttons are replaced by active controls. + * + * Please refer to the original documentation of the {@link TBoundColumn} for usage. + * + * @author LANDWEHR Computer und Software GmbH + * @package System.Web.UI.ActiveControls + * @since 3.2 + */ +class TActiveBoundColumn extends TBoundColumn { + protected function initializeHeaderCell($cell,$columnIndex) { + $text=$this->getHeaderText(); + + if(($classPath=$this->getHeaderRenderer())!=='') { + $control=Prado::createComponent($classPath); + if($control instanceof IDataRenderer) { + if($control instanceof IItemDataRenderer) { + $item=$cell->getParent(); + $control->setItemIndex($item->getItemIndex()); + $control->setItemType($item->getItemType()); + } + $control->setData($text); + } + $cell->getControls()->add($control); + } + else if($this->getAllowSorting()) { + $sortExpression=$this->getSortExpression(); + if(($url=$this->getHeaderImageUrl())!=='') { + $button=Prado::createComponent('System.Web.UI.WebControls.TActiveImageButton'); + $button->setImageUrl($url); + $button->setCommandName(TDataGrid::CMD_SORT); + $button->setCommandParameter($sortExpression); + if($text!=='') { + $button->setAlternateText($text); + $button->setToolTip($text); + } + $button->setCausesValidation(false); + $cell->getControls()->add($button); + } + else if($text!=='') { + $button=Prado::createComponent('System.Web.UI.WebControls.TActiveLinkButton'); + $button->setText($text); + $button->setCommandName(TDataGrid::CMD_SORT); + $button->setCommandParameter($sortExpression); + $button->setCausesValidation(false); + $cell->getControls()->add($button); + } + else + $cell->setText(' '); + } + else { + if(($url=$this->getHeaderImageUrl())!=='') { + $image=Prado::createComponent('System.Web.UI.WebControls.TActiveImage'); + $image->setImageUrl($url); + if($text!=='') { + $image->setAlternateText($text); + $image->setToolTip($text); + } + $cell->getControls()->add($image); + } + else if($text!=='') + $cell->setText($text); + else + $cell->setText(' '); + } + } +} + + +/** + * TActiveEditCommandColumn class + * + * TActiveEditCommandColumn contains the Edit command buttons for editing data items in each row. + * + * TActiveEditCommandColumn will create an edit button if a cell is not in edit mode. + * Otherwise an update button and a cancel button will be created within the cell. + * The button captions are specified using {@link setEditText EditText}, + * {@link setUpdateText UpdateText}, and {@link setCancelText CancelText}. + * + * This is the active counterpart to the {@link TEditCommandColumn} control. The buttons for + * interaction are replaced by active buttons. + * + * Please refer to the original documentation of the {@link TEditCommandColumn} for usage. + * + * @author LANDWEHR Computer und Software GmbH + * @package System.Web.UI.ActiveControls + * @since 3.2 + */ +class TActiveEditCommandColumn extends TEditCommandColumn { + protected function createButton($commandName,$text,$causesValidation,$validationGroup) { + if($this->getButtonType()===TButtonColumnType::LinkButton) + $button=Prado::createComponent('System.Web.UI.WebControls.TActiveLinkButton'); + else if($this->getButtonType()===TButtonColumnType::PushButton) + $button=Prado::createComponent('System.Web.UI.WebControls.TActiveButton'); + else // image buttons + { + $button=Prado::createComponent('System.Web.UI.WebControls.TActiveImageButton'); + $button->setToolTip($text); + if(strcasecmp($commandName,'Update')===0) + $url=$this->getUpdateImageUrl(); + else if(strcasecmp($commandName,'Cancel')===0) + $url=$this->getCancelImageUrl(); + else + $url=$this->getEditImageUrl(); + $button->setImageUrl($url); + } + $button->setText($text); + $button->setCommandName($commandName); + $button->setCausesValidation($causesValidation); + $button->setValidationGroup($validationGroup); + return $button; + } +} + + +/** + * TActiveButtonColumn class + * + * TActiveButtonColumn contains a user-defined command button, such as Add or Remove, + * that corresponds with each row in the column. + * + * This is the active counterpart to the {@link TButtonColumn} control where the + * button is replaced by the appropriate active button control. + * + * Please refer to the original documentation of the {@link TButtonColumn} for usage. + * + * @author LANDWEHR Computer und Software GmbH + * @package System.Web.UI.ActiveControls + * @since 3.2 + */ +class TActiveButtonColumn extends TButtonColumn { + public function initializeCell($cell,$columnIndex,$itemType) { + if($itemType===TListItemType::Item || $itemType===TListItemType::AlternatingItem || $itemType===TListItemType::SelectedItem || $itemType===TListItemType::EditItem) { + $buttonType=$this->getButtonType(); + if($buttonType===TButtonColumnType::LinkButton) + $button=new TActiveLinkButton; + else if($buttonType===TButtonColumnType::PushButton) + $button=new TActiveButton; + else // image button + { + $button=new TActiveImageButton; + $button->setImageUrl($this->getImageUrl()); + $button->setToolTip($this->getText()); + } + $button->setText($this->getText()); + $button->setCommandName($this->getCommandName()); + $button->setCausesValidation($this->getCausesValidation()); + $button->setValidationGroup($this->getValidationGroup()); + if($this->getDataTextField()!=='' || ($buttonType===TButtonColumnType::ImageButton && $this->getDataImageUrlField()!=='')) + $button->attachEventHandler('OnDataBinding',array($this,'dataBindColumn')); + $cell->getControls()->add($button); + $cell->registerObject('Button',$button); + } + else + parent::initializeCell($cell,$columnIndex,$itemType); + } +} + + +/** + * TActiveTemplateColumn class + * + * TActiveTemplateColumn customizes the layout of controls in the column with templates. + * In particular, you can specify {@link setItemTemplate ItemTemplate}, + * {@link setEditItemTemplate EditItemTemplate}, {@link setHeaderTemplate HeaderTemplate} + * and {@link setFooterTemplate FooterTemplate} to customize specific + * type of cells in the column. + * + * This is the active counterpart to the {@link TTemplateColumn} control. For that purpose, + * if sorting is allowed, the header links/buttons are replaced by active controls. + * + * Please refer to the original documentation of the {@link TTemplateColumn} for usage. + * + * @author LANDWEHR Computer und Software GmbH + * @package System.Web.UI.ActiveControls + * @since 3.2 + */ +class TActiveTemplateColumn extends TTemplateColumn { + protected function initializeHeaderCell($cell,$columnIndex) { + $text=$this->getHeaderText(); + + if(($classPath=$this->getHeaderRenderer())!=='') { + $control=Prado::createComponent($classPath); + if($control instanceof IDataRenderer) { + if($control instanceof IItemDataRenderer) { + $item=$cell->getParent(); + $control->setItemIndex($item->getItemIndex()); + $control->setItemType($item->getItemType()); + } + $control->setData($text); + } + $cell->getControls()->add($control); + } + else if($this->getAllowSorting()) { + $sortExpression=$this->getSortExpression(); + if(($url=$this->getHeaderImageUrl())!=='') { + $button=Prado::createComponent('System.Web.UI.WebControls.TActiveImageButton'); + $button->setImageUrl($url); + $button->setCommandName(TDataGrid::CMD_SORT); + $button->setCommandParameter($sortExpression); + if($text!=='') + $button->setAlternateText($text); + $button->setCausesValidation(false); + $cell->getControls()->add($button); + } + else if($text!=='') { + $button=Prado::createComponent('System.Web.UI.WebControls.TActiveLinkButton'); + $button->setText($text); + $button->setCommandName(TDataGrid::CMD_SORT); + $button->setCommandParameter($sortExpression); + $button->setCausesValidation(false); + $cell->getControls()->add($button); + } + else + $cell->setText(' '); + } + else { + if(($url=$this->getHeaderImageUrl())!=='') { + $image=Prado::createComponent('System.Web.UI.WebControls.TActiveImage'); + $image->setImageUrl($url); + if($text!=='') + $image->setAlternateText($text); + $cell->getControls()->add($image); + } + else if($text!=='') + $cell->setText($text); + else + $cell->setText(' '); + } + } +} + +/** + * TActiveHyperLinkColumn class + * + * TActiveHyperLinkColumn contains a hyperlink for each item in the column. + * + * This is the active counterpart to the {@link THyperLinkColumn} control. For that purpose, + * if sorting is allowed, the header links/buttons are replaced by active controls. + * + * Please refer to the original documentation of the {@link THyperLinkColumn} for usage. + * + * @author LANDWEHR Computer und Software GmbH + * @package System.Web.UI.ActiveControls + * @since 3.2 + */ +class TActiveHyperLinkColumn extends THyperLinkColumn +{ + + protected function initializeHeaderCell($cell,$columnIndex) + { + $text=$this->getHeaderText(); + + if(($classPath=$this->getHeaderRenderer())!=='') + { + $control=Prado::createComponent($classPath); + if($control instanceof IDataRenderer) + { + if($control instanceof IItemDataRenderer) + { + $item=$cell->getParent(); + $control->setItemIndex($item->getItemIndex()); + $control->setItemType($item->getItemType()); + } + $control->setData($text); + } + $cell->getControls()->add($control); + } + else if($this->getAllowSorting()) + { + $sortExpression=$this->getSortExpression(); + if(($url=$this->getHeaderImageUrl())!=='') + { + $button=Prado::createComponent('System.Web.UI.WebControls.TActiveImageButton'); + $button->setImageUrl($url); + $button->setCommandName(TDataGrid::CMD_SORT); + $button->setCommandParameter($sortExpression); + if($text!=='') + $button->setAlternateText($text); + $button->setCausesValidation(false); + $cell->getControls()->add($button); + } + else if($text!=='') + { + $button=Prado::createComponent('System.Web.UI.WebControls.TActiveLinkButton'); + $button->setText($text); + $button->setCommandName(TDataGrid::CMD_SORT); + $button->setCommandParameter($sortExpression); + $button->setCausesValidation(false); + $cell->getControls()->add($button); + } + else + $cell->setText(' '); + } + else + { + if(($url=$this->getHeaderImageUrl())!=='') + { + $image=Prado::createComponent('System.Web.UI.WebControls.TActiveImage'); + $image->setImageUrl($url); + if($text!=='') + $image->setAlternateText($text); + $cell->getControls()->add($image); + } + else if($text!=='') + $cell->setText($text); + else + $cell->setText(' '); + } + } +} + +/** + * TActiveCheckBoxColumn class + * + * TActiveCheckBoxColumn represents a checkbox column that is bound to a field in a data source. + * + * This is the active counterpart to the {@link TCheckBoxColumn} control. For that purpose, + * if sorting is allowed, the header links/buttons are replaced by active controls. + * + * Please refer to the original documentation of the {@link TCheckBoxColumn} for usage. + * + * @author LANDWEHR Computer und Software GmbH + * @package System.Web.UI.ActiveControls + * @since 3.2 + */ +class TActiveCheckBoxColumn extends TCheckBoxColumn +{ + /** + * Initializes the specified cell to its initial values. + * This method overrides the parent implementation. + * It creates a checkbox inside the cell. + * If the column is read-only or if the item is not in edit mode, + * the checkbox will be set disabled. + * @param TTableCell the cell to be initialized. + * @param integer the index to the Columns property that the cell resides in. + * @param string the type of cell (Header,Footer,Item,AlternatingItem,EditItem,SelectedItem) + */ + public function initializeCell($cell,$columnIndex,$itemType) + { + if($itemType===TListItemType::Item || $itemType===TListItemType::AlternatingItem || $itemType===TListItemType::SelectedItem || $itemType===TListItemType::EditItem) + { + $checkBox=new TActiveCheckBox; + if($this->getReadOnly() || $itemType!==TListItemType::EditItem) + $checkBox->setEnabled(false); + $cell->setHorizontalAlign('Center'); + $cell->getControls()->add($checkBox); + $cell->registerObject('CheckBox',$checkBox); + if($this->getDataField()!=='') + $checkBox->attachEventHandler('OnDataBinding',array($this,'dataBindColumn')); + } + else + parent::initializeCell($cell,$columnIndex,$itemType); + } + + protected function initializeHeaderCell($cell,$columnIndex) + { + $text=$this->getHeaderText(); + + if(($classPath=$this->getHeaderRenderer())!=='') + { + $control=Prado::createComponent($classPath); + if($control instanceof IDataRenderer) + { + if($control instanceof IItemDataRenderer) + { + $item=$cell->getParent(); + $control->setItemIndex($item->getItemIndex()); + $control->setItemType($item->getItemType()); + } + $control->setData($text); + } + $cell->getControls()->add($control); + } + else if($this->getAllowSorting()) + { + $sortExpression=$this->getSortExpression(); + if(($url=$this->getHeaderImageUrl())!=='') + { + $button=Prado::createComponent('System.Web.UI.WebControls.TActiveImageButton'); + $button->setImageUrl($url); + $button->setCommandName(TDataGrid::CMD_SORT); + $button->setCommandParameter($sortExpression); + if($text!=='') + $button->setAlternateText($text); + $button->setCausesValidation(false); + $cell->getControls()->add($button); + } + else if($text!=='') + { + $button=Prado::createComponent('System.Web.UI.WebControls.TActiveLinkButton'); + $button->setText($text); + $button->setCommandName(TDataGrid::CMD_SORT); + $button->setCommandParameter($sortExpression); + $button->setCausesValidation(false); + $cell->getControls()->add($button); + } + else + $cell->setText(' '); + } + else + { + if(($url=$this->getHeaderImageUrl())!=='') + { + $image=Prado::createComponent('System.Web.UI.WebControls.TActiveImage'); + $image->setImageUrl($url); + if($text!=='') + $image->setAlternateText($text); + $cell->getControls()->add($image); + } + else if($text!=='') + $cell->setText($text); + else + $cell->setText(' '); + } + } +} + +/** + * TActiveDropDownListColumn class + * + * TActiveDropDownListColumn represents a column that is bound to a field in a data source. + * + * This is the active counterpart to the {@link TDropDownListColumn} control. For that purpose, + * if sorting is allowed, the header links/buttons are replaced by active controls. + * + * Please refer to the original documentation of the {@link TDropDownListColumn} for usage. + * + * @author LANDWEHR Computer und Software GmbH + * @package System.Web.UI.ActiveControls + * @since 3.2 + */ +class TActiveDropDownListColumn extends TDropDownListColumn +{ + protected function initializeHeaderCell($cell,$columnIndex) + { + $text=$this->getHeaderText(); + + if(($classPath=$this->getHeaderRenderer())!=='') + { + $control=Prado::createComponent($classPath); + if($control instanceof IDataRenderer) + { + if($control instanceof IItemDataRenderer) + { + $item=$cell->getParent(); + $control->setItemIndex($item->getItemIndex()); + $control->setItemType($item->getItemType()); + } + $control->setData($text); + } + $cell->getControls()->add($control); + } + else if($this->getAllowSorting()) + { + $sortExpression=$this->getSortExpression(); + if(($url=$this->getHeaderImageUrl())!=='') + { + $button=Prado::createComponent('System.Web.UI.WebControls.TActiveImageButton'); + $button->setImageUrl($url); + $button->setCommandName(TDataGrid::CMD_SORT); + $button->setCommandParameter($sortExpression); + if($text!=='') + $button->setAlternateText($text); + $button->setCausesValidation(false); + $cell->getControls()->add($button); + } + else if($text!=='') + { + $button=Prado::createComponent('System.Web.UI.WebControls.TActiveLinkButton'); + $button->setText($text); + $button->setCommandName(TDataGrid::CMD_SORT); + $button->setCommandParameter($sortExpression); + $button->setCausesValidation(false); + $cell->getControls()->add($button); + } + else + $cell->setText(' '); + } + else + { + if(($url=$this->getHeaderImageUrl())!=='') + { + $image=Prado::createComponent('System.Web.UI.WebControls.TActiveImage'); + $image->setImageUrl($url); + if($text!=='') + $image->setAlternateText($text); + $cell->getControls()->add($image); + } + else if($text!=='') + $cell->setText($text); + else + $cell->setText(' '); + } + } + +} + +/** + * TActiveLiteralColumn class + * + * TActiveLiteralColumn represents a static text column that is bound to a field in a data source. + * The cells in the column will be displayed with static texts using the data indexed by + * {@link setDataField DataField}. You can customize the display by + * setting {@link setDataFormatString DataFormatString}. + * + * If {@link setDataField DataField} is not specified, the cells will be filled + * with {@link setText Text}. + * + * If {@link setEncode Encode} is true, the static texts will be HTML-encoded. + * + * This is the active counterpart to the {@link TLiteralColumn} control. For that purpose, + * if sorting is allowed, the header links/buttons are replaced by active controls. + * + * Please refer to the original documentation of the {@link TLiteralColumn} for usage. + * + * @author Fabio Bas + * @package System.Web.UI.ActiveControls + * @since 3.2.0a + */ +class TActiveLiteralColumn extends TLiteralColumn { + protected function initializeHeaderCell($cell,$columnIndex) { + $text=$this->getHeaderText(); + + if(($classPath=$this->getHeaderRenderer())!=='') { + $control=Prado::createComponent($classPath); + if($control instanceof IDataRenderer) { + if($control instanceof IItemDataRenderer) { + $item=$cell->getParent(); + $control->setItemIndex($item->getItemIndex()); + $control->setItemType($item->getItemType()); + } + $control->setData($text); + } + $cell->getControls()->add($control); + } + else if($this->getAllowSorting()) { + $sortExpression=$this->getSortExpression(); + if(($url=$this->getHeaderImageUrl())!=='') { + $button=Prado::createComponent('System.Web.UI.WebControls.TActiveImageButton'); + $button->setImageUrl($url); + $button->setCommandName(TDataGrid::CMD_SORT); + $button->setCommandParameter($sortExpression); + if($text!=='') { + $button->setAlternateText($text); + $button->setToolTip($text); + } + $button->setCausesValidation(false); + $cell->getControls()->add($button); + } + else if($text!=='') { + $button=Prado::createComponent('System.Web.UI.WebControls.TActiveLinkButton'); + $button->setText($text); + $button->setCommandName(TDataGrid::CMD_SORT); + $button->setCommandParameter($sortExpression); + $button->setCausesValidation(false); + $cell->getControls()->add($button); + } + else + $cell->setText(' '); + } + else { + if(($url=$this->getHeaderImageUrl())!=='') { + $image=Prado::createComponent('System.Web.UI.WebControls.TActiveImage'); + $image->setImageUrl($url); + if($text!=='') { + $image->setAlternateText($text); + $image->setToolTip($text); + } + $cell->getControls()->add($image); + } + else if($text!=='') + $cell->setText($text); + else + $cell->setText(' '); + } + } +} diff --git a/framework/Web/UI/ActiveControls/TActiveDataList.php b/framework/Web/UI/ActiveControls/TActiveDataList.php new file mode 100644 index 00000000..dbf70067 --- /dev/null +++ b/framework/Web/UI/ActiveControls/TActiveDataList.php @@ -0,0 +1,117 @@ + + * @copyright Copyright © 2008, PradoSoft + * @license http://www.pradosoft.com/license + * @package System.Web.UI.ActiveControls + * @version $Id: TActiveDataList.php 2706 2009-09-24 14:42:30Z rojaro $ + */ + +/** + * TActiveDataList class + * + * TActiveDataList represents a data bound and updatable grid control which is the + * active counterpart to the original {@link TDataList} control. + * + * This component can be used in the same way as the regular datalist, the only + * difference is that the active datalist uses callbacks instead of postbacks + * for interaction. + * + * Please refer to the original documentation of the regular counterparts for usage. + * + * @author Marcos Aurelio Nobre + * @package System.Web.UI.ActiveControls + */ +class TActiveDataList extends TDataList implements IActiveControl { + + /** + * Creates a new callback control, sets the adapter to + * TActiveControlAdapter. + */ + public function __construct() + { + parent::__construct(); + $this->setAdapter(new TActiveControlAdapter($this)); + } + + /** + * @return TBaseActiveControl standard active control options. + */ + public function getActiveControl() + { + return $this->getAdapter()->getBaseActiveControl(); + } + + /** + * Sets the data source object associated with the repeater control. + * In addition, the render method of all connected pagers is called so they + * get updated when the data source is changed. Also the repeater registers + * itself for rendering in order to get it's content replaced on client side. + * @param Traversable|array|string data source object + */ + public function setDataSource($value) + { + parent::setDataSource($value); + if($this->getActiveControl()->canUpdateClientSide()) { + $this->renderPager(); + $this->getPage()->getAdapter()->registerControlToRender($this,$this->getResponse()->createHtmlWriter()); + } + } + + /** + * Returns the id of the surrounding container (span). + * @return string container id + */ + protected function getContainerID() + { + return $this->ClientID.'_Container'; + } + + /** + * Renders the repeater. + * If the repeater did not pass the prerender phase yet, it will register itself for rendering later. + * Else it will call the {@link renderRepeater()} method which will do the rendering of the repeater. + * @param THtmlWriter writer for the rendering purpose + */ + public function render($writer) + { + if($this->getHasPreRendered()) { + $this->renderDataList($writer); + if($this->getActiveControl()->canUpdateClientSide()) $this->getPage()->getCallbackClient()->replaceContent($this->getContainerID(),$writer); + } + else { + $this->getPage()->getAdapter()->registerControlToRender($this,$writer); + } + } + + /** + * Loops through all {@link TActivePager} on the page and registers the ones which are set to paginate + * the repeater for rendering. This is to ensure that the connected pagers are also rendered if the + * data source changed. + */ + private function renderPager() + { + $pager=$this->getPage()->findControlsByType('TActivePager', false); + foreach($pager as $item) + { + if($item->ControlToPaginate==$this->ID) { + $writer=$this->getResponse()->createHtmlWriter(); + $this->getPage()->getAdapter()->registerControlToRender($item,$writer); + } + } + } + + /** + * Renders the repeater by writing a span tag with the container id obtained from {@link getContainerID()} + * which will be called by the replacement method of the client script to update it's content. + * @param THtmlWriter writer for the rendering purpose + */ + private function renderDataList($writer) + { + $writer->write(''); + parent::render($writer); + $writer->write(''); + } +} diff --git a/framework/Web/UI/ActiveControls/TActiveLabel.php b/framework/Web/UI/ActiveControls/TActiveLabel.php index 4105e3dc..e2d14419 100644 --- a/framework/Web/UI/ActiveControls/TActiveLabel.php +++ b/framework/Web/UI/ActiveControls/TActiveLabel.php @@ -1,90 +1,90 @@ - - * @link http://www.pradosoft.com/ - * @copyright Copyright © 2005-2008 PradoSoft - * @license http://www.pradosoft.com/license/ - * @version $Id$ - * @package System.Web.UI.ActiveControls - */ - -/** - * Load active control adapter. - */ -Prado::using('System.Web.UI.ActiveControls.TActiveControlAdapter'); - -/** - * TActiveLabel class - * - * The active control counterpart of TLabel component. When - * {@link TBaseActiveControl::setEnableUpdate ActiveControl.EnableUpdate} - * property is true the during a callback request, setting {@link setText Text} - * property will also set the text of the label on the client upon callback - * completion. Similarly, setting {@link setForControl ForControl} will also set - * the client-side "for" attribute on the label. - * - * @author Wei Zhuo - * @version $Id$ - * @package System.Web.UI.ActiveControls - * @since 3.1 - */ -class TActiveLabel extends TLabel implements IActiveControl -{ - /** - * Creates a new callback control, sets the adapter to - * TActiveControlAdapter. If you override this class, be sure to set the - * adapter appropriately by, for example, by calling this constructor. - */ - public function __construct() - { - parent::__construct(); - $this->setAdapter(new TActiveControlAdapter($this)); - } - - /** - * @return TBaseActiveControl basic active control options. - */ - public function getActiveControl() - { - return $this->getAdapter()->getBaseActiveControl(); - } - - /** - * On callback response, the inner HTML of the label is updated. - * @param string the text value of the label - */ - public function setText($value) - { - parent::setText($value); - if($this->getActiveControl()->canUpdateClientSide()) - $this->getPage()->getCallbackClient()->update($this, $value); - } - - /** - * Sets the ID of the control that the label is associated with. - * The control must be locatable via {@link TControl::findControl} using the ID. - * On callback response, the For attribute of the label is updated. - * @param string the associated control ID - */ - public function setForControl($value) - { - parent::setForControl($value); - if($this->getActiveControl()->canUpdateClientSide()) - { - $id=$this->findControl($value)->getClientID(); - $this->getPage()->getCallbackClient()->setAttribute($this, 'for', $id); - } - } - - /** - * Adds attribute id to the renderer. + + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2008 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Web.UI.ActiveControls + */ + +/** + * Load active control adapter. + */ +Prado::using('System.Web.UI.ActiveControls.TActiveControlAdapter'); + +/** + * TActiveLabel class + * + * The active control counterpart of TLabel component. When + * {@link TBaseActiveControl::setEnableUpdate ActiveControl.EnableUpdate} + * property is true the during a callback request, setting {@link setText Text} + * property will also set the text of the label on the client upon callback + * completion. Similarly, setting {@link setForControl ForControl} will also set + * the client-side "for" attribute on the label. + * + * @author Wei Zhuo + * @version $Id$ + * @package System.Web.UI.ActiveControls + * @since 3.1 + */ +class TActiveLabel extends TLabel implements IActiveControl +{ + /** + * Creates a new callback control, sets the adapter to + * TActiveControlAdapter. If you override this class, be sure to set the + * adapter appropriately by, for example, by calling this constructor. + */ + public function __construct() + { + parent::__construct(); + $this->setAdapter(new TActiveControlAdapter($this)); + } + + /** + * @return TBaseActiveControl basic active control options. + */ + public function getActiveControl() + { + return $this->getAdapter()->getBaseActiveControl(); + } + + /** + * On callback response, the inner HTML of the label is updated. + * @param string the text value of the label + */ + public function setText($value) + { + parent::setText($value); + if($this->getActiveControl()->canUpdateClientSide()) + $this->getPage()->getCallbackClient()->update($this, $value); + } + + /** + * Sets the ID of the control that the label is associated with. + * The control must be locatable via {@link TControl::findControl} using the ID. + * On callback response, the For attribute of the label is updated. + * @param string the associated control ID + */ + public function setForControl($value) + { + parent::setForControl($value); + if($this->getActiveControl()->canUpdateClientSide()) + { + $id=$this->findControl($value)->getClientID(); + $this->getPage()->getCallbackClient()->setAttribute($this, 'for', $id); + } + } + + /** + * Adds attribute id to the renderer. * @param THtmlWriter the writer used for the rendering purpose - */ - protected function addAttributesToRender($writer) { - $writer->addAttribute('id',$this->getClientID()); - parent::addAttributesToRender($writer); - } -} - + */ + protected function addAttributesToRender($writer) { + $writer->addAttribute('id',$this->getClientID()); + parent::addAttributesToRender($writer); + } +} + diff --git a/framework/Web/UI/ActiveControls/TActiveMultiView.php b/framework/Web/UI/ActiveControls/TActiveMultiView.php new file mode 100644 index 00000000..5040ef94 --- /dev/null +++ b/framework/Web/UI/ActiveControls/TActiveMultiView.php @@ -0,0 +1,110 @@ + + * @link http://www.landwehr-software.de/ + * @copyright Copyright © 2009 LANDWEHR Computer und Software GmbH + * @license http://www.pradosoft.com/license/ + * @package System.Web.UI.ActiveControls + */ + +/** + * Includes the following used classes + */ +Prado::using('System.Web.UI.WebControls.TMultiView'); + +/** + * TActiveMultiView class. + * + * TActiveMultiView is the active counterpart to the original {@link TMultiView} control. + * It re-renders on Callback when {@link setActiveView ActiveView} or + * {@link setActiveViewIndex ActiveViewIndex} is called. + * + * Please refer to the original documentation of the regular counterpart for usage. + * + * @author LANDWEHR Computer und Software GmbH + * @package System.Web.UI.ActiveControls + * @since 3.1.6 + */ +class TActiveMultiView extends TMultiView implements IActiveControl +{ + /** + * Creates a new callback control, sets the adapter to + * TActiveControlAdapter. + */ + public function __construct() + { + parent::__construct(); + $this->setAdapter(new TActiveControlAdapter($this)); + } + + /** + * @return TBaseActiveControl standard active control options. + */ + public function getActiveControl() + { + return $this->getAdapter()->getBaseActiveControl(); + } + + /** + * Returns the id of the surrounding container (span). + * @return string container id + */ + protected function getContainerID() + { + return $this->ClientID.'_Container'; + } + + /** + * Renders the TActiveMultiView. + * If the MutliView did not pass the prerender phase yet, it will register itself for rendering later. + * Else it will call the {@link renderMultiView()} method which will do the rendering of the MultiView. + * @param THtmlWriter writer for the rendering purpose + */ + public function render($writer) + { + if($this->getHasPreRendered()) { + $this->renderMultiView($writer); + if($this->getActiveControl()->canUpdateClientSide()) + $this->getPage()->getCallbackClient()->replaceContent($this->getContainerID(),$writer); + } + else + $this->getPage()->getAdapter()->registerControlToRender($this,$writer); + } + + /** + * Renders the TActiveMultiView by writing a span tag with the container id obtained from {@link getContainerID()} + * which will be called by the replacement method of the client script to update it's content. + * @param $writer THtmlWriter writer for the rendering purpose + */ + protected function renderMultiView($writer) + { + $writer->addAttribute('id', $this->getContainerID()); + $writer->renderBeginTag('span'); + parent::render($writer); + $writer->renderEndTag(); + } + + /** + * @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) + { + parent::setActiveViewIndex($value); + if($this->getActiveControl()->canUpdateClientSide()) + $this->getPage()->getAdapter()->registerControlToRender($this,$this->getResponse()->createHtmlWriter()); + } + + /** + * @param TView the view to be activated + * @throws TInvalidOperationException if the view is not in the view collection + */ + public function setActiveView($value) + { + parent::setActiveView($value); + if($this->getActiveControl()->canUpdateClientSide()) + $this->getPage()->getAdapter()->registerControlToRender($this,$this->getResponse()->createHtmlWriter()); + } +} diff --git a/framework/Web/UI/ActiveControls/TActiveRepeater.php b/framework/Web/UI/ActiveControls/TActiveRepeater.php new file mode 100644 index 00000000..ccfda4aa --- /dev/null +++ b/framework/Web/UI/ActiveControls/TActiveRepeater.php @@ -0,0 +1,113 @@ + + * @package System.Web.UI.ActiveControls + * @since 3.2 + * @version $Id: TActiveRepeater.php 2707 2009-09-29 10:33:30Z Christophe.Boulain $ + */ + +/** + * TActiveRepeater class + * + * TActiveRepeater represents a data bound and updatable grid control which is the + * active counterpart to the original {@link TRepeater} control. + * + * This component can be used in the same way as the regular datagrid, the only + * difference is that the active repeater uses callbacks instead of postbacks + * for interaction. + * + * Please refer to the original documentation of the regular counterparts for usage. + * + * @author LANDWEHR Computer und Software GmbH + * @package System.Web.UI.ActiveControls + * @since 3.2 + */ +class TActiveRepeater extends TRepeater implements IActiveControl, ISurroundable { + +/** + * Creates a new callback control, sets the adapter to + * TActiveControlAdapter. + */ + public function __construct() { + parent::__construct(); + $this->setAdapter(new TActiveControlAdapter($this)); + } + + /** + * @return TBaseActiveControl standard active control options. + */ + public function getActiveControl() { + return $this->getAdapter()->getBaseActiveControl(); + } + + /** + * Sets the data source object associated with the repeater control. + * In addition, the render method of all connected pagers is called so they + * get updated when the data source is changed. Also the repeater registers + * itself for rendering in order to get it's content replaced on client side. + * @param Traversable|array|string data source object + */ + public function setDataSource($value) { + parent::setDataSource($value); + if($this->getActiveControl()->canUpdateClientSide()) { + $this->renderPager(); + $this->getPage()->getAdapter()->registerControlToRender($this,$this->getResponse()->createHtmlWriter()); + } + } + + /** + * Returns the id of the surrounding container (span). + * @return string container id + */ + public function getSurroundingTagID() { + return $this->ClientID.'_Container'; + } + + /** + * Renders the repeater. + * If the repeater did not pass the prerender phase yet, it will register itself for rendering later. + * Else it will call the {@link renderRepeater()} method which will do the rendering of the repeater. + * @param THtmlWriter writer for the rendering purpose + */ + public function render($writer) { + if($this->getHasPreRendered()) { + $this->renderRepeater($writer); + if($this->getActiveControl()->canUpdateClientSide()) $this->getPage()->getCallbackClient()->replaceContent($this->getSurroundingTagId(),$writer); + } + else { + $this->getPage()->getAdapter()->registerControlToRender($this,$writer); + } + } + + /** + * Loops through all {@link TActivePager} on the page and registers the ones which are set to paginate + * the repeater for rendering. This is to ensure that the connected pagers are also rendered if the + * data source changed. + */ + private function renderPager() { + $pager=$this->getPage()->findControlsByType('TActivePager', false); + foreach($pager as $item) { + if($item->ControlToPaginate==$this->ID) { + $writer=$this->getResponse()->createHtmlWriter(); + $this->getPage()->getAdapter()->registerControlToRender($item,$writer); + } + } + } + + /** + * Renders the repeater by writing a span tag with the container id obtained from {@link getSurroundingTagID()} + * which will be called by the replacement method of the client script to update it's content. + * @param THtmlWriter writer for the rendering purpose + */ + private function renderRepeater($writer) { + $writer->addAttribute('id',$this->getSurroundingTagID()); + $writer->renderBeginTag('span'); + parent::render($writer); + $writer->renderEndTag(); + } + +} + +?> \ No newline at end of file diff --git a/framework/Web/UI/ActiveControls/TActiveTableCell.php b/framework/Web/UI/ActiveControls/TActiveTableCell.php new file mode 100644 index 00000000..833ce6e7 --- /dev/null +++ b/framework/Web/UI/ActiveControls/TActiveTableCell.php @@ -0,0 +1,244 @@ + + * @link http://www.landwehr-software.de/ + * @copyright Copyright © 2009 LANDWEHR Computer und Software GmbH + * @license http://www.pradosoft.com/license/ + * @package System.Web.UI.ActiveControls + * @version $Id$ + */ + +/** + * Includes the following used classes + */ +Prado::using('System.Web.UI.WebControls.TTableRow'); +Prado::using('System.Web.UI.ActiveControls.TActiveControlAdapter'); +Prado::using('System.Web.UI.ActiveControls.TCallbackEventParameter'); + +/** + * TActiveTableCell class. + * + * TActiveTableCell is the active counterpart to the original {@link TTableCell} control + * and displays a table cell. The horizontal and vertical alignments of the cell + * are specified via {@link setHorizontalAlign HorizontalAlign} and + * {@link setVerticalAlign VerticalAlign} properties, respectively. + * + * TActiveTableCell allows the contents of the table cell to be changed during callback. When + * {@link onCellSelected CellSelected} property is set, selecting (clicking on) the cell will + * perform a callback request causing {@link onCellSelected OnCellSelected} event to be fired. + * + * It will also bubble the {@link onCellSelected OnCellSelected} event up to it's parent + * {@link TActiveTableRow} control which will fire up the event handlers if implemented. + * + * TActiveTableCell allows the client-side cell contents to be updated during a + * callback response by getting a new writer, invoking the render method and flushing the + * output, similar to a {@link TActivePanel} control. + * + * function callback_request($sender, $param) + * { + * $this->active_cell->render($param->getNewWriter()); + * } + * + * + * Please refer to the original documentation of the regular counterpart for usage. + * + * @author LANDWEHR Computer und Software GmbH + * @package System.Web.UI.ActiveControls + * @version $Id$ + * @since 3.2 + */ +class TActiveTableCell extends TTableCell implements ICallbackEventHandler, IActiveControl +{ + + /** + * @var TTable parent row control containing the cell + */ + private $_row; + + /** + * Creates a new callback control, sets the adapter to TActiveControlAdapter. + */ + public function __construct() + { + parent::__construct(); + $this->setAdapter(new TActiveControlAdapter($this)); + } + + /** + * @return TBaseActiveCallbackControl standard callback control options. + */ + public function getActiveControl() + { + return $this->getAdapter()->getBaseActiveControl(); + } + + /** + * @return string corresponding javascript class name for this TActiveTableCell. + */ + protected function getClientClassName() + { + return 'Prado.WebUI.TActiveTableCell'; + } + + /** + * Raises the callback event. This method is required by {@link ICallbackEventHandler} + * interface. It will raise {@link onCellSelected OnCellSelected} event with a + * {@link TActiveTableCellEventParameter} containing the zero-based index of the + * TActiveTableCell. + * This method is mainly used by framework and control developers. + * @param TCallbackEventParameter the event parameter + */ + public function raiseCallbackEvent($param) + { + $parameter = new TActiveTableCellEventParameter($this->getResponse(), $param->getCallbackParameter(), $this->getCellIndex()); + $this->onCellSelected($parameter); + $this->raiseBubbleEvent($this, $parameter); + } + + /** + * This method is invoked when a callback is requested. The method raises + * 'OnCellSelected' event to fire up the event handlers. If you override this + * method, be sure to call the parent implementation so that the event + * handler can be invoked. + * @param TActiveTableCellEventParameter event parameter to be passed to the event handlers + */ + public function onCellSelected($param) + { + $this->raiseEvent('OnCellSelected', $this, $param); + } + + /** + * Ensure that the ID attribute is rendered and registers the javascript code + * for initializing the active control if the event handler for the + * {@link onCellSelected OnCellSelected} event is set. + * @param THtmlWriter the writer responsible for rendering + */ + protected function addAttributesToRender($writer) + { + parent::addAttributesToRender($writer); + $writer->addAttribute('id', $this->getClientID()); + if ($this->hasEventHandler('OnCellSelected')) + $this->getActiveControl()->registerCallbackClientScript($this->getClientClassName(), $this->getPostBackOptions()); + } + + /** + * Renders and replaces the cell's content on the client-side. When render() is + * called before the OnPreRender event, such as when render() is called during + * a callback event handler, the rendering is defered until OnPreRender event + * is raised. + * @param THtmlWriter html writer + */ + public function render($writer) + { + if ($this->getHasPreRendered()) + { + parent::render($writer); + if ($this->getActiveControl()->canUpdateClientSide()) + $this->getPage()->getCallbackClient()->replaceContent($this, $writer); + } + else { + $this->getPage()->getAdapter()->registerControlToRender($this, $writer); + // If we update a TActiveTableCell on callback, we shouldn't update all childs, + // because the whole content will be replaced by the parent. + if ($this->getHasControls()) + { + foreach ($this->findControlsByType('IActiveControl', false) as $control) + $control->getActiveControl()->setEnableUpdate(false); + } + } + } + + /** + * Returns postback specifications for the table cell. + * This method is used by framework and control developers. + * @return array parameters about how the row defines its postback behavior. + */ + protected function getPostBackOptions() + { + $options['ID'] = $this->getClientID(); + $options['EventTarget'] = $this->getUniqueID(); + return $options; + } + + /** + * Returns the zero-based index of the TActiveTableCell within the {@link TTableCellCollection} + * of the parent {@link TTableRow} control. Raises a {@link TConfigurationException} if the cell + * is no member of the cell collection. + * @return integer the zero-based index of the cell + */ + public function getCellIndex() + { + foreach ($this->getRow()->getCells() as $key => $row) + if ($row == $this) return $key; + throw new TConfigurationException('tactivetablecell_control_notincollection', get_class($this), $this->getUniqueID()); + } + + /** + * Returns the parent {@link TTableRow} control by looping through all parents until a {@link TTableRow} + * is found. Raises a {@link TConfigurationException} if no row control is found. + * @return TTableRow the parent row control + */ + public function getRow() + { + if ($this->_row === null) + { + $row = $this->getParent(); + while (!($row instanceof TTableRow) && $row !== null) + { + $row = $row->getParent(); + } + if ($row instanceof TTableRow) $this->_row = $row; + else throw new TConfigurationException('tactivetablecell_control_outoftable', get_class($this), $this->getUniqueID()); + } + return $this->_row; + } + +} + +/** + * TActiveTableCellEventParameter class. + * + * The TActiveTableCellEventParameter provides the parameter passed during the callback + * requestion in the {@link getCallbackParameter CallbackParameter} property. The + * callback response content (e.g. new HTML content) must be rendered + * using an THtmlWriter obtained from the {@link getNewWriter NewWriter} + * property, which returns a NEW instance of TCallbackResponseWriter. + * + * The {@link getSelectedCellIndex SelectedCellIndex} is a zero-based index of the + * TActiveTableCell , -1 if the cell is not part of the cell collection (this shouldn't + * happen though since an exception is thrown before). + * + * @author LANDWEHR Computer und Software GmbH + * @package System.Web.UI.ActiveControls + * @since 3.2 + */ +class TActiveTableCellEventParameter extends TCallbackEventParameter +{ + + /** + * @var integer the zero-based index of the cell. + */ + private $_selectedCellIndex = -1; + + /** + * Creates a new TActiveTableRowEventParameter. + */ + public function __construct($response, $parameter, $index=-1) + { + parent::__construct($response, $parameter); + $this->_selectedCellIndex = $index; + } + + /** + * Returns the zero-based index of the {@link TActiveTableCell} within the + * {@link TTableCellCollection} of the parent {@link TTableRow} control. + * @return integer the zero-based index of the cell. + */ + public function getSelectedCellIndex() + { + return $this->_selectedCellIndex; + } + +} \ No newline at end of file diff --git a/framework/Web/UI/ActiveControls/TActiveTableRow.php b/framework/Web/UI/ActiveControls/TActiveTableRow.php new file mode 100644 index 00000000..31287617 --- /dev/null +++ b/framework/Web/UI/ActiveControls/TActiveTableRow.php @@ -0,0 +1,262 @@ + + * @link http://www.landwehr-software.de/ + * @copyright Copyright © 2009 LANDWEHR Computer und Software GmbH + * @license http://www.pradosoft.com/license/ + * @package System.Web.UI.ActiveControls + * @version $Id$ + */ + +/** + * Includes the following used classes + */ +Prado::using('System.Web.UI.WebControls.TTableRow'); +Prado::using('System.Web.UI.ActiveControls.TActiveControlAdapter'); +Prado::using('System.Web.UI.ActiveControls.TCallbackEventParameter'); + +/** + * TActiveTableRow class. + * + * TActiveTableRow is the active counterpart to the original {@link TTableRow} control + * and displays a table row. The table cells in the row can be accessed + * via {@link getCells Cells}. The horizontal and vertical alignments of the row + * are specified via {@link setHorizontalAlign HorizontalAlign} and + * {@link setVerticalAlign VerticalAlign} properties, respectively. + * + * TActiveTableRow allows the contents of the table row to be changed during callback. When + * {@link onRowSelected RowSelected} property is set, selecting (clicking on) the row will + * perform a callback request causing {@link onRowSelected OnRowSelected} event to be fired. + * + * It will also respond to a bubbled {@link onCellSelected OnCellSelected} event of a + * {@link TActiveTableCell} child control and fire a {@link onRowSelected OnRowSelected} event. + * + * TActiveTableRow allows the client-side row contents to be updated during a + * callback response by getting a new writer, invoking the render method and flushing the + * output, similar to a {@link TActivePanel} control. + * + * function callback_request($sender, $param) + * { + * $this->active_row->render($param->getNewWriter()); + * } + * + * + * Please refer to the original documentation of the regular counterpart for usage. + * + * @author LANDWEHR Computer und Software GmbH + * @package System.Web.UI.ActiveControls + * @version $Id$ + * @since 3.2 + */ +class TActiveTableRow extends TTableRow implements ICallbackEventHandler, IActiveControl +{ + + /** + * @var TTable parent table control containing the row + */ + private $_table; + + /** + * Creates a new callback control, sets the adapter to TActiveControlAdapter. + * */ + public function __construct() + { + parent::__construct(); + $this->setAdapter(new TActiveControlAdapter($this)); + } + + /** + * @return TBaseActiveCallbackControl standard callback control options. + */ + public function getActiveControl() + { + return $this->getAdapter()->getBaseActiveControl(); + } + + /** + * @return string corresponding javascript class name for this TActiveTableRow. + */ + protected function getClientClassName() + { + return 'Prado.WebUI.TActiveTableRow'; + } + + /** + * Raises the callback event. This method is required by {@link ICallbackEventHandler} + * interface. It will raise {@link onRowSelected OnRowSelected} event with a + * {@link TActiveTableRowEventParameter} containing the zero-based index of the + * TActiveTableRow. + * This method is mainly used by framework and control developers. + * @param TCallbackEventParameter the event parameter + */ + public function raiseCallbackEvent($param) + { + $parameter = new TActiveTableRowEventParameter($this->getResponse(), $param->getCallbackParameter(), $this->getRowIndex()); + $this->onRowSelected($parameter); + } + + /** + * This method overrides parent's implementation and raises the control's + * callback event. This will fire the {@link onRowSelected OnRowSelected} + * event if an appropriate event handler is implemented. + * @param TControl the sender of the event + * @param TEventParameter event parameter + * @return boolean whether the event bubbling should stop here. + */ + public function bubbleEvent($sender, $param) + { + if ($param instanceof TActiveTableCellEventParameter) + { + $this->raiseCallbackEvent($param); + return true; + } + else return false; + } + + /** + * This method is invoked when a callback is requested. The method raises + * 'OnRowSelected' event to fire up the event handlers. If you override this + * method, be sure to call the parent implementation so that the event + * handler can be invoked. + * @param TActiveTableRowEventParameter event parameter to be passed to the event handlers + */ + public function onRowSelected($param) + { + $this->raiseEvent('OnRowSelected', $this, $param); + } + + /** + * Ensure that the ID attribute is rendered and registers the javascript code + * for initializing the active control if the event handler for the + * {@link onRowSelected OnRowSelected} event is set. + * @param THtmlWriter the writer responsible for rendering + */ + protected function addAttributesToRender($writer) + { + parent::addAttributesToRender($writer); + $writer->addAttribute('id', $this->getClientID()); + if ($this->hasEventHandler('OnRowSelected')) + $this->getActiveControl()->registerCallbackClientScript($this->getClientClassName(), $this->getPostBackOptions()); + } + + /** + * Renders and replaces the row's content on the client-side. When render() is + * called before the OnPreRender event, such as when render() is called during + * a callback event handler, the rendering is defered until OnPreRender event + * is raised. + * @param THtmlWriter html writer + */ + public function render($writer) + { + if ($this->getHasPreRendered()) + { + parent::render($writer); + if ($this->getActiveControl()->canUpdateClientSide()) + $this->getPage()->getCallbackClient()->replaceContent($this, $writer); + } + else + { + $this->getPage()->getAdapter()->registerControlToRender($this, $writer); + // If we update a TActiveTableRow on callback, we shouldn't update all childs, + // because the whole content will be replaced by the parent. + if ($this->getHasControls()) + { + foreach ($this->findControlsByType('IActiveControl', false) as $control) + $control->getActiveControl()->setEnableUpdate(false); + } + } + } + + /** + * Returns postback specifications for the table row. + * This method is used by framework and control developers. + * @return array parameters about how the row defines its postback behavior. + */ + protected function getPostBackOptions() + { + $options['ID'] = $this->getClientID(); + $options['EventTarget'] = $this->getUniqueID(); + return $options; + } + + /** + * Returns the zero-based index of the TActiveTableRow within the {@link TTableRowCollection} + * of the parent {@link TTable} control. Raises a {@link TConfigurationException} if the row + * is no member of the row collection. + * @return integer the zero-based index of the row + */ + public function getRowIndex() + { + foreach ($this->getTable()->getRows() as $key => $row) + if ($row == $this) return $key; + throw new TConfigurationException('tactivetablerow_control_notincollection', get_class($this), $this->getUniqueID()); + } + + /** + * Returns the parent {@link TTable} control by looping through all parents until a {@link TTable} + * is found. Raises a {@link TConfigurationException} if no table control is found. + * @return TTable the parent table control + */ + public function getTable() + { + if ($this->_table === null) + { + $table = $this->getParent(); + while (!($table instanceof TTable) && $table !== null) + { + $table = $table->getParent(); + } + if ($table instanceof TTable) $this->_table = $table; + else throw new TConfigurationException('tactivetablerow_control_outoftable', get_class($this), $this->getUniqueID()); + } + return $this->_table; + } + +} + +/** + * TActiveTableRowEventParameter class. + * + * The TActiveTableRowEventParameter provides the parameter passed during the callback + * requestion in the {@link getCallbackParameter CallbackParameter} property. The + * callback response content (e.g. new HTML content) must be rendered + * using an THtmlWriter obtained from the {@link getNewWriter NewWriter} + * property, which returns a NEW instance of TCallbackResponseWriter. + * + * The {@link getSelectedRowIndex SelectedRowIndex} is a zero-based index of the + * TActiveTableRow , -1 if the row is not part of the row collection (this shouldn't + * happen though since an exception is thrown before). + * + * @author LANDWEHR Computer und Software GmbH + * @package System.Web.UI.ActiveControls + * @since 3.2 + */ +class TActiveTableRowEventParameter extends TCallbackEventParameter +{ + /** + * @var integer the zero-based index of the row. + */ + private $_selectedRowIndex = -1; + + /** + * Creates a new TActiveTableRowEventParameter. + */ + public function __construct($response, $parameter, $index=-1) + { + parent::__construct($response, $parameter); + $this->_selectedRowIndex = $index; + } + + /** + * Returns the zero-based index of the {@link TActiveTableRow} within the + * {@link TTableRowCollection} of the parent {@link TTable} control. + * @return integer the zero-based index of the row. + */ + public function getSelectedRowIndex() + { + return $this->_selectedRowIndex; + } + +} \ No newline at end of file diff --git a/framework/Web/UI/TTemplateControlInheritable.php b/framework/Web/UI/TTemplateControlInheritable.php new file mode 100644 index 00000000..1a62740a --- /dev/null +++ b/framework/Web/UI/TTemplateControlInheritable.php @@ -0,0 +1,116 @@ + + * @link http://www.schlaue-kids.net/ + * @copyright Copyright © 2010 Schlaue-Kids.net + * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Web.UI + */ + +Prado::using('System.Web.UI.TTemplateControl'); + +/** + * TTemplateControlInheritable class. + * TTemplateControlInheritable is an extension to the base class for all controls that use templates. + * By default, a control template is assumed to be in a file under the same + * directory with the control class file. They have the same file name and + * different extension name. For template file, the extension name is ".tpl". + * If a TTemplateControlInheritable is inherited it uses the base class template unless the + * inheriting control defines an own. + * + * @author Schlaue-Kids.net + * @author Kyle Caine + * @version $Id$ + * @package System.Web.UI + * @since 3.1.8 + */ +class TTemplateControlInheritable extends TTemplateControl +{ + // methods + + /** + * Creates child controls. + * This method is overridden to load and instantiate control template. + * This method should only be used by framework and control developers. + * Uses the controls template if available or the base class template otherwise. + * + * @return void + * @throws TConfigurationException if a template control directive is invalid + */ + public function createChildControls() + { + if(null === ($_template = $this->getTemplate())) { + return $this->doCreateChildControlsFor(get_class($this)); + } + + foreach($_template->getDirective() as $_name => $_value) { + if(!is_string($_value)) { + throw new TConfigurationException('templatecontrol_directive_invalid', get_class($this), $name); + } + + $this->setSubProperty($_name, $_value); + } + + $_template->instantiateIn($this); + } + + /** + * This method creates the cild controls for the given class + * + * @param string $parentClass The class to generate the child controls for + * @return void + */ + public function doCreateChildControlsFor($parentClass) + { + if(false !== ($_parentClass = get_parent_class($parentClass)) && 'TTemplateControl' != $_parentClass) { + $this->doCreateChildControlsFor($_parentClass); + } + + $this->doTemplateForClass($parentClass); + } + + /** + * This method creates the template object for the given class + * + * @param string $p_class The class to create the template from + * @return void + * @throws TConfigurationException if a template control directive is invalid + */ + public function doTemplateForClass($parentClass) + { + if(null !== ($_template = $this->getService()->getTemplateManager()->getTemplateByClassName($parentClass))) { + foreach($_template->getDirective() as $_name => $_value) { + if(!is_string($_value)) { + throw new TConfigurationException('templatecontrol_directive_invalid', get_class(this), $_name); + } + + $this->setSubProperty($_name, $_value); + } + + $_template->instantiateIn($this); + } + } + + // getter/setter + + /** + * A source template control loads its template from external storage, + * such as file, db, rather than from within another template. + * + * @return boolean whether the current control is a source template control + */ + public function getIsSourceTemplateControl() + { + if(null !== ($_template = $this->getTemplate())) { + return $_template->getIsSourceTemplate(); + } + + return ($_template = $this->getService()->getTemplateManager()->getTemplateByClassName(get_parent_class($this))) + ? $this->_template->getIsSourceTemplate() + : false; + } +} \ No newline at end of file -- cgit v1.2.3