diff options
author | ctrlaltca <> | 2012-07-12 11:21:01 +0000 |
---|---|---|
committer | ctrlaltca <> | 2012-07-12 11:21:01 +0000 |
commit | 903ae8a581fac1e6917fc3e31d2ad8fb91df80c3 (patch) | |
tree | e08bf04f0823650a231227ac3499121270172a23 /framework/Web/UI/WebControls/TDataGrid.php | |
parent | 3e4e6e66aeb3f8fea4e1eb4237498ef9d2358f63 (diff) |
standardize the use of unix eol; use svn properties to enforce native eol
Diffstat (limited to 'framework/Web/UI/WebControls/TDataGrid.php')
-rw-r--r-- | framework/Web/UI/WebControls/TDataGrid.php | 4516 |
1 files changed, 2258 insertions, 2258 deletions
diff --git a/framework/Web/UI/WebControls/TDataGrid.php b/framework/Web/UI/WebControls/TDataGrid.php index 2af66b33..2e2c5252 100644 --- a/framework/Web/UI/WebControls/TDataGrid.php +++ b/framework/Web/UI/WebControls/TDataGrid.php @@ -1,2258 +1,2258 @@ -<?php
-/**
- * TDataGrid related class files.
- * This file contains the definition of the following classes:
- * TDataGrid, TDataGridItem, TDataGridItemCollection, TDataGridColumnCollection,
- * TDataGridPagerStyle, TDataGridItemEventParameter,
- * TDataGridCommandEventParameter, TDataGridSortCommandEventParameter,
- * TDataGridPageChangedEventParameter
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @link http://www.pradosoft.com/
- * @copyright Copyright © 2005-2012 PradoSoft
- * @license http://www.pradosoft.com/license/
- * @version $Id$
- * @package System.Web.UI.WebControls
- */
-
-/**
- * Includes TBaseList, TPagedDataSource, TDummyDataSource and TTable classes
- */
-Prado::using('System.Web.UI.WebControls.TBaseDataList');
-Prado::using('System.Collections.TPagedDataSource');
-Prado::using('System.Collections.TDummyDataSource');
-Prado::using('System.Web.UI.WebControls.TTable');
-Prado::using('System.Web.UI.WebControls.TPanel');
-Prado::using('System.Web.UI.WebControls.TDataGridPagerStyle');
-
-/**
- * TDataGrid class
- *
- * TDataGrid represents a data bound and updatable grid control.
- *
- * To populate data into the datagrid, sets its {@link setDataSource DataSource}
- * to a tabular data source and call {@link dataBind()}.
- * Each row of data will be represented by an item in the {@link getItems Items}
- * collection of the datagrid.
- *
- * An item can be at one of three states: browsing, selected and edit.
- * The state determines how the item will be displayed. For example, if an item
- * is in edit state, it may be displayed as a table row with input text boxes
- * if the columns are of type {@link TBoundColumn}; and if in browsing state,
- * they are displayed as static text.
- *
- * To change the state of an item, set {@link setEditItemIndex EditItemIndex}
- * or {@link setSelectedItemIndex SelectedItemIndex} property.
- *
- * Each datagrid item has a {@link TDataGridItem::getItemType type}
- * which tells the position and state of the item in the datalist. An item in the header
- * of the repeater is of type Header. A body item may be of either
- * Item, AlternatingItem, SelectedItem or EditItem, depending whether the item
- * index is odd or even, whether it is being selected or edited.
- *
- * A datagrid is specified with a list of columns. Each column specifies how the corresponding
- * table column will be displayed. For example, the header/footer text of that column,
- * the cells in that column, and so on. The following column types are currently
- * provided by the framework,
- * - {@link TBoundColumn}, associated with a specific field in datasource and displays the corresponding data.
- * - {@link TEditCommandColumn}, displaying edit/update/cancel command buttons
- * - {@link TButtonColumn}, displaying generic command buttons that may be bound to specific field in datasource.
- * - {@link TDropDownListColumn}, displaying a dropdown list when the item is in edit state
- * - {@link THyperLinkColumn}, displaying a hyperlink that may be bound to specific field in datasource.
- * - {@link TCheckBoxColumn}, displaying a checkbox that may be bound to specific field in datasource.
- * - {@link TTemplateColumn}, displaying content based on templates.
- *
- * There are three ways to specify columns for a datagrid.
- * <ul>
- * <li>Automatically generated based on data source.
- * By setting {@link setAutoGenerateColumns AutoGenerateColumns} to true,
- * a list of columns will be automatically generated based on the schema of the data source.
- * Each column corresponds to a column of the data.</li>
- * <li>Specified in template. For example,
- * <code>
- * <com:TDataGrid ...>
- * <com:TBoundColumn .../>
- * <com:TEditCommandColumn .../>
- * </com:TDataGrid>
- * </code>
- * </li>
- * <li>Manually created in code. Columns can be manipulated via
- * the {@link setColumns Columns} property of the datagrid. For example,
- * <code>
- * $column=new TBoundColumn;
- * $datagrid->Columns[]=$column;
- * </code>
- * </li>
- * </ul>
- * Note, automatically generated columns cannot be accessed via
- * the {@link getColumns Columns} property.
- *
- * TDataGrid supports sorting. If the {@link setAllowSorting AllowSorting}
- * is set to true, a column with nonempty {@link setSortExpression SortExpression}
- * will have its header text displayed as a clickable link button.
- * Clicking on the link button will raise {@link onSortCommand OnSortCommand}
- * event. You can respond to this event, sort the data source according
- * to the event parameter, and then invoke {@link databind()} on the datagrid
- * to show to end users the sorted data.
- *
- * TDataGrid supports paging. If the {@link setAllowPaging AllowPaging}
- * is set to true, a pager will be displayed on top and/or bottom of the table.
- * How the pager will be displayed is determined by the {@link getPagerStyle PagerStyle}
- * property. Clicking on a pager button will raise an {@link onPageIndexChanged OnPageIndexChanged}
- * event. You can respond to this event, specify the page to be displayed by
- * setting {@link setCurrentPageIndex CurrentPageIndex}</b> property,
- * and then invoke {@link databind()} on the datagrid to show to end users
- * a new page of data.
- *
- * TDataGrid supports two kinds of paging. The first one is based on the number of data items in
- * datasource. The number of pages {@link getPageCount PageCount} is calculated based
- * the item number and the {@link setPageSize PageSize} property.
- * The datagrid will manage which section of the data source to be displayed
- * based on the {@link setCurrentPageIndex CurrentPageIndex} property.
- * The second approach calculates the page number based on the
- * {@link setVirtualItemCount VirtualItemCount} property and
- * the {@link setPageSize PageSize} property. The datagrid will always
- * display from the beginning of the datasource up to the number of
- * {@link setPageSize PageSize} data items. This approach is especially
- * useful when the datasource may contain too many data items to be managed by
- * the datagrid efficiently.
- *
- * When the datagrid contains a button control that raises an {@link onCommand OnCommand}
- * event, the event will be bubbled up to the datagrid control.
- * If the event's command name is recognizable by the datagrid control,
- * a corresponding item event will be raised. The following item events will be
- * raised upon a specific command:
- * - OnEditCommand, if CommandName=edit
- * - OnCancelCommand, if CommandName=cancel
- * - OnSelectCommand, if CommandName=select
- * - OnDeleteCommand, if CommandName=delete
- * - OnUpdateCommand, if CommandName=update
- * - onPageIndexChanged, if CommandName=page
- * - OnSortCommand, if CommandName=sort
- * Note, an {@link onItemCommand OnItemCommand} event is raised in addition to
- * the above specific command events.
- *
- * TDataGrid also raises an {@link onItemCreated OnItemCreated} event for
- * every newly created datagrid item. You can respond to this event to customize
- * the content or style of the newly created item.
- *
- * Note, the data bound to the datagrid are reset to null after databinding.
- * There are several ways to access the data associated with a datagrid row:
- * - Access the data in {@link onItemDataBound OnItemDataBound} event
- * - Use {@link getDataKeys DataKeys} to obtain the data key associated with
- * the specified datagrid row and use the key to fetch the corresponding data
- * from some persistent storage such as DB.
- * - Save the data in viewstate and get it back during postbacks.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Web.UI.WebControls
- * @since 3.0
- */
-class TDataGrid extends TBaseDataList implements INamingContainer
-{
- /**
- * datagrid item types
- * @deprecated deprecated since version 3.0.4. Use TListItemType constants instead.
- */
- const IT_HEADER='Header';
- const IT_FOOTER='Footer';
- const IT_ITEM='Item';
- const IT_SEPARATOR='Separator';
- const IT_ALTERNATINGITEM='AlternatingItem';
- const IT_EDITITEM='EditItem';
- const IT_SELECTEDITEM='SelectedItem';
- const IT_PAGER='Pager';
-
- /**
- * Command name that TDataGrid understands.
- */
- const CMD_SELECT='Select';
- const CMD_EDIT='Edit';
- const CMD_UPDATE='Update';
- const CMD_DELETE='Delete';
- const CMD_CANCEL='Cancel';
- const CMD_SORT='Sort';
- const CMD_PAGE='Page';
- const CMD_PAGE_NEXT='Next';
- const CMD_PAGE_PREV='Previous';
- const CMD_PAGE_FIRST='First';
- const CMD_PAGE_LAST='Last';
-
- /**
- * @var TDataGridColumnCollection manually created column collection
- */
- private $_columns=null;
- /**
- * @var TDataGridColumnCollection automatically created column collection
- */
- private $_autoColumns=null;
- /**
- * @var TList all columns including both manually and automatically created columns
- */
- private $_allColumns=null;
- /**
- * @var TDataGridItemCollection datagrid item collection
- */
- private $_items=null;
- /**
- * @var TDataGridItem header item
- */
- private $_header=null;
- /**
- * @var TDataGridItem footer item
- */
- private $_footer=null;
- /**
- * @var TPagedDataSource paged data source object
- */
- private $_pagedDataSource=null;
- private $_topPager=null;
- private $_bottomPager=null;
- /**
- * @var ITemplate template used when empty data is bounded
- */
- private $_emptyTemplate=null;
- /**
- * @var boolean whether empty template is effective
- */
- private $_useEmptyTemplate=false;
-
- /**
- * @return string tag name (table) of the datagrid
- */
- protected function getTagName()
- {
- return 'table';
- }
-
- /**
- * @return string Name of the class used in AutoGenerateColumns mode
- */
- protected function getAutoGenerateColumnName()
- {
- return 'TBoundColumn';
- }
-
- /**
- * Adds objects parsed in template to datagrid.
- * Datagrid columns are added into {@link getColumns Columns} collection.
- * @param mixed object parsed in template
- */
- public function addParsedObject($object)
- {
- if($object instanceof TDataGridColumn)
- $this->getColumns()->add($object);
- else
- parent::addParsedObject($object); // this is needed by EmptyTemplate
- }
-
- /**
- * @return TDataGridColumnCollection manually specified datagrid columns
- */
- public function getColumns()
- {
- if(!$this->_columns)
- $this->_columns=new TDataGridColumnCollection($this);
- return $this->_columns;
- }
-
- /**
- * @return TDataGridColumnCollection automatically generated datagrid columns
- */
- public function getAutoColumns()
- {
- if(!$this->_autoColumns)
- $this->_autoColumns=new TDataGridColumnCollection($this);
- return $this->_autoColumns;
- }
-
- /**
- * @return TDataGridItemCollection datagrid item collection
- */
- public function getItems()
- {
- if(!$this->_items)
- $this->_items=new TDataGridItemCollection;
- return $this->_items;
- }
-
- /**
- * @return integer number of items
- */
- public function getItemCount()
- {
- return $this->_items?$this->_items->getCount():0;
- }
-
- /**
- * Creates a style object for the control.
- * This method creates a {@link TTableStyle} to be used by datagrid.
- * @return TTableStyle control style to be used
- */
- protected function createStyle()
- {
- return new TTableStyle;
- }
-
- /**
- * @return string the URL of the background image for the datagrid
- */
- public function getBackImageUrl()
- {
- return $this->getStyle()->getBackImageUrl();
- }
-
- /**
- * @param string the URL of the background image for the datagrid
- */
- public function setBackImageUrl($value)
- {
- $this->getStyle()->setBackImageUrl($value);
- }
-
- /**
- * @return TTableItemStyle the style for every item
- */
- public function getItemStyle()
- {
- if(($style=$this->getViewState('ItemStyle',null))===null)
- {
- $style=new TTableItemStyle;
- $this->setViewState('ItemStyle',$style,null);
- }
- return $style;
- }
-
- /**
- * @return TTableItemStyle the style for each alternating item
- */
- public function getAlternatingItemStyle()
- {
- if(($style=$this->getViewState('AlternatingItemStyle',null))===null)
- {
- $style=new TTableItemStyle;
- $this->setViewState('AlternatingItemStyle',$style,null);
- }
- return $style;
- }
-
- /**
- * @return TTableItemStyle the style for selected item
- */
- public function getSelectedItemStyle()
- {
- if(($style=$this->getViewState('SelectedItemStyle',null))===null)
- {
- $style=new TTableItemStyle;
- $this->setViewState('SelectedItemStyle',$style,null);
- }
- return $style;
- }
-
- /**
- * @return TTableItemStyle the style for edit item
- */
- public function getEditItemStyle()
- {
- if(($style=$this->getViewState('EditItemStyle',null))===null)
- {
- $style=new TTableItemStyle;
- $this->setViewState('EditItemStyle',$style,null);
- }
- return $style;
- }
-
- /**
- * @return TTableItemStyle the style for header
- */
- public function getHeaderStyle()
- {
- if(($style=$this->getViewState('HeaderStyle',null))===null)
- {
- $style=new TTableItemStyle;
- $this->setViewState('HeaderStyle',$style,null);
- }
- return $style;
- }
-
- /**
- * @return TTableItemStyle the style for footer
- */
- public function getFooterStyle()
- {
- if(($style=$this->getViewState('FooterStyle',null))===null)
- {
- $style=new TTableItemStyle;
- $this->setViewState('FooterStyle',$style,null);
- }
- return $style;
- }
-
- /**
- * @return TDataGridPagerStyle the style for pager
- */
- public function getPagerStyle()
- {
- if(($style=$this->getViewState('PagerStyle',null))===null)
- {
- $style=new TDataGridPagerStyle;
- $this->setViewState('PagerStyle',$style,null);
- }
- return $style;
- }
-
- /**
- * @return TStyle the style for thead element, if any
- * @since 3.1.1
- */
- public function getTableHeadStyle()
- {
- if(($style=$this->getViewState('TableHeadStyle',null))===null)
- {
- $style=new TStyle;
- $this->setViewState('TableHeadStyle',$style,null);
- }
- return $style;
- }
-
- /**
- * @return TStyle the style for tbody element, if any
- * @since 3.1.1
- */
- public function getTableBodyStyle()
- {
- if(($style=$this->getViewState('TableBodyStyle',null))===null)
- {
- $style=new TStyle;
- $this->setViewState('TableBodyStyle',$style,null);
- }
- return $style;
- }
-
- /**
- * @return TStyle the style for tfoot element, if any
- * @since 3.1.1
- */
- public function getTableFootStyle()
- {
- if(($style=$this->getViewState('TableFootStyle',null))===null)
- {
- $style=new TStyle;
- $this->setViewState('TableFootStyle',$style,null);
- }
- return $style;
- }
-
- /**
- * @return string caption for the datagrid
- */
- public function getCaption()
- {
- return $this->getViewState('Caption','');
- }
-
- /**
- * @param string caption for the datagrid
- */
- public function setCaption($value)
- {
- $this->setViewState('Caption',$value,'');
- }
-
- /**
- * @return TTableCaptionAlign datagrid caption alignment. Defaults to TTableCaptionAlign::NotSet.
- */
- public function getCaptionAlign()
- {
- return $this->getViewState('CaptionAlign',TTableCaptionAlign::NotSet);
- }
-
- /**
- * @param TTableCaptionAlign datagrid caption alignment. Valid values include
- */
- public function setCaptionAlign($value)
- {
- $this->setViewState('CaptionAlign',TPropertyValue::ensureEnum($value,'TTableCaptionAlign'),TTableCaptionAlign::NotSet);
- }
-
- /**
- * @return TDataGridItem the header item
- */
- public function getHeader()
- {
- return $this->_header;
- }
-
- /**
- * @return TDataGridItem the footer item
- */
- public function getFooter()
- {
- return $this->_footer;
- }
-
- /**
- * @return TDataGridPager the pager displayed at the top of datagrid. It could be null if paging is disabled.
- */
- public function getTopPager()
- {
- return $this->_topPager;
- }
-
- /**
- * @return TDataGridPager the pager displayed at the bottom of datagrid. It could be null if paging is disabled.
- */
- public function getBottomPager()
- {
- return $this->_bottomPager;
- }
-
- /**
- * @return TDataGridItem the selected item, null if no item is selected.
- */
- public function getSelectedItem()
- {
- $index=$this->getSelectedItemIndex();
- $items=$this->getItems();
- if($index>=0 && $index<$items->getCount())
- return $items->itemAt($index);
- else
- return null;
- }
-
- /**
- * @return integer the zero-based index of the selected item in {@link getItems Items}.
- * A value -1 means no item selected.
- */
- public function getSelectedItemIndex()
- {
- return $this->getViewState('SelectedItemIndex',-1);
- }
-
- /**
- * Selects an item by its index in {@link getItems Items}.
- * Previously selected item will be un-selected.
- * If the item to be selected is already in edit mode, it will remain in edit mode.
- * If the index is less than 0, any existing selection will be cleared up.
- * @param integer the selected item index
- */
- public function setSelectedItemIndex($value)
- {
- if(($value=TPropertyValue::ensureInteger($value))<0)
- $value=-1;
- if(($current=$this->getSelectedItemIndex())!==$value)
- {
- $this->setViewState('SelectedItemIndex',$value,-1);
- $items=$this->getItems();
- $itemCount=$items->getCount();
- if($current>=0 && $current<$itemCount)
- {
- $item=$items->itemAt($current);
- if($item->getItemType()!==TListItemType::EditItem)
- $item->setItemType($current%2?TListItemType::AlternatingItem:TListItemType::Item);
- }
- if($value>=0 && $value<$itemCount)
- {
- $item=$items->itemAt($value);
- if($item->getItemType()!==TListItemType::EditItem)
- $item->setItemType(TListItemType::SelectedItem);
- }
- }
- }
-
- /**
- * @return TDataGridItem the edit item
- */
- public function getEditItem()
- {
- $index=$this->getEditItemIndex();
- $items=$this->getItems();
- if($index>=0 && $index<$items->getCount())
- return $items->itemAt($index);
- else
- return null;
- }
-
- /**
- * @return integer the zero-based index of the edit item in {@link getItems Items}.
- * A value -1 means no item is in edit mode.
- */
- public function getEditItemIndex()
- {
- return $this->getViewState('EditItemIndex',-1);
- }
-
- /**
- * Edits an item by its index in {@link getItems Items}.
- * Previously editting item will change to normal item state.
- * If the index is less than 0, any existing edit item will be cleared up.
- * @param integer the edit item index
- */
- public function setEditItemIndex($value)
- {
- if(($value=TPropertyValue::ensureInteger($value))<0)
- $value=-1;
- if(($current=$this->getEditItemIndex())!==$value)
- {
- $this->setViewState('EditItemIndex',$value,-1);
- $items=$this->getItems();
- $itemCount=$items->getCount();
- if($current>=0 && $current<$itemCount)
- $items->itemAt($current)->setItemType($current%2?TListItemType::AlternatingItem:TListItemType::Item);
- if($value>=0 && $value<$itemCount)
- $items->itemAt($value)->setItemType(TListItemType::EditItem);
- }
- }
-
- /**
- * @return boolean whether sorting is enabled. Defaults to false.
- */
- public function getAllowSorting()
- {
- return $this->getViewState('AllowSorting',false);
- }
-
- /**
- * @param boolean whether sorting is enabled
- */
- public function setAllowSorting($value)
- {
- $this->setViewState('AllowSorting',TPropertyValue::ensureBoolean($value),false);
- }
-
- /**
- * @return boolean whether datagrid columns should be automatically generated. Defaults to true.
- */
- public function getAutoGenerateColumns()
- {
- return $this->getViewState('AutoGenerateColumns',true);
- }
-
- /**
- * @param boolean whether datagrid columns should be automatically generated
- */
- public function setAutoGenerateColumns($value)
- {
- $this->setViewState('AutoGenerateColumns',TPropertyValue::ensureBoolean($value),true);
- }
-
- /**
- * @return boolean whether the header should be displayed. Defaults to true.
- */
- public function getShowHeader()
- {
- return $this->getViewState('ShowHeader',true);
- }
-
- /**
- * @param boolean whether the header should be displayed
- */
- public function setShowHeader($value)
- {
- $this->setViewState('ShowHeader',TPropertyValue::ensureBoolean($value),true);
- }
-
- /**
- * @return boolean whether the footer should be displayed. Defaults to false.
- */
- public function getShowFooter()
- {
- return $this->getViewState('ShowFooter',false);
- }
-
- /**
- * @param boolean whether the footer should be displayed
- */
- public function setShowFooter($value)
- {
- $this->setViewState('ShowFooter',TPropertyValue::ensureBoolean($value),false);
- }
-
- /**
- * @return ITemplate the template applied when no data is bound to the datagrid
- */
- public function getEmptyTemplate()
- {
- return $this->_emptyTemplate;
- }
-
- /**
- * @param ITemplate the template applied when no data is bound to the datagrid
- * @throws TInvalidDataTypeException if the input is not an {@link ITemplate} or not null.
- */
- public function setEmptyTemplate($value)
- {
- if($value instanceof ITemplate || $value===null)
- $this->_emptyTemplate=$value;
- else
- throw new TInvalidDataTypeException('datagrid_template_required','EmptyTemplate');
- }
-
- /**
- * This method overrides parent's implementation to handle
- * {@link onItemCommand OnItemCommand} event which is bubbled from
- * {@link TDataGridItem} child controls.
- * If the event parameter is {@link TDataGridCommandEventParameter} and
- * the command name is a recognized one, which includes 'select', 'edit',
- * 'delete', 'update', and 'cancel' (case-insensitive), then a
- * corresponding command event is also raised (such as {@link onEditCommand OnEditCommand}).
- * This method should only be used by control developers.
- * @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 TDataGridCommandEventParameter)
- {
- $this->onItemCommand($param);
- $command=$param->getCommandName();
- if(strcasecmp($command,self::CMD_SELECT)===0)
- {
- $this->setSelectedItemIndex($param->getItem()->getItemIndex());
- $this->onSelectedIndexChanged($param);
- return true;
- }
- else if(strcasecmp($command,self::CMD_EDIT)===0)
- {
- $this->onEditCommand($param);
- return true;
- }
- else if(strcasecmp($command,self::CMD_DELETE)===0)
- {
- $this->onDeleteCommand($param);
- return true;
- }
- else if(strcasecmp($command,self::CMD_UPDATE)===0)
- {
- $this->onUpdateCommand($param);
- return true;
- }
- else if(strcasecmp($command,self::CMD_CANCEL)===0)
- {
- $this->onCancelCommand($param);
- return true;
- }
- else if(strcasecmp($command,self::CMD_SORT)===0)
- {
- $this->onSortCommand(new TDataGridSortCommandEventParameter($sender,$param));
- return true;
- }
- else if(strcasecmp($command,self::CMD_PAGE)===0)
- {
- $p=$param->getCommandParameter();
- if(strcasecmp($p,self::CMD_PAGE_NEXT)===0)
- $pageIndex=$this->getCurrentPageIndex()+1;
- else if(strcasecmp($p,self::CMD_PAGE_PREV)===0)
- $pageIndex=$this->getCurrentPageIndex()-1;
- else if(strcasecmp($p,self::CMD_PAGE_FIRST)===0)
- $pageIndex=0;
- else if(strcasecmp($p,self::CMD_PAGE_LAST)===0)
- $pageIndex=$this->getPageCount()-1;
- else
- $pageIndex=TPropertyValue::ensureInteger($p)-1;
- $this->onPageIndexChanged(new TDataGridPageChangedEventParameter($sender,$pageIndex));
- return true;
- }
- }
- return false;
- }
-
- /**
- * Raises <b>OnCancelCommand</b> event.
- * This method is invoked when a button control raises <b>OnCommand</b> event
- * with <b>cancel</b> command name.
- * @param TDataGridCommandEventParameter event parameter
- */
- public function onCancelCommand($param)
- {
- $this->raiseEvent('OnCancelCommand',$this,$param);
- }
-
- /**
- * Raises <b>OnDeleteCommand</b> event.
- * This method is invoked when a button control raises <b>OnCommand</b> event
- * with <b>delete</b> command name.
- * @param TDataGridCommandEventParameter event parameter
- */
- public function onDeleteCommand($param)
- {
- $this->raiseEvent('OnDeleteCommand',$this,$param);
- }
-
- /**
- * Raises <b>OnEditCommand</b> event.
- * This method is invoked when a button control raises <b>OnCommand</b> event
- * with <b>edit</b> command name.
- * @param TDataGridCommandEventParameter event parameter
- */
- public function onEditCommand($param)
- {
- $this->raiseEvent('OnEditCommand',$this,$param);
- }
-
- /**
- * Raises <b>OnItemCommand</b> event.
- * This method is invoked when a button control raises <b>OnCommand</b> event.
- * @param TDataGridCommandEventParameter event parameter
- */
- public function onItemCommand($param)
- {
- $this->raiseEvent('OnItemCommand',$this,$param);
- }
-
- /**
- * Raises <b>OnSortCommand</b> event.
- * This method is invoked when a button control raises <b>OnCommand</b> event
- * with <b>sort</b> command name.
- * @param TDataGridSortCommandEventParameter event parameter
- */
- public function onSortCommand($param)
- {
- $this->raiseEvent('OnSortCommand',$this,$param);
- }
-
- /**
- * Raises <b>OnUpdateCommand</b> event.
- * This method is invoked when a button control raises <b>OnCommand</b> event
- * with <b>update</b> command name.
- * @param TDataGridCommandEventParameter event parameter
- */
- public function onUpdateCommand($param)
- {
- $this->raiseEvent('OnUpdateCommand',$this,$param);
- }
-
- /**
- * Raises <b>OnItemCreated</b> event.
- * This method is invoked right after a datagrid item is created and before
- * added to page hierarchy.
- * @param TDataGridItemEventParameter event parameter
- */
- public function onItemCreated($param)
- {
- $this->raiseEvent('OnItemCreated',$this,$param);
- }
-
- /**
- * Raises <b>OnPagerCreated</b> event.
- * This method is invoked right after a datagrid pager is created and before
- * added to page hierarchy.
- * @param TDataGridPagerEventParameter event parameter
- */
- public function onPagerCreated($param)
- {
- $this->raiseEvent('OnPagerCreated',$this,$param);
- }
-
- /**
- * Raises <b>OnItemDataBound</b> event.
- * This method is invoked for each datagrid item after it performs
- * databinding.
- * @param TDataGridItemEventParameter event parameter
- */
- public function onItemDataBound($param)
- {
- $this->raiseEvent('OnItemDataBound',$this,$param);
- }
-
- /**
- * Raises <b>OnPageIndexChanged</b> event.
- * This method is invoked when current page is changed.
- * @param TDataGridPageChangedEventParameter event parameter
- */
- public function onPageIndexChanged($param)
- {
- $this->raiseEvent('OnPageIndexChanged',$this,$param);
- }
-
- /**
- * Saves item count in viewstate.
- * This method is invoked right before control state is to be saved.
- */
- public function saveState()
- {
- parent::saveState();
- if(!$this->getEnableViewState(true))
- return;
- if($this->_items)
- $this->setViewState('ItemCount',$this->_items->getCount(),0);
- else
- $this->clearViewState('ItemCount');
- if($this->_autoColumns)
- {
- $state=array();
- foreach($this->_autoColumns as $column)
- $state[]=$column->saveState();
- $this->setViewState('AutoColumns',$state,array());
- }
- else
- $this->clearViewState('AutoColumns');
- if($this->_columns)
- {
- $state=array();
- foreach($this->_columns as $column)
- $state[]=$column->saveState();
- $this->setViewState('Columns',$state,array());
- }
- else
- $this->clearViewState('Columns');
- }
-
- /**
- * Loads item count information from viewstate.
- * This method is invoked right after control state is loaded.
- */
- public function loadState()
- {
- parent::loadState();
- if(!$this->getEnableViewState(true))
- return;
- if(!$this->getIsDataBound())
- {
- $state=$this->getViewState('AutoColumns',array());
- if(!empty($state))
- {
- $this->_autoColumns=new TDataGridColumnCollection($this);
- foreach($state as $st)
- {
- $column=new $this->AutoGenerateColumnName;
- $column->loadState($st);
- $this->_autoColumns->add($column);
- }
- }
- else
- $this->_autoColumns=null;
- $state=$this->getViewState('Columns',array());
- if($this->_columns && $this->_columns->getCount()===count($state))
- {
- $i=0;
- foreach($this->_columns as $column)
- {
- $column->loadState($state[$i]);
- $i++;
- }
- }
- $this->restoreGridFromViewState();
- }
- }
-
- /**
- * Clears up all items in the datagrid.
- */
- public function reset()
- {
- $this->getControls()->clear();
- $this->getItems()->clear();
- $this->_header=null;
- $this->_footer=null;
- $this->_topPager=null;
- $this->_bottomPager=null;
- $this->_useEmptyTemplate=false;
- }
-
- /**
- * Restores datagrid content from viewstate.
- */
- protected function restoreGridFromViewState()
- {
- $this->reset();
-
- $allowPaging=$this->getAllowPaging();
-
- $itemCount=$this->getViewState('ItemCount',0);
- $dsIndex=$this->getViewState('DataSourceIndex',0);
-
- $columns=new TList($this->getColumns());
- $columns->mergeWith($this->_autoColumns);
- $this->_allColumns=$columns;
-
- $items=$this->getItems();
-
- if($columns->getCount())
- {
- foreach($columns as $column)
- $column->initialize();
- $selectedIndex=$this->getSelectedItemIndex();
- $editIndex=$this->getEditItemIndex();
- for($index=0;$index<$itemCount;++$index)
- {
- if($index===0)
- {
- if($allowPaging)
- $this->_topPager=$this->createPager();
- $this->_header=$this->createItemInternal(-1,-1,TListItemType::Header,false,null,$columns);
- }
- if($index===$editIndex)
- $itemType=TListItemType::EditItem;
- else if($index===$selectedIndex)
- $itemType=TListItemType::SelectedItem;
- else if($index % 2)
- $itemType=TListItemType::AlternatingItem;
- else
- $itemType=TListItemType::Item;
- $items->add($this->createItemInternal($index,$dsIndex,$itemType,false,null,$columns));
- $dsIndex++;
- }
- if($index>0)
- {
- $this->_footer=$this->createItemInternal(-1,-1,TListItemType::Footer,false,null,$columns);
- if($allowPaging)
- $this->_bottomPager=$this->createPager();
- }
- }
- if(!$dsIndex && $this->_emptyTemplate!==null)
- {
- $this->_useEmptyTemplate=true;
- $this->_emptyTemplate->instantiateIn($this);
- }
- }
-
- /**
- * Performs databinding to populate datagrid items from data source.
- * This method is invoked by {@link dataBind()}.
- * You may override this function to provide your own way of data population.
- * @param Traversable the bound data
- */
- protected function performDataBinding($data)
- {
- $this->reset();
- $keys=$this->getDataKeys();
- $keys->clear();
- $keyField=$this->getDataKeyField();
-
- // get all columns
- if($this->getAutoGenerateColumns())
- {
- $columns=new TList($this->getColumns());
- $autoColumns=$this->createAutoColumns($data);
- $columns->mergeWith($autoColumns);
- }
- else
- $columns=$this->getColumns();
- $this->_allColumns=$columns;
-
- $items=$this->getItems();
-
- $index=0;
- $allowPaging=$this->getAllowPaging() && ($data instanceof TPagedDataSource);
- $dsIndex=$allowPaging?$data->getFirstIndexInPage():0;
- $this->setViewState('DataSourceIndex',$dsIndex,0);
- if($columns->getCount())
- {
- foreach($columns as $column)
- $column->initialize();
-
- $selectedIndex=$this->getSelectedItemIndex();
- $editIndex=$this->getEditItemIndex();
- foreach($data as $key=>$row)
- {
- if($keyField!=='')
- $keys->add($this->getDataFieldValue($row,$keyField));
- else
- $keys->add($key);
- if($index===0)
- {
- if($allowPaging)
- $this->_topPager=$this->createPager();
- $this->_header=$this->createItemInternal(-1,-1,TListItemType::Header,true,null,$columns);
- }
- if($index===$editIndex)
- $itemType=TListItemType::EditItem;
- else if($index===$selectedIndex)
- $itemType=TListItemType::SelectedItem;
- else if($index % 2)
- $itemType=TListItemType::AlternatingItem;
- else
- $itemType=TListItemType::Item;
- $items->add($this->createItemInternal($index,$dsIndex,$itemType,true,$row,$columns));
- $index++;
- $dsIndex++;
- }
- if($index>0)
- {
- $this->_footer=$this->createItemInternal(-1,-1,TListItemType::Footer,true,null,$columns);
- if($allowPaging)
- $this->_bottomPager=$this->createPager();
- }
- }
- $this->setViewState('ItemCount',$index,0);
- if(!$dsIndex && $this->_emptyTemplate!==null)
- {
- $this->_useEmptyTemplate=true;
- $this->_emptyTemplate->instantiateIn($this);
- $this->dataBindChildren();
- }
- }
-
- /**
- * Merges consecutive cells who have the same text.
- * @since 3.1.1
- */
- private function groupCells()
- {
- if(($columns=$this->_allColumns)===null)
- return;
- $items=$this->getItems();
- foreach($columns as $id=>$column)
- {
- if(!$column->getEnableCellGrouping())
- continue;
- $prevCell=null;
- $prevCellText=null;
- foreach($items as $item)
- {
- $itemType=$item->getItemType();
- $cell=$item->getCells()->itemAt($id);
- if(!$cell->getVisible())
- continue;
- if($itemType===TListItemType::Item || $itemType===TListItemType::AlternatingItem || $itemType===TListItemType::SelectedItem)
- {
- if(($cellText=$this->getCellText($cell))==='')
- {
- $prevCell=null;
- $prevCellText=null;
- continue;
- }
- if($prevCell===null || $prevCellText!==$cellText)
- {
- $prevCell=$cell;
- $prevCellText=$cellText;
- }
- else
- {
- if(($rowSpan=$prevCell->getRowSpan())===0)
- $rowSpan=1;
- $prevCell->setRowSpan($rowSpan+1);
- $cell->setVisible(false);
- }
- }
- }
- }
- }
-
- private function getCellText($cell)
- {
- if(($data=$cell->getText())==='' && $cell->getHasControls())
- {
- $controls=$cell->getControls();
- foreach($controls as $control)
- {
- if($control instanceof IDataRenderer)
- return $control->getData();
- }
- }
- return $data;
- }
-
- /**
- * Creates a datagrid item instance based on the item type and index.
- * @param integer zero-based item index
- * @param TListItemType item type
- * @return TDataGridItem created data list item
- */
- protected function createItem($itemIndex,$dataSourceIndex,$itemType)
- {
- return new TDataGridItem($itemIndex,$dataSourceIndex,$itemType);
- }
-
- private function createItemInternal($itemIndex,$dataSourceIndex,$itemType,$dataBind,$dataItem,$columns)
- {
- $item=$this->createItem($itemIndex,$dataSourceIndex,$itemType);
- $this->initializeItem($item,$columns);
- $param=new TDataGridItemEventParameter($item);
- if($dataBind)
- {
- $item->setDataItem($dataItem);
- $this->onItemCreated($param);
- $this->getControls()->add($item);
- $item->dataBind();
- $this->onItemDataBound($param);
- }
- else
- {
- $this->onItemCreated($param);
- $this->getControls()->add($item);
- }
- return $item;
- }
-
- /**
- * Initializes a datagrid item and cells inside it
- * @param TDataGrid datagrid item to be initialized
- * @param TDataGridColumnCollection datagrid columns to be used to initialize the cells in the item
- */
- protected function initializeItem($item,$columns)
- {
- $cells=$item->getCells();
- $itemType=$item->getItemType();
- $index=0;
- foreach($columns as $column)
- {
- if($itemType===TListItemType::Header)
- $cell=new TTableHeaderCell;
- else
- $cell=new TTableCell;
- if(($id=$column->getID())!=='')
- $item->registerObject($id,$cell);
- $cells->add($cell);
- $column->initializeCell($cell,$index,$itemType);
- $index++;
- }
- }
-
- protected function createPager()
- {
- $pager=new TDataGridPager($this);
- $this->buildPager($pager);
- $this->onPagerCreated(new TDataGridPagerEventParameter($pager));
- $this->getControls()->add($pager);
- return $pager;
- }
-
- /**
- * Builds the pager content based on pager style.
- * @param TDataGridPager the container for the pager
- */
- protected function buildPager($pager)
- {
- switch($this->getPagerStyle()->getMode())
- {
- case TDataGridPagerMode::NextPrev:
- $this->buildNextPrevPager($pager);
- break;
- case TDataGridPagerMode::Numeric:
- $this->buildNumericPager($pager);
- break;
- }
- }
-
- /**
- * Creates a pager button.
- * Depending on the button type, a TLinkButton or a TButton may be created.
- * If it is enabled (clickable), its command name and parameter will also be set.
- * Derived classes may override this method to create additional types of buttons, such as TImageButton.
- * @param mixed the container pager instance of TActiveDatagridPager
- * @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($pager,$buttonType,$enabled,$text,$commandName,$commandParameter)
- {
- if($buttonType===TDataGridPagerButtonType::LinkButton)
- {
- if($enabled)
- $button=new TLinkButton;
- else
- {
- $button=new TLabel;
- $button->setText($text);
- return $button;
- }
- }
- else
- {
- $button=new TButton;
- if(!$enabled)
- $button->setEnabled(false);
- }
- $button->setText($text);
- $button->setCommandName($commandName);
- $button->setCommandParameter($commandParameter);
- $button->setCausesValidation(false);
- return $button;
- }
-
- /**
- * Builds a next-prev pager
- * @param TDataGridPager the container for the pager
- */
- protected function buildNextPrevPager($pager)
- {
- $style=$this->getPagerStyle();
- $buttonType=$style->getButtonType();
- $controls=$pager->getControls();
- $currentPageIndex=$this->getCurrentPageIndex();
- if($currentPageIndex===0)
- {
- if(($text=$style->getFirstPageText())!=='')
- {
- $label=$this->createPagerButton($pager,$buttonType,false,$text,'','');
- $controls->add($label);
- $controls->add("\n");
- }
-
- $label=$this->createPagerButton($pager,$buttonType,false,$style->getPrevPageText(),'','');
- $controls->add($label);
- }
- else
- {
- if(($text=$style->getFirstPageText())!=='')
- {
- $button=$this->createPagerButton($pager,$buttonType,true,$text,self::CMD_PAGE,self::CMD_PAGE_FIRST);
- $controls->add($button);
- $controls->add("\n");
- }
-
- $button=$this->createPagerButton($pager,$buttonType,true,$style->getPrevPageText(),self::CMD_PAGE,self::CMD_PAGE_PREV);
- $controls->add($button);
- }
- $controls->add("\n");
- if($currentPageIndex===$this->getPageCount()-1)
- {
- $label=$this->createPagerButton($pager,$buttonType,false,$style->getNextPageText(),'','');
- $controls->add($label);
- if(($text=$style->getLastPageText())!=='')
- {
- $controls->add("\n");
- $label=$this->createPagerButton($pager,$buttonType,false,$text,'','');
- $controls->add($label);
- }
- }
- else
- {
- $button=$this->createPagerButton($pager,$buttonType,true,$style->getNextPageText(),self::CMD_PAGE,self::CMD_PAGE_NEXT);
- $controls->add($button);
- if(($text=$style->getLastPageText())!=='')
- {
- $controls->add("\n");
- $button=$this->createPagerButton($pager,$buttonType,true,$text,self::CMD_PAGE,self::CMD_PAGE_LAST);
- $controls->add($button);
- }
- }
- }
-
- /**
- * Builds a numeric pager
- * @param TDataGridPager the container for the pager
- */
- protected function buildNumericPager($pager)
- {
- $style=$this->getPagerStyle();
- $buttonType=$style->getButtonType();
- $controls=$pager->getControls();
- $pageCount=$this->getPageCount();
- $pageIndex=$this->getCurrentPageIndex()+1;
- $maxButtonCount=$style->getPageButtonCount();
- $buttonCount=$maxButtonCount>$pageCount?$pageCount:$maxButtonCount;
- $startPageIndex=1;
- $endPageIndex=$buttonCount;
- if($pageIndex>$endPageIndex)
- {
- $startPageIndex=((int)(($pageIndex-1)/$maxButtonCount))*$maxButtonCount+1;
- if(($endPageIndex=$startPageIndex+$maxButtonCount-1)>$pageCount)
- $endPageIndex=$pageCount;
- if($endPageIndex-$startPageIndex+1<$maxButtonCount)
- {
- if(($startPageIndex=$endPageIndex-$maxButtonCount+1)<1)
- $startPageIndex=1;
- }
- }
-
- if($startPageIndex>1)
- {
- if(($text=$style->getFirstPageText())!=='')
- {
- $button=$this->createPagerButton($pager,$buttonType,true,$text,self::CMD_PAGE,self::CMD_PAGE_FIRST);
- $controls->add($button);
- $controls->add("\n");
- }
- $prevPageIndex=$startPageIndex-1;
- $button=$this->createPagerButton($pager,$buttonType,true,$style->getPrevPageText(),self::CMD_PAGE,"$prevPageIndex");
- $controls->add($button);
- $controls->add("\n");
- }
-
- for($i=$startPageIndex;$i<=$endPageIndex;++$i)
- {
- if($i===$pageIndex)
- {
- $label=$this->createPagerButton($pager,$buttonType,false,"$i",'','');
- $controls->add($label);
- }
- else
- {
- $button=$this->createPagerButton($pager,$buttonType,true,"$i",self::CMD_PAGE,"$i");
- $controls->add($button);
- }
- if($i<$endPageIndex)
- $controls->add("\n");
- }
-
- if($pageCount>$endPageIndex)
- {
- $controls->add("\n");
- $nextPageIndex=$endPageIndex+1;
- $button=$this->createPagerButton($pager,$buttonType,true,$style->getNextPageText(),self::CMD_PAGE,"$nextPageIndex");
- $controls->add($button);
- if(($text=$style->getLastPageText())!=='')
- {
- $controls->add("\n");
- $button=$this->createPagerButton($pager,$buttonType,true,$text,self::CMD_PAGE,self::CMD_PAGE_LAST);
- $controls->add($button);
- }
- }
- }
-
- /**
- * Automatically generates datagrid columns based on datasource schema
- * @param Traversable data source bound to the datagrid
- * @return TDataGridColumnCollection
- */
- protected function createAutoColumns($dataSource)
- {
- if(!$dataSource)
- return null;
- $autoColumns=$this->getAutoColumns();
- $autoColumns->clear();
- foreach($dataSource as $row)
- {
- foreach($row as $key=>$value)
- {
- $column=new $this->AutoGenerateColumnName;
- if(is_string($key))
- {
- $column->setHeaderText($key);
- $column->setDataField($key);
- $column->setSortExpression($key);
- $autoColumns->add($column);
- }
- else
- {
- $column->setHeaderText(TListItemType::Item);
- $column->setDataField($key);
- $column->setSortExpression(TListItemType::Item);
- $autoColumns->add($column);
- }
- }
- break;
- }
- return $autoColumns;
- }
-
- /**
- * Applies styles to items, header, footer and separators.
- * Item styles are applied in a hierarchical way. Style in higher hierarchy
- * will inherit from styles in lower hierarchy.
- * Starting from the lowest hierarchy, the item styles include
- * item's own style, {@link getItemStyle ItemStyle}, {@link getAlternatingItemStyle AlternatingItemStyle},
- * {@link getSelectedItemStyle SelectedItemStyle}, and {@link getEditItemStyle EditItemStyle}.
- * Therefore, if background color is set as red in {@link getItemStyle ItemStyle},
- * {@link getEditItemStyle EditItemStyle} will also have red background color
- * unless it is set to a different value explicitly.
- */
- protected function applyItemStyles()
- {
- $itemStyle=$this->getViewState('ItemStyle',null);
-
- $alternatingItemStyle=$this->getViewState('AlternatingItemStyle',null);
- if($itemStyle!==null)
- {
- if($alternatingItemStyle===null)
- $alternatingItemStyle=$itemStyle;
- else
- $alternatingItemStyle->mergeWith($itemStyle);
- }
-
- $selectedItemStyle=$this->getViewState('SelectedItemStyle',null);
-
- $editItemStyle=$this->getViewState('EditItemStyle',null);
- if($selectedItemStyle!==null)
- {
- if($editItemStyle===null)
- $editItemStyle=$selectedItemStyle;
- else
- $editItemStyle->mergeWith($selectedItemStyle);
- }
-
- $headerStyle=$this->getViewState('HeaderStyle',null);
- $footerStyle=$this->getViewState('FooterStyle',null);
- $pagerStyle=$this->getViewState('PagerStyle',null);
- $separatorStyle=$this->getViewState('SeparatorStyle',null);
-
- foreach($this->getControls() as $index=>$item)
- {
- if(!($item instanceof TDataGridItem) && !($item instanceof TDataGridPager))
- continue;
- $itemType=$item->getItemType();
- switch($itemType)
- {
- case TListItemType::Header:
- if($headerStyle)
- $item->getStyle()->mergeWith($headerStyle);
- if(!$this->getShowHeader())
- $item->setVisible(false);
- break;
- case TListItemType::Footer:
- if($footerStyle)
- $item->getStyle()->mergeWith($footerStyle);
- if(!$this->getShowFooter())
- $item->setVisible(false);
- break;
- case TListItemType::Separator:
- if($separatorStyle)
- $item->getStyle()->mergeWith($separatorStyle);
- break;
- case TListItemType::Item:
- if($itemStyle)
- $item->getStyle()->mergeWith($itemStyle);
- break;
- case TListItemType::AlternatingItem:
- if($alternatingItemStyle)
- $item->getStyle()->mergeWith($alternatingItemStyle);
- break;
- case TListItemType::SelectedItem:
- if($selectedItemStyle)
- $item->getStyle()->mergeWith($selectedItemStyle);
- if($index % 2==1)
- {
- if($itemStyle)
- $item->getStyle()->mergeWith($itemStyle);
- }
- else
- {
- if($alternatingItemStyle)
- $item->getStyle()->mergeWith($alternatingItemStyle);
- }
- break;
- case TListItemType::EditItem:
- if($editItemStyle)
- $item->getStyle()->mergeWith($editItemStyle);
- if($index % 2==1)
- {
- if($itemStyle)
- $item->getStyle()->mergeWith($itemStyle);
- }
- else
- {
- if($alternatingItemStyle)
- $item->getStyle()->mergeWith($alternatingItemStyle);
- }
- break;
- case TListItemType::Pager:
- if($pagerStyle)
- {
- $item->getStyle()->mergeWith($pagerStyle);
- if($index===0)
- {
- if($pagerStyle->getPosition()===TDataGridPagerPosition::Bottom || !$pagerStyle->getVisible())
- $item->setVisible(false);
- }
- else
- {
- if($pagerStyle->getPosition()===TDataGridPagerPosition::Top || !$pagerStyle->getVisible())
- $item->setVisible(false);
- }
- }
- break;
- default:
- break;
- }
- if($this->_columns && $itemType!==TListItemType::Pager)
- {
- $n=$this->_columns->getCount();
- $cells=$item->getCells();
- for($i=0;$i<$n;++$i)
- {
- $cell=$cells->itemAt($i);
- $column=$this->_columns->itemAt($i);
- if(!$column->getVisible())
- $cell->setVisible(false);
- else
- {
- if($itemType===TListItemType::Header)
- $style=$column->getHeaderStyle(false);
- else if($itemType===TListItemType::Footer)
- $style=$column->getFooterStyle(false);
- else
- $style=$column->getItemStyle(false);
- if($style!==null)
- $cell->getStyle()->mergeWith($style);
- }
- }
- }
- }
- }
-
- /**
- * Renders the openning tag for the datagrid control which will render table caption if present.
- * @param THtmlWriter the writer used for the rendering purpose
- */
- public function renderBeginTag($writer)
- {
- parent::renderBeginTag($writer);
- if(($caption=$this->getCaption())!=='')
- {
- if(($align=$this->getCaptionAlign())!==TTableCaptionAlign::NotSet)
- $writer->addAttribute('align',strtolower($align));
- $writer->renderBeginTag('caption');
- $writer->write($caption);
- $writer->renderEndTag();
- }
- }
-
- /**
- * Renders the datagrid.
- * @param THtmlWriter writer for the rendering purpose
- */
- public function render($writer)
- {
- if($this->getHasControls())
- {
- $this->groupCells();
- if($this->_useEmptyTemplate)
- {
- $control=new TWebControl;
- $control->setID($this->getClientID());
- $control->copyBaseAttributes($this);
- if($this->getHasStyle())
- $control->getStyle()->copyFrom($this->getStyle());
- $control->renderBeginTag($writer);
- $this->renderContents($writer);
- $control->renderEndTag($writer);
- }
- else if($this->getViewState('ItemCount',0)>0)
- {
- $this->applyItemStyles();
- if($this->_topPager)
- {
- $this->_topPager->renderControl($writer);
- $writer->writeLine();
- }
- $this->renderTable($writer);
- if($this->_bottomPager)
- {
- $writer->writeLine();
- $this->_bottomPager->renderControl($writer);
- }
- }
- }
- }
-
- /**
- * Renders the tabular data.
- * @param THtmlWriter writer
- */
- protected function renderTable($writer)
- {
- $this->renderBeginTag($writer);
- if($this->_header && $this->_header->getVisible())
- {
- $writer->writeLine();
- if($style=$this->getViewState('TableHeadStyle',null))
- $style->addAttributesToRender($writer);
- $writer->renderBeginTag('thead');
- $this->_header->render($writer);
- $writer->renderEndTag();
- }
- $writer->writeLine();
- if($style=$this->getViewState('TableBodyStyle',null))
- $style->addAttributesToRender($writer);
- $writer->renderBeginTag('tbody');
- foreach($this->getItems() as $item)
- $item->renderControl($writer);
- $writer->renderEndTag();
-
- if($this->_footer && $this->_footer->getVisible())
- {
- $writer->writeLine();
- if($style=$this->getViewState('TableFootStyle',null))
- $style->addAttributesToRender($writer);
- $writer->renderBeginTag('tfoot');
- $this->_footer->render($writer);
- $writer->renderEndTag();
- }
-
- $writer->writeLine();
- $this->renderEndTag($writer);
- }
-}
-
-/**
- * TDataGridItemEventParameter class
- *
- * TDataGridItemEventParameter encapsulates the parameter data for
- * {@link TDataGrid::onItemCreated OnItemCreated} event of {@link TDataGrid} controls.
- * The {@link getItem Item} property indicates the datagrid item related with the event.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Web.UI.WebControls
- * @since 3.0
- */
-class TDataGridItemEventParameter extends TEventParameter
-{
- /**
- * The TDataGridItem control responsible for the event.
- * @var TDataGridItem
- */
- private $_item=null;
-
- /**
- * Constructor.
- * @param TDataGridItem datagrid item related with the corresponding event
- */
- public function __construct(TDataGridItem $item)
- {
- $this->_item=$item;
- }
-
- /**
- * @return TDataGridItem datagrid item related with the corresponding event
- */
- public function getItem()
- {
- return $this->_item;
- }
-}
-
-/**
- * TDataGridPagerEventParameter class
- *
- * TDataGridPagerEventParameter encapsulates the parameter data for
- * {@link TDataGrid::onPagerCreated OnPagerCreated} event of {@link TDataGrid} controls.
- * The {@link getPager Pager} property indicates the datagrid pager related with the event.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Web.UI.WebControls
- * @since 3.0
- */
-class TDataGridPagerEventParameter extends TEventParameter
-{
- /**
- * The TDataGridPager control responsible for the event.
- * @var TDataGridPager
- */
- protected $_pager=null;
-
- /**
- * Constructor.
- * @param TDataGridPager datagrid pager related with the corresponding event
- */
- public function __construct(TDataGridPager $pager)
- {
- $this->_pager=$pager;
- }
-
- /**
- * @return TDataGridPager datagrid pager related with the corresponding event
- */
- public function getPager()
- {
- return $this->_pager;
- }
-}
-
-/**
- * TDataGridCommandEventParameter class
- *
- * TDataGridCommandEventParameter encapsulates the parameter data for
- * {@link TDataGrid::onItemCommand ItemCommand} event of {@link TDataGrid} controls.
- *
- * The {@link getItem Item} property indicates the datagrid item related with the event.
- * The {@link getCommandSource CommandSource} refers to the control that originally
- * raises the Command event.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Web.UI.WebControls
- * @since 3.0
- */
-class TDataGridCommandEventParameter extends TCommandEventParameter
-{
- /**
- * @var TDataGridItem the TDataGridItem control responsible for the event.
- */
- private $_item=null;
- /**
- * @var TControl the control originally raises the <b>Command</b> event.
- */
- private $_source=null;
-
- /**
- * Constructor.
- * @param TDataGridItem datagrid item responsible for the event
- * @param TControl original event sender
- * @param TCommandEventParameter original event parameter
- */
- public function __construct($item,$source,TCommandEventParameter $param)
- {
- $this->_item=$item;
- $this->_source=$source;
- parent::__construct($param->getCommandName(),$param->getCommandParameter());
- }
-
- /**
- * @return TDataGridItem the TDataGridItem control responsible for the event.
- */
- public function getItem()
- {
- return $this->_item;
- }
-
- /**
- * @return TControl the control originally raises the <b>Command</b> event.
- */
- public function getCommandSource()
- {
- return $this->_source;
- }
-}
-
-/**
- * TDataGridSortCommandEventParameter class
- *
- * TDataGridSortCommandEventParameter encapsulates the parameter data for
- * {@link TDataGrid::onSortCommand SortCommand} event of {@link TDataGrid} controls.
- *
- * The {@link getCommandSource CommandSource} property refers to the control
- * that originally raises the OnCommand event, while {@link getSortExpression SortExpression}
- * gives the sort expression carried with the sort command.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Web.UI.WebControls
- * @since 3.0
- */
-class TDataGridSortCommandEventParameter extends TEventParameter
-{
- /**
- * @var string sort expression
- */
- private $_sortExpression='';
- /**
- * @var TControl original event sender
- */
- private $_source=null;
-
- /**
- * Constructor.
- * @param TControl the control originally raises the <b>OnCommand</b> event.
- * @param TDataGridCommandEventParameter command event parameter
- */
- public function __construct($source,TDataGridCommandEventParameter $param)
- {
- $this->_source=$source;
- $this->_sortExpression=$param->getCommandParameter();
- }
-
- /**
- * @return TControl the control originally raises the <b>OnCommand</b> event.
- */
- public function getCommandSource()
- {
- return $this->_source;
- }
-
- /**
- * @return string sort expression
- */
- public function getSortExpression()
- {
- return $this->_sortExpression;
- }
-}
-
-/**
- * TDataGridPageChangedEventParameter class
- *
- * TDataGridPageChangedEventParameter encapsulates the parameter data for
- * {@link TDataGrid::onPageIndexChanged PageIndexChanged} event of {@link TDataGrid} controls.
- *
- * The {@link getCommandSource CommandSource} property refers to the control
- * that originally raises the OnCommand event, while {@link getNewPageIndex NewPageIndex}
- * returns the new page index carried with the page command.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Web.UI.WebControls
- * @since 3.0
- */
-class TDataGridPageChangedEventParameter extends TEventParameter
-{
- /**
- * @var integer new page index
- */
- private $_newIndex;
- /**
- * @var TControl original event sender
- */
- private $_source=null;
-
- /**
- * Constructor.
- * @param TControl the control originally raises the <b>OnCommand</b> event.
- * @param integer new page index
- */
- public function __construct($source,$newPageIndex)
- {
- $this->_source=$source;
- $this->_newIndex=$newPageIndex;
- }
-
- /**
- * @return TControl the control originally raises the <b>OnCommand</b> event.
- */
- public function getCommandSource()
- {
- return $this->_source;
- }
-
- /**
- * @return integer new page index
- */
- public function getNewPageIndex()
- {
- return $this->_newIndex;
- }
-}
-
-/**
- * TDataGridItem class
- *
- * A TDataGridItem control represents an item in the {@link TDataGrid} control,
- * such as heading section, footer section, or a data item.
- * The index and data value of the item can be accessed via {@link getItemIndex ItemIndex}>
- * and {@link getDataItem DataItem} properties, respectively. The type of the item
- * is given by {@link getItemType ItemType} property. Property {@link getDataSourceIndex DataSourceIndex}
- * gives the index of the item from the bound data source.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Web.UI.WebControls
- * @since 3.0
- */
-class TDataGridItem extends TTableRow implements INamingContainer
-{
- /**
- * @var integer index of the data item in the Items collection of datagrid
- */
- private $_itemIndex='';
- /**
- * @var integer index of the item from the bound data source
- */
- private $_dataSourceIndex=0;
- /**
- * type of the TDataGridItem
- * @var string
- */
- private $_itemType='';
- /**
- * value of the data item
- * @var mixed
- */
- private $_data=null;
-
- /**
- * Constructor.
- * @param integer zero-based index of the item in the item collection of datagrid
- * @param TListItemType item type
- */
- public function __construct($itemIndex,$dataSourceIndex,$itemType)
- {
- $this->_itemIndex=$itemIndex;
- $this->_dataSourceIndex=$dataSourceIndex;
- $this->setItemType($itemType);
- if($itemType===TListItemType::Header)
- $this->setTableSection(TTableRowSection::Header);
- else if($itemType===TListItemType::Footer)
- $this->setTableSection(TTableRowSection::Footer);
- }
-
- /**
- * @return TListItemType item type.
- */
- public function getItemType()
- {
- return $this->_itemType;
- }
-
- /**
- * @param TListItemType item type
- */
- public function setItemType($value)
- {
- $this->_itemType=TPropertyValue::ensureEnum($value,'TListItemType');
- }
-
- /**
- * @return integer zero-based index of the item in the item collection of datagrid
- */
- public function getItemIndex()
- {
- return $this->_itemIndex;
- }
-
- /**
- * @return integer the index of the datagrid item from the bound data source
- */
- public function getDataSourceIndex()
- {
- return $this->_dataSourceIndex;
- }
-
- /**
- * @return mixed data associated with the item
- * @since 3.1.0
- */
- public function getData()
- {
- return $this->_data;
- }
-
- /**
- * @param mixed data to be associated with the item
- * @since 3.1.0
- */
- public function setData($value)
- {
- $this->_data=$value;
- }
-
- /**
- * This property is deprecated since v3.1.0.
- * @return mixed data associated with the item
- * @deprecated deprecated since v3.1.0. Use {@link getData} instead.
- */
- public function getDataItem()
- {
- return $this->getData();
- }
-
- /**
- * This property is deprecated since v3.1.0.
- * @param mixed data to be associated with the item
- * @deprecated deprecated since version 3.1.0. Use {@link setData} instead.
- */
- public function setDataItem($value)
- {
- return $this->setData($value);
- }
-
- /**
- * This method overrides parent's implementation by wrapping event parameter
- * for <b>OnCommand</b> event with item information.
- * @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 TCommandEventParameter)
- {
- $this->raiseBubbleEvent($this,new TDataGridCommandEventParameter($this,$sender,$param));
- return true;
- }
- else
- return false;
- }
-}
-
-
-/**
- * TDataGridPager class.
- *
- * TDataGridPager represents a datagrid pager.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Web.UI.WebControls
- * @since 3.0
- */
-class TDataGridPager extends TPanel implements INamingContainer
-{
- private $_dataGrid;
-
- /**
- * Constructor.
- * @param TDataGrid datagrid object
- */
- public function __construct($dataGrid)
- {
- $this->_dataGrid=$dataGrid;
- }
-
- /**
- * This method overrides parent's implementation by wrapping event parameter
- * for <b>OnCommand</b> event with item information.
- * @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 TCommandEventParameter)
- {
- $this->raiseBubbleEvent($this,new TDataGridCommandEventParameter($this,$sender,$param));
- return true;
- }
- else
- return false;
- }
-
- /**
- * @return TDataGrid the datagrid owning this pager
- */
- public function getDataGrid()
- {
- return $this->_dataGrid;
- }
-
- /**
- * @return string item type.
- */
- public function getItemType()
- {
- return TListItemType::Pager;
- }
-}
-
-
-/**
- * TDataGridItemCollection class.
- *
- * TDataGridItemCollection represents a collection of data grid items.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Web.UI.WebControls
- * @since 3.0
- */
-class TDataGridItemCollection extends TList
-{
- /**
- * Inserts an item at the specified position.
- * This overrides the parent implementation by inserting only TDataGridItem.
- * @param integer the speicified position.
- * @param mixed new item
- * @throws TInvalidDataTypeException if the item to be inserted is not a TDataGridItem.
- */
- public function insertAt($index,$item)
- {
- if($item instanceof TDataGridItem)
- parent::insertAt($index,$item);
- else
- throw new TInvalidDataTypeException('datagriditemcollection_datagriditem_required');
- }
-}
-
-/**
- * TDataGridColumnCollection class.
- *
- * TDataGridColumnCollection represents a collection of data grid columns.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Web.UI.WebControls
- * @since 3.0
- */
-class TDataGridColumnCollection extends TList
-{
- /**
- * the control that owns this collection.
- * @var TControl
- */
- private $_o;
-
- /**
- * Constructor.
- * @param TDataGrid the control that owns this collection.
- */
- public function __construct(TDataGrid $owner)
- {
- $this->_o=$owner;
- }
-
- /**
- * @return TDataGrid the control that owns this collection.
- */
- protected function getOwner()
- {
- return $this->_o;
- }
-
- /**
- * Inserts an item at the specified position.
- * This overrides the parent implementation by inserting only TDataGridColumn.
- * @param integer the speicified position.
- * @param mixed new item
- * @throws TInvalidDataTypeException if the item to be inserted is not a TDataGridColumn.
- */
- public function insertAt($index,$item)
- {
- if($item instanceof TDataGridColumn)
- {
- $item->setOwner($this->_o);
- parent::insertAt($index,$item);
- }
- else
- throw new TInvalidDataTypeException('datagridcolumncollection_datagridcolumn_required');
- }
-}
-
-/**
- * TDataGridPagerMode class.
- * TDataGridPagerMode defines the enumerable type for the possible modes that a datagrid pager can take.
- *
- * The following enumerable values are defined:
- * - NextPrev: pager buttons are displayed as next and previous pages
- * - Numeric: pager buttons are displayed as numeric page numbers
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Web.UI.WebControls
- * @since 3.0.4
- */
-class TDataGridPagerMode extends TEnumerable
-{
- const NextPrev='NextPrev';
- const Numeric='Numeric';
-}
-
-
-/**
- * TDataGridPagerButtonType class.
- * TDataGridPagerButtonType defines the enumerable type for the possible types of datagrid pager buttons.
- *
- * The following enumerable values are defined:
- * - LinkButton: link buttons
- * - PushButton: form submit buttons
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Web.UI.WebControls
- * @since 3.0.4
- */
-class TDataGridPagerButtonType extends TEnumerable
-{
- const LinkButton='LinkButton';
- const PushButton='PushButton';
-}
-
-
-/**
- * TDataGridPagerPosition class.
- * TDataGridPagerPosition defines the enumerable type for the possible positions that a datagrid pager can be located at.
- *
- * The following enumerable values are defined:
- * - Bottom: pager appears only at the bottom of the data grid.
- * - Top: pager appears only at the top of the data grid.
- * - TopAndBottom: pager appears on both top and bottom of the data grid.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Id$
- * @package System.Web.UI.WebControls
- * @since 3.0.4
- */
-class TDataGridPagerPosition extends TEnumerable
-{
- const Bottom='Bottom';
- const Top='Top';
- const TopAndBottom='TopAndBottom';
-}
-
+<?php +/** + * TDataGrid related class files. + * This file contains the definition of the following classes: + * TDataGrid, TDataGridItem, TDataGridItemCollection, TDataGridColumnCollection, + * TDataGridPagerStyle, TDataGridItemEventParameter, + * TDataGridCommandEventParameter, TDataGridSortCommandEventParameter, + * TDataGridPageChangedEventParameter + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005-2012 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Web.UI.WebControls + */ + +/** + * Includes TBaseList, TPagedDataSource, TDummyDataSource and TTable classes + */ +Prado::using('System.Web.UI.WebControls.TBaseDataList'); +Prado::using('System.Collections.TPagedDataSource'); +Prado::using('System.Collections.TDummyDataSource'); +Prado::using('System.Web.UI.WebControls.TTable'); +Prado::using('System.Web.UI.WebControls.TPanel'); +Prado::using('System.Web.UI.WebControls.TDataGridPagerStyle'); + +/** + * TDataGrid class + * + * TDataGrid represents a data bound and updatable grid control. + * + * To populate data into the datagrid, sets its {@link setDataSource DataSource} + * to a tabular data source and call {@link dataBind()}. + * Each row of data will be represented by an item in the {@link getItems Items} + * collection of the datagrid. + * + * An item can be at one of three states: browsing, selected and edit. + * The state determines how the item will be displayed. For example, if an item + * is in edit state, it may be displayed as a table row with input text boxes + * if the columns are of type {@link TBoundColumn}; and if in browsing state, + * they are displayed as static text. + * + * To change the state of an item, set {@link setEditItemIndex EditItemIndex} + * or {@link setSelectedItemIndex SelectedItemIndex} property. + * + * Each datagrid item has a {@link TDataGridItem::getItemType type} + * which tells the position and state of the item in the datalist. An item in the header + * of the repeater is of type Header. A body item may be of either + * Item, AlternatingItem, SelectedItem or EditItem, depending whether the item + * index is odd or even, whether it is being selected or edited. + * + * A datagrid is specified with a list of columns. Each column specifies how the corresponding + * table column will be displayed. For example, the header/footer text of that column, + * the cells in that column, and so on. The following column types are currently + * provided by the framework, + * - {@link TBoundColumn}, associated with a specific field in datasource and displays the corresponding data. + * - {@link TEditCommandColumn}, displaying edit/update/cancel command buttons + * - {@link TButtonColumn}, displaying generic command buttons that may be bound to specific field in datasource. + * - {@link TDropDownListColumn}, displaying a dropdown list when the item is in edit state + * - {@link THyperLinkColumn}, displaying a hyperlink that may be bound to specific field in datasource. + * - {@link TCheckBoxColumn}, displaying a checkbox that may be bound to specific field in datasource. + * - {@link TTemplateColumn}, displaying content based on templates. + * + * There are three ways to specify columns for a datagrid. + * <ul> + * <li>Automatically generated based on data source. + * By setting {@link setAutoGenerateColumns AutoGenerateColumns} to true, + * a list of columns will be automatically generated based on the schema of the data source. + * Each column corresponds to a column of the data.</li> + * <li>Specified in template. For example, + * <code> + * <com:TDataGrid ...> + * <com:TBoundColumn .../> + * <com:TEditCommandColumn .../> + * </com:TDataGrid> + * </code> + * </li> + * <li>Manually created in code. Columns can be manipulated via + * the {@link setColumns Columns} property of the datagrid. For example, + * <code> + * $column=new TBoundColumn; + * $datagrid->Columns[]=$column; + * </code> + * </li> + * </ul> + * Note, automatically generated columns cannot be accessed via + * the {@link getColumns Columns} property. + * + * TDataGrid supports sorting. If the {@link setAllowSorting AllowSorting} + * is set to true, a column with nonempty {@link setSortExpression SortExpression} + * will have its header text displayed as a clickable link button. + * Clicking on the link button will raise {@link onSortCommand OnSortCommand} + * event. You can respond to this event, sort the data source according + * to the event parameter, and then invoke {@link databind()} on the datagrid + * to show to end users the sorted data. + * + * TDataGrid supports paging. If the {@link setAllowPaging AllowPaging} + * is set to true, a pager will be displayed on top and/or bottom of the table. + * How the pager will be displayed is determined by the {@link getPagerStyle PagerStyle} + * property. Clicking on a pager button will raise an {@link onPageIndexChanged OnPageIndexChanged} + * event. You can respond to this event, specify the page to be displayed by + * setting {@link setCurrentPageIndex CurrentPageIndex}</b> property, + * and then invoke {@link databind()} on the datagrid to show to end users + * a new page of data. + * + * TDataGrid supports two kinds of paging. The first one is based on the number of data items in + * datasource. The number of pages {@link getPageCount PageCount} is calculated based + * the item number and the {@link setPageSize PageSize} property. + * The datagrid will manage which section of the data source to be displayed + * based on the {@link setCurrentPageIndex CurrentPageIndex} property. + * The second approach calculates the page number based on the + * {@link setVirtualItemCount VirtualItemCount} property and + * the {@link setPageSize PageSize} property. The datagrid will always + * display from the beginning of the datasource up to the number of + * {@link setPageSize PageSize} data items. This approach is especially + * useful when the datasource may contain too many data items to be managed by + * the datagrid efficiently. + * + * When the datagrid contains a button control that raises an {@link onCommand OnCommand} + * event, the event will be bubbled up to the datagrid control. + * If the event's command name is recognizable by the datagrid control, + * a corresponding item event will be raised. The following item events will be + * raised upon a specific command: + * - OnEditCommand, if CommandName=edit + * - OnCancelCommand, if CommandName=cancel + * - OnSelectCommand, if CommandName=select + * - OnDeleteCommand, if CommandName=delete + * - OnUpdateCommand, if CommandName=update + * - onPageIndexChanged, if CommandName=page + * - OnSortCommand, if CommandName=sort + * Note, an {@link onItemCommand OnItemCommand} event is raised in addition to + * the above specific command events. + * + * TDataGrid also raises an {@link onItemCreated OnItemCreated} event for + * every newly created datagrid item. You can respond to this event to customize + * the content or style of the newly created item. + * + * Note, the data bound to the datagrid are reset to null after databinding. + * There are several ways to access the data associated with a datagrid row: + * - Access the data in {@link onItemDataBound OnItemDataBound} event + * - Use {@link getDataKeys DataKeys} to obtain the data key associated with + * the specified datagrid row and use the key to fetch the corresponding data + * from some persistent storage such as DB. + * - Save the data in viewstate and get it back during postbacks. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @version $Id$ + * @package System.Web.UI.WebControls + * @since 3.0 + */ +class TDataGrid extends TBaseDataList implements INamingContainer +{ + /** + * datagrid item types + * @deprecated deprecated since version 3.0.4. Use TListItemType constants instead. + */ + const IT_HEADER='Header'; + const IT_FOOTER='Footer'; + const IT_ITEM='Item'; + const IT_SEPARATOR='Separator'; + const IT_ALTERNATINGITEM='AlternatingItem'; + const IT_EDITITEM='EditItem'; + const IT_SELECTEDITEM='SelectedItem'; + const IT_PAGER='Pager'; + + /** + * Command name that TDataGrid understands. + */ + const CMD_SELECT='Select'; + const CMD_EDIT='Edit'; + const CMD_UPDATE='Update'; + const CMD_DELETE='Delete'; + const CMD_CANCEL='Cancel'; + const CMD_SORT='Sort'; + const CMD_PAGE='Page'; + const CMD_PAGE_NEXT='Next'; + const CMD_PAGE_PREV='Previous'; + const CMD_PAGE_FIRST='First'; + const CMD_PAGE_LAST='Last'; + + /** + * @var TDataGridColumnCollection manually created column collection + */ + private $_columns=null; + /** + * @var TDataGridColumnCollection automatically created column collection + */ + private $_autoColumns=null; + /** + * @var TList all columns including both manually and automatically created columns + */ + private $_allColumns=null; + /** + * @var TDataGridItemCollection datagrid item collection + */ + private $_items=null; + /** + * @var TDataGridItem header item + */ + private $_header=null; + /** + * @var TDataGridItem footer item + */ + private $_footer=null; + /** + * @var TPagedDataSource paged data source object + */ + private $_pagedDataSource=null; + private $_topPager=null; + private $_bottomPager=null; + /** + * @var ITemplate template used when empty data is bounded + */ + private $_emptyTemplate=null; + /** + * @var boolean whether empty template is effective + */ + private $_useEmptyTemplate=false; + + /** + * @return string tag name (table) of the datagrid + */ + protected function getTagName() + { + return 'table'; + } + + /** + * @return string Name of the class used in AutoGenerateColumns mode + */ + protected function getAutoGenerateColumnName() + { + return 'TBoundColumn'; + } + + /** + * Adds objects parsed in template to datagrid. + * Datagrid columns are added into {@link getColumns Columns} collection. + * @param mixed object parsed in template + */ + public function addParsedObject($object) + { + if($object instanceof TDataGridColumn) + $this->getColumns()->add($object); + else + parent::addParsedObject($object); // this is needed by EmptyTemplate + } + + /** + * @return TDataGridColumnCollection manually specified datagrid columns + */ + public function getColumns() + { + if(!$this->_columns) + $this->_columns=new TDataGridColumnCollection($this); + return $this->_columns; + } + + /** + * @return TDataGridColumnCollection automatically generated datagrid columns + */ + public function getAutoColumns() + { + if(!$this->_autoColumns) + $this->_autoColumns=new TDataGridColumnCollection($this); + return $this->_autoColumns; + } + + /** + * @return TDataGridItemCollection datagrid item collection + */ + public function getItems() + { + if(!$this->_items) + $this->_items=new TDataGridItemCollection; + return $this->_items; + } + + /** + * @return integer number of items + */ + public function getItemCount() + { + return $this->_items?$this->_items->getCount():0; + } + + /** + * Creates a style object for the control. + * This method creates a {@link TTableStyle} to be used by datagrid. + * @return TTableStyle control style to be used + */ + protected function createStyle() + { + return new TTableStyle; + } + + /** + * @return string the URL of the background image for the datagrid + */ + public function getBackImageUrl() + { + return $this->getStyle()->getBackImageUrl(); + } + + /** + * @param string the URL of the background image for the datagrid + */ + public function setBackImageUrl($value) + { + $this->getStyle()->setBackImageUrl($value); + } + + /** + * @return TTableItemStyle the style for every item + */ + public function getItemStyle() + { + if(($style=$this->getViewState('ItemStyle',null))===null) + { + $style=new TTableItemStyle; + $this->setViewState('ItemStyle',$style,null); + } + return $style; + } + + /** + * @return TTableItemStyle the style for each alternating item + */ + public function getAlternatingItemStyle() + { + if(($style=$this->getViewState('AlternatingItemStyle',null))===null) + { + $style=new TTableItemStyle; + $this->setViewState('AlternatingItemStyle',$style,null); + } + return $style; + } + + /** + * @return TTableItemStyle the style for selected item + */ + public function getSelectedItemStyle() + { + if(($style=$this->getViewState('SelectedItemStyle',null))===null) + { + $style=new TTableItemStyle; + $this->setViewState('SelectedItemStyle',$style,null); + } + return $style; + } + + /** + * @return TTableItemStyle the style for edit item + */ + public function getEditItemStyle() + { + if(($style=$this->getViewState('EditItemStyle',null))===null) + { + $style=new TTableItemStyle; + $this->setViewState('EditItemStyle',$style,null); + } + return $style; + } + + /** + * @return TTableItemStyle the style for header + */ + public function getHeaderStyle() + { + if(($style=$this->getViewState('HeaderStyle',null))===null) + { + $style=new TTableItemStyle; + $this->setViewState('HeaderStyle',$style,null); + } + return $style; + } + + /** + * @return TTableItemStyle the style for footer + */ + public function getFooterStyle() + { + if(($style=$this->getViewState('FooterStyle',null))===null) + { + $style=new TTableItemStyle; + $this->setViewState('FooterStyle',$style,null); + } + return $style; + } + + /** + * @return TDataGridPagerStyle the style for pager + */ + public function getPagerStyle() + { + if(($style=$this->getViewState('PagerStyle',null))===null) + { + $style=new TDataGridPagerStyle; + $this->setViewState('PagerStyle',$style,null); + } + return $style; + } + + /** + * @return TStyle the style for thead element, if any + * @since 3.1.1 + */ + public function getTableHeadStyle() + { + if(($style=$this->getViewState('TableHeadStyle',null))===null) + { + $style=new TStyle; + $this->setViewState('TableHeadStyle',$style,null); + } + return $style; + } + + /** + * @return TStyle the style for tbody element, if any + * @since 3.1.1 + */ + public function getTableBodyStyle() + { + if(($style=$this->getViewState('TableBodyStyle',null))===null) + { + $style=new TStyle; + $this->setViewState('TableBodyStyle',$style,null); + } + return $style; + } + + /** + * @return TStyle the style for tfoot element, if any + * @since 3.1.1 + */ + public function getTableFootStyle() + { + if(($style=$this->getViewState('TableFootStyle',null))===null) + { + $style=new TStyle; + $this->setViewState('TableFootStyle',$style,null); + } + return $style; + } + + /** + * @return string caption for the datagrid + */ + public function getCaption() + { + return $this->getViewState('Caption',''); + } + + /** + * @param string caption for the datagrid + */ + public function setCaption($value) + { + $this->setViewState('Caption',$value,''); + } + + /** + * @return TTableCaptionAlign datagrid caption alignment. Defaults to TTableCaptionAlign::NotSet. + */ + public function getCaptionAlign() + { + return $this->getViewState('CaptionAlign',TTableCaptionAlign::NotSet); + } + + /** + * @param TTableCaptionAlign datagrid caption alignment. Valid values include + */ + public function setCaptionAlign($value) + { + $this->setViewState('CaptionAlign',TPropertyValue::ensureEnum($value,'TTableCaptionAlign'),TTableCaptionAlign::NotSet); + } + + /** + * @return TDataGridItem the header item + */ + public function getHeader() + { + return $this->_header; + } + + /** + * @return TDataGridItem the footer item + */ + public function getFooter() + { + return $this->_footer; + } + + /** + * @return TDataGridPager the pager displayed at the top of datagrid. It could be null if paging is disabled. + */ + public function getTopPager() + { + return $this->_topPager; + } + + /** + * @return TDataGridPager the pager displayed at the bottom of datagrid. It could be null if paging is disabled. + */ + public function getBottomPager() + { + return $this->_bottomPager; + } + + /** + * @return TDataGridItem the selected item, null if no item is selected. + */ + public function getSelectedItem() + { + $index=$this->getSelectedItemIndex(); + $items=$this->getItems(); + if($index>=0 && $index<$items->getCount()) + return $items->itemAt($index); + else + return null; + } + + /** + * @return integer the zero-based index of the selected item in {@link getItems Items}. + * A value -1 means no item selected. + */ + public function getSelectedItemIndex() + { + return $this->getViewState('SelectedItemIndex',-1); + } + + /** + * Selects an item by its index in {@link getItems Items}. + * Previously selected item will be un-selected. + * If the item to be selected is already in edit mode, it will remain in edit mode. + * If the index is less than 0, any existing selection will be cleared up. + * @param integer the selected item index + */ + public function setSelectedItemIndex($value) + { + if(($value=TPropertyValue::ensureInteger($value))<0) + $value=-1; + if(($current=$this->getSelectedItemIndex())!==$value) + { + $this->setViewState('SelectedItemIndex',$value,-1); + $items=$this->getItems(); + $itemCount=$items->getCount(); + if($current>=0 && $current<$itemCount) + { + $item=$items->itemAt($current); + if($item->getItemType()!==TListItemType::EditItem) + $item->setItemType($current%2?TListItemType::AlternatingItem:TListItemType::Item); + } + if($value>=0 && $value<$itemCount) + { + $item=$items->itemAt($value); + if($item->getItemType()!==TListItemType::EditItem) + $item->setItemType(TListItemType::SelectedItem); + } + } + } + + /** + * @return TDataGridItem the edit item + */ + public function getEditItem() + { + $index=$this->getEditItemIndex(); + $items=$this->getItems(); + if($index>=0 && $index<$items->getCount()) + return $items->itemAt($index); + else + return null; + } + + /** + * @return integer the zero-based index of the edit item in {@link getItems Items}. + * A value -1 means no item is in edit mode. + */ + public function getEditItemIndex() + { + return $this->getViewState('EditItemIndex',-1); + } + + /** + * Edits an item by its index in {@link getItems Items}. + * Previously editting item will change to normal item state. + * If the index is less than 0, any existing edit item will be cleared up. + * @param integer the edit item index + */ + public function setEditItemIndex($value) + { + if(($value=TPropertyValue::ensureInteger($value))<0) + $value=-1; + if(($current=$this->getEditItemIndex())!==$value) + { + $this->setViewState('EditItemIndex',$value,-1); + $items=$this->getItems(); + $itemCount=$items->getCount(); + if($current>=0 && $current<$itemCount) + $items->itemAt($current)->setItemType($current%2?TListItemType::AlternatingItem:TListItemType::Item); + if($value>=0 && $value<$itemCount) + $items->itemAt($value)->setItemType(TListItemType::EditItem); + } + } + + /** + * @return boolean whether sorting is enabled. Defaults to false. + */ + public function getAllowSorting() + { + return $this->getViewState('AllowSorting',false); + } + + /** + * @param boolean whether sorting is enabled + */ + public function setAllowSorting($value) + { + $this->setViewState('AllowSorting',TPropertyValue::ensureBoolean($value),false); + } + + /** + * @return boolean whether datagrid columns should be automatically generated. Defaults to true. + */ + public function getAutoGenerateColumns() + { + return $this->getViewState('AutoGenerateColumns',true); + } + + /** + * @param boolean whether datagrid columns should be automatically generated + */ + public function setAutoGenerateColumns($value) + { + $this->setViewState('AutoGenerateColumns',TPropertyValue::ensureBoolean($value),true); + } + + /** + * @return boolean whether the header should be displayed. Defaults to true. + */ + public function getShowHeader() + { + return $this->getViewState('ShowHeader',true); + } + + /** + * @param boolean whether the header should be displayed + */ + public function setShowHeader($value) + { + $this->setViewState('ShowHeader',TPropertyValue::ensureBoolean($value),true); + } + + /** + * @return boolean whether the footer should be displayed. Defaults to false. + */ + public function getShowFooter() + { + return $this->getViewState('ShowFooter',false); + } + + /** + * @param boolean whether the footer should be displayed + */ + public function setShowFooter($value) + { + $this->setViewState('ShowFooter',TPropertyValue::ensureBoolean($value),false); + } + + /** + * @return ITemplate the template applied when no data is bound to the datagrid + */ + public function getEmptyTemplate() + { + return $this->_emptyTemplate; + } + + /** + * @param ITemplate the template applied when no data is bound to the datagrid + * @throws TInvalidDataTypeException if the input is not an {@link ITemplate} or not null. + */ + public function setEmptyTemplate($value) + { + if($value instanceof ITemplate || $value===null) + $this->_emptyTemplate=$value; + else + throw new TInvalidDataTypeException('datagrid_template_required','EmptyTemplate'); + } + + /** + * This method overrides parent's implementation to handle + * {@link onItemCommand OnItemCommand} event which is bubbled from + * {@link TDataGridItem} child controls. + * If the event parameter is {@link TDataGridCommandEventParameter} and + * the command name is a recognized one, which includes 'select', 'edit', + * 'delete', 'update', and 'cancel' (case-insensitive), then a + * corresponding command event is also raised (such as {@link onEditCommand OnEditCommand}). + * This method should only be used by control developers. + * @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 TDataGridCommandEventParameter) + { + $this->onItemCommand($param); + $command=$param->getCommandName(); + if(strcasecmp($command,self::CMD_SELECT)===0) + { + $this->setSelectedItemIndex($param->getItem()->getItemIndex()); + $this->onSelectedIndexChanged($param); + return true; + } + else if(strcasecmp($command,self::CMD_EDIT)===0) + { + $this->onEditCommand($param); + return true; + } + else if(strcasecmp($command,self::CMD_DELETE)===0) + { + $this->onDeleteCommand($param); + return true; + } + else if(strcasecmp($command,self::CMD_UPDATE)===0) + { + $this->onUpdateCommand($param); + return true; + } + else if(strcasecmp($command,self::CMD_CANCEL)===0) + { + $this->onCancelCommand($param); + return true; + } + else if(strcasecmp($command,self::CMD_SORT)===0) + { + $this->onSortCommand(new TDataGridSortCommandEventParameter($sender,$param)); + return true; + } + else if(strcasecmp($command,self::CMD_PAGE)===0) + { + $p=$param->getCommandParameter(); + if(strcasecmp($p,self::CMD_PAGE_NEXT)===0) + $pageIndex=$this->getCurrentPageIndex()+1; + else if(strcasecmp($p,self::CMD_PAGE_PREV)===0) + $pageIndex=$this->getCurrentPageIndex()-1; + else if(strcasecmp($p,self::CMD_PAGE_FIRST)===0) + $pageIndex=0; + else if(strcasecmp($p,self::CMD_PAGE_LAST)===0) + $pageIndex=$this->getPageCount()-1; + else + $pageIndex=TPropertyValue::ensureInteger($p)-1; + $this->onPageIndexChanged(new TDataGridPageChangedEventParameter($sender,$pageIndex)); + return true; + } + } + return false; + } + + /** + * Raises <b>OnCancelCommand</b> event. + * This method is invoked when a button control raises <b>OnCommand</b> event + * with <b>cancel</b> command name. + * @param TDataGridCommandEventParameter event parameter + */ + public function onCancelCommand($param) + { + $this->raiseEvent('OnCancelCommand',$this,$param); + } + + /** + * Raises <b>OnDeleteCommand</b> event. + * This method is invoked when a button control raises <b>OnCommand</b> event + * with <b>delete</b> command name. + * @param TDataGridCommandEventParameter event parameter + */ + public function onDeleteCommand($param) + { + $this->raiseEvent('OnDeleteCommand',$this,$param); + } + + /** + * Raises <b>OnEditCommand</b> event. + * This method is invoked when a button control raises <b>OnCommand</b> event + * with <b>edit</b> command name. + * @param TDataGridCommandEventParameter event parameter + */ + public function onEditCommand($param) + { + $this->raiseEvent('OnEditCommand',$this,$param); + } + + /** + * Raises <b>OnItemCommand</b> event. + * This method is invoked when a button control raises <b>OnCommand</b> event. + * @param TDataGridCommandEventParameter event parameter + */ + public function onItemCommand($param) + { + $this->raiseEvent('OnItemCommand',$this,$param); + } + + /** + * Raises <b>OnSortCommand</b> event. + * This method is invoked when a button control raises <b>OnCommand</b> event + * with <b>sort</b> command name. + * @param TDataGridSortCommandEventParameter event parameter + */ + public function onSortCommand($param) + { + $this->raiseEvent('OnSortCommand',$this,$param); + } + + /** + * Raises <b>OnUpdateCommand</b> event. + * This method is invoked when a button control raises <b>OnCommand</b> event + * with <b>update</b> command name. + * @param TDataGridCommandEventParameter event parameter + */ + public function onUpdateCommand($param) + { + $this->raiseEvent('OnUpdateCommand',$this,$param); + } + + /** + * Raises <b>OnItemCreated</b> event. + * This method is invoked right after a datagrid item is created and before + * added to page hierarchy. + * @param TDataGridItemEventParameter event parameter + */ + public function onItemCreated($param) + { + $this->raiseEvent('OnItemCreated',$this,$param); + } + + /** + * Raises <b>OnPagerCreated</b> event. + * This method is invoked right after a datagrid pager is created and before + * added to page hierarchy. + * @param TDataGridPagerEventParameter event parameter + */ + public function onPagerCreated($param) + { + $this->raiseEvent('OnPagerCreated',$this,$param); + } + + /** + * Raises <b>OnItemDataBound</b> event. + * This method is invoked for each datagrid item after it performs + * databinding. + * @param TDataGridItemEventParameter event parameter + */ + public function onItemDataBound($param) + { + $this->raiseEvent('OnItemDataBound',$this,$param); + } + + /** + * Raises <b>OnPageIndexChanged</b> event. + * This method is invoked when current page is changed. + * @param TDataGridPageChangedEventParameter event parameter + */ + public function onPageIndexChanged($param) + { + $this->raiseEvent('OnPageIndexChanged',$this,$param); + } + + /** + * Saves item count in viewstate. + * This method is invoked right before control state is to be saved. + */ + public function saveState() + { + parent::saveState(); + if(!$this->getEnableViewState(true)) + return; + if($this->_items) + $this->setViewState('ItemCount',$this->_items->getCount(),0); + else + $this->clearViewState('ItemCount'); + if($this->_autoColumns) + { + $state=array(); + foreach($this->_autoColumns as $column) + $state[]=$column->saveState(); + $this->setViewState('AutoColumns',$state,array()); + } + else + $this->clearViewState('AutoColumns'); + if($this->_columns) + { + $state=array(); + foreach($this->_columns as $column) + $state[]=$column->saveState(); + $this->setViewState('Columns',$state,array()); + } + else + $this->clearViewState('Columns'); + } + + /** + * Loads item count information from viewstate. + * This method is invoked right after control state is loaded. + */ + public function loadState() + { + parent::loadState(); + if(!$this->getEnableViewState(true)) + return; + if(!$this->getIsDataBound()) + { + $state=$this->getViewState('AutoColumns',array()); + if(!empty($state)) + { + $this->_autoColumns=new TDataGridColumnCollection($this); + foreach($state as $st) + { + $column=new $this->AutoGenerateColumnName; + $column->loadState($st); + $this->_autoColumns->add($column); + } + } + else + $this->_autoColumns=null; + $state=$this->getViewState('Columns',array()); + if($this->_columns && $this->_columns->getCount()===count($state)) + { + $i=0; + foreach($this->_columns as $column) + { + $column->loadState($state[$i]); + $i++; + } + } + $this->restoreGridFromViewState(); + } + } + + /** + * Clears up all items in the datagrid. + */ + public function reset() + { + $this->getControls()->clear(); + $this->getItems()->clear(); + $this->_header=null; + $this->_footer=null; + $this->_topPager=null; + $this->_bottomPager=null; + $this->_useEmptyTemplate=false; + } + + /** + * Restores datagrid content from viewstate. + */ + protected function restoreGridFromViewState() + { + $this->reset(); + + $allowPaging=$this->getAllowPaging(); + + $itemCount=$this->getViewState('ItemCount',0); + $dsIndex=$this->getViewState('DataSourceIndex',0); + + $columns=new TList($this->getColumns()); + $columns->mergeWith($this->_autoColumns); + $this->_allColumns=$columns; + + $items=$this->getItems(); + + if($columns->getCount()) + { + foreach($columns as $column) + $column->initialize(); + $selectedIndex=$this->getSelectedItemIndex(); + $editIndex=$this->getEditItemIndex(); + for($index=0;$index<$itemCount;++$index) + { + if($index===0) + { + if($allowPaging) + $this->_topPager=$this->createPager(); + $this->_header=$this->createItemInternal(-1,-1,TListItemType::Header,false,null,$columns); + } + if($index===$editIndex) + $itemType=TListItemType::EditItem; + else if($index===$selectedIndex) + $itemType=TListItemType::SelectedItem; + else if($index % 2) + $itemType=TListItemType::AlternatingItem; + else + $itemType=TListItemType::Item; + $items->add($this->createItemInternal($index,$dsIndex,$itemType,false,null,$columns)); + $dsIndex++; + } + if($index>0) + { + $this->_footer=$this->createItemInternal(-1,-1,TListItemType::Footer,false,null,$columns); + if($allowPaging) + $this->_bottomPager=$this->createPager(); + } + } + if(!$dsIndex && $this->_emptyTemplate!==null) + { + $this->_useEmptyTemplate=true; + $this->_emptyTemplate->instantiateIn($this); + } + } + + /** + * Performs databinding to populate datagrid items from data source. + * This method is invoked by {@link dataBind()}. + * You may override this function to provide your own way of data population. + * @param Traversable the bound data + */ + protected function performDataBinding($data) + { + $this->reset(); + $keys=$this->getDataKeys(); + $keys->clear(); + $keyField=$this->getDataKeyField(); + + // get all columns + if($this->getAutoGenerateColumns()) + { + $columns=new TList($this->getColumns()); + $autoColumns=$this->createAutoColumns($data); + $columns->mergeWith($autoColumns); + } + else + $columns=$this->getColumns(); + $this->_allColumns=$columns; + + $items=$this->getItems(); + + $index=0; + $allowPaging=$this->getAllowPaging() && ($data instanceof TPagedDataSource); + $dsIndex=$allowPaging?$data->getFirstIndexInPage():0; + $this->setViewState('DataSourceIndex',$dsIndex,0); + if($columns->getCount()) + { + foreach($columns as $column) + $column->initialize(); + + $selectedIndex=$this->getSelectedItemIndex(); + $editIndex=$this->getEditItemIndex(); + foreach($data as $key=>$row) + { + if($keyField!=='') + $keys->add($this->getDataFieldValue($row,$keyField)); + else + $keys->add($key); + if($index===0) + { + if($allowPaging) + $this->_topPager=$this->createPager(); + $this->_header=$this->createItemInternal(-1,-1,TListItemType::Header,true,null,$columns); + } + if($index===$editIndex) + $itemType=TListItemType::EditItem; + else if($index===$selectedIndex) + $itemType=TListItemType::SelectedItem; + else if($index % 2) + $itemType=TListItemType::AlternatingItem; + else + $itemType=TListItemType::Item; + $items->add($this->createItemInternal($index,$dsIndex,$itemType,true,$row,$columns)); + $index++; + $dsIndex++; + } + if($index>0) + { + $this->_footer=$this->createItemInternal(-1,-1,TListItemType::Footer,true,null,$columns); + if($allowPaging) + $this->_bottomPager=$this->createPager(); + } + } + $this->setViewState('ItemCount',$index,0); + if(!$dsIndex && $this->_emptyTemplate!==null) + { + $this->_useEmptyTemplate=true; + $this->_emptyTemplate->instantiateIn($this); + $this->dataBindChildren(); + } + } + + /** + * Merges consecutive cells who have the same text. + * @since 3.1.1 + */ + private function groupCells() + { + if(($columns=$this->_allColumns)===null) + return; + $items=$this->getItems(); + foreach($columns as $id=>$column) + { + if(!$column->getEnableCellGrouping()) + continue; + $prevCell=null; + $prevCellText=null; + foreach($items as $item) + { + $itemType=$item->getItemType(); + $cell=$item->getCells()->itemAt($id); + if(!$cell->getVisible()) + continue; + if($itemType===TListItemType::Item || $itemType===TListItemType::AlternatingItem || $itemType===TListItemType::SelectedItem) + { + if(($cellText=$this->getCellText($cell))==='') + { + $prevCell=null; + $prevCellText=null; + continue; + } + if($prevCell===null || $prevCellText!==$cellText) + { + $prevCell=$cell; + $prevCellText=$cellText; + } + else + { + if(($rowSpan=$prevCell->getRowSpan())===0) + $rowSpan=1; + $prevCell->setRowSpan($rowSpan+1); + $cell->setVisible(false); + } + } + } + } + } + + private function getCellText($cell) + { + if(($data=$cell->getText())==='' && $cell->getHasControls()) + { + $controls=$cell->getControls(); + foreach($controls as $control) + { + if($control instanceof IDataRenderer) + return $control->getData(); + } + } + return $data; + } + + /** + * Creates a datagrid item instance based on the item type and index. + * @param integer zero-based item index + * @param TListItemType item type + * @return TDataGridItem created data list item + */ + protected function createItem($itemIndex,$dataSourceIndex,$itemType) + { + return new TDataGridItem($itemIndex,$dataSourceIndex,$itemType); + } + + private function createItemInternal($itemIndex,$dataSourceIndex,$itemType,$dataBind,$dataItem,$columns) + { + $item=$this->createItem($itemIndex,$dataSourceIndex,$itemType); + $this->initializeItem($item,$columns); + $param=new TDataGridItemEventParameter($item); + if($dataBind) + { + $item->setDataItem($dataItem); + $this->onItemCreated($param); + $this->getControls()->add($item); + $item->dataBind(); + $this->onItemDataBound($param); + } + else + { + $this->onItemCreated($param); + $this->getControls()->add($item); + } + return $item; + } + + /** + * Initializes a datagrid item and cells inside it + * @param TDataGrid datagrid item to be initialized + * @param TDataGridColumnCollection datagrid columns to be used to initialize the cells in the item + */ + protected function initializeItem($item,$columns) + { + $cells=$item->getCells(); + $itemType=$item->getItemType(); + $index=0; + foreach($columns as $column) + { + if($itemType===TListItemType::Header) + $cell=new TTableHeaderCell; + else + $cell=new TTableCell; + if(($id=$column->getID())!=='') + $item->registerObject($id,$cell); + $cells->add($cell); + $column->initializeCell($cell,$index,$itemType); + $index++; + } + } + + protected function createPager() + { + $pager=new TDataGridPager($this); + $this->buildPager($pager); + $this->onPagerCreated(new TDataGridPagerEventParameter($pager)); + $this->getControls()->add($pager); + return $pager; + } + + /** + * Builds the pager content based on pager style. + * @param TDataGridPager the container for the pager + */ + protected function buildPager($pager) + { + switch($this->getPagerStyle()->getMode()) + { + case TDataGridPagerMode::NextPrev: + $this->buildNextPrevPager($pager); + break; + case TDataGridPagerMode::Numeric: + $this->buildNumericPager($pager); + break; + } + } + + /** + * Creates a pager button. + * Depending on the button type, a TLinkButton or a TButton may be created. + * If it is enabled (clickable), its command name and parameter will also be set. + * Derived classes may override this method to create additional types of buttons, such as TImageButton. + * @param mixed the container pager instance of TActiveDatagridPager + * @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($pager,$buttonType,$enabled,$text,$commandName,$commandParameter) + { + if($buttonType===TDataGridPagerButtonType::LinkButton) + { + if($enabled) + $button=new TLinkButton; + else + { + $button=new TLabel; + $button->setText($text); + return $button; + } + } + else + { + $button=new TButton; + if(!$enabled) + $button->setEnabled(false); + } + $button->setText($text); + $button->setCommandName($commandName); + $button->setCommandParameter($commandParameter); + $button->setCausesValidation(false); + return $button; + } + + /** + * Builds a next-prev pager + * @param TDataGridPager the container for the pager + */ + protected function buildNextPrevPager($pager) + { + $style=$this->getPagerStyle(); + $buttonType=$style->getButtonType(); + $controls=$pager->getControls(); + $currentPageIndex=$this->getCurrentPageIndex(); + if($currentPageIndex===0) + { + if(($text=$style->getFirstPageText())!=='') + { + $label=$this->createPagerButton($pager,$buttonType,false,$text,'',''); + $controls->add($label); + $controls->add("\n"); + } + + $label=$this->createPagerButton($pager,$buttonType,false,$style->getPrevPageText(),'',''); + $controls->add($label); + } + else + { + if(($text=$style->getFirstPageText())!=='') + { + $button=$this->createPagerButton($pager,$buttonType,true,$text,self::CMD_PAGE,self::CMD_PAGE_FIRST); + $controls->add($button); + $controls->add("\n"); + } + + $button=$this->createPagerButton($pager,$buttonType,true,$style->getPrevPageText(),self::CMD_PAGE,self::CMD_PAGE_PREV); + $controls->add($button); + } + $controls->add("\n"); + if($currentPageIndex===$this->getPageCount()-1) + { + $label=$this->createPagerButton($pager,$buttonType,false,$style->getNextPageText(),'',''); + $controls->add($label); + if(($text=$style->getLastPageText())!=='') + { + $controls->add("\n"); + $label=$this->createPagerButton($pager,$buttonType,false,$text,'',''); + $controls->add($label); + } + } + else + { + $button=$this->createPagerButton($pager,$buttonType,true,$style->getNextPageText(),self::CMD_PAGE,self::CMD_PAGE_NEXT); + $controls->add($button); + if(($text=$style->getLastPageText())!=='') + { + $controls->add("\n"); + $button=$this->createPagerButton($pager,$buttonType,true,$text,self::CMD_PAGE,self::CMD_PAGE_LAST); + $controls->add($button); + } + } + } + + /** + * Builds a numeric pager + * @param TDataGridPager the container for the pager + */ + protected function buildNumericPager($pager) + { + $style=$this->getPagerStyle(); + $buttonType=$style->getButtonType(); + $controls=$pager->getControls(); + $pageCount=$this->getPageCount(); + $pageIndex=$this->getCurrentPageIndex()+1; + $maxButtonCount=$style->getPageButtonCount(); + $buttonCount=$maxButtonCount>$pageCount?$pageCount:$maxButtonCount; + $startPageIndex=1; + $endPageIndex=$buttonCount; + if($pageIndex>$endPageIndex) + { + $startPageIndex=((int)(($pageIndex-1)/$maxButtonCount))*$maxButtonCount+1; + if(($endPageIndex=$startPageIndex+$maxButtonCount-1)>$pageCount) + $endPageIndex=$pageCount; + if($endPageIndex-$startPageIndex+1<$maxButtonCount) + { + if(($startPageIndex=$endPageIndex-$maxButtonCount+1)<1) + $startPageIndex=1; + } + } + + if($startPageIndex>1) + { + if(($text=$style->getFirstPageText())!=='') + { + $button=$this->createPagerButton($pager,$buttonType,true,$text,self::CMD_PAGE,self::CMD_PAGE_FIRST); + $controls->add($button); + $controls->add("\n"); + } + $prevPageIndex=$startPageIndex-1; + $button=$this->createPagerButton($pager,$buttonType,true,$style->getPrevPageText(),self::CMD_PAGE,"$prevPageIndex"); + $controls->add($button); + $controls->add("\n"); + } + + for($i=$startPageIndex;$i<=$endPageIndex;++$i) + { + if($i===$pageIndex) + { + $label=$this->createPagerButton($pager,$buttonType,false,"$i",'',''); + $controls->add($label); + } + else + { + $button=$this->createPagerButton($pager,$buttonType,true,"$i",self::CMD_PAGE,"$i"); + $controls->add($button); + } + if($i<$endPageIndex) + $controls->add("\n"); + } + + if($pageCount>$endPageIndex) + { + $controls->add("\n"); + $nextPageIndex=$endPageIndex+1; + $button=$this->createPagerButton($pager,$buttonType,true,$style->getNextPageText(),self::CMD_PAGE,"$nextPageIndex"); + $controls->add($button); + if(($text=$style->getLastPageText())!=='') + { + $controls->add("\n"); + $button=$this->createPagerButton($pager,$buttonType,true,$text,self::CMD_PAGE,self::CMD_PAGE_LAST); + $controls->add($button); + } + } + } + + /** + * Automatically generates datagrid columns based on datasource schema + * @param Traversable data source bound to the datagrid + * @return TDataGridColumnCollection + */ + protected function createAutoColumns($dataSource) + { + if(!$dataSource) + return null; + $autoColumns=$this->getAutoColumns(); + $autoColumns->clear(); + foreach($dataSource as $row) + { + foreach($row as $key=>$value) + { + $column=new $this->AutoGenerateColumnName; + if(is_string($key)) + { + $column->setHeaderText($key); + $column->setDataField($key); + $column->setSortExpression($key); + $autoColumns->add($column); + } + else + { + $column->setHeaderText(TListItemType::Item); + $column->setDataField($key); + $column->setSortExpression(TListItemType::Item); + $autoColumns->add($column); + } + } + break; + } + return $autoColumns; + } + + /** + * Applies styles to items, header, footer and separators. + * Item styles are applied in a hierarchical way. Style in higher hierarchy + * will inherit from styles in lower hierarchy. + * Starting from the lowest hierarchy, the item styles include + * item's own style, {@link getItemStyle ItemStyle}, {@link getAlternatingItemStyle AlternatingItemStyle}, + * {@link getSelectedItemStyle SelectedItemStyle}, and {@link getEditItemStyle EditItemStyle}. + * Therefore, if background color is set as red in {@link getItemStyle ItemStyle}, + * {@link getEditItemStyle EditItemStyle} will also have red background color + * unless it is set to a different value explicitly. + */ + protected function applyItemStyles() + { + $itemStyle=$this->getViewState('ItemStyle',null); + + $alternatingItemStyle=$this->getViewState('AlternatingItemStyle',null); + if($itemStyle!==null) + { + if($alternatingItemStyle===null) + $alternatingItemStyle=$itemStyle; + else + $alternatingItemStyle->mergeWith($itemStyle); + } + + $selectedItemStyle=$this->getViewState('SelectedItemStyle',null); + + $editItemStyle=$this->getViewState('EditItemStyle',null); + if($selectedItemStyle!==null) + { + if($editItemStyle===null) + $editItemStyle=$selectedItemStyle; + else + $editItemStyle->mergeWith($selectedItemStyle); + } + + $headerStyle=$this->getViewState('HeaderStyle',null); + $footerStyle=$this->getViewState('FooterStyle',null); + $pagerStyle=$this->getViewState('PagerStyle',null); + $separatorStyle=$this->getViewState('SeparatorStyle',null); + + foreach($this->getControls() as $index=>$item) + { + if(!($item instanceof TDataGridItem) && !($item instanceof TDataGridPager)) + continue; + $itemType=$item->getItemType(); + switch($itemType) + { + case TListItemType::Header: + if($headerStyle) + $item->getStyle()->mergeWith($headerStyle); + if(!$this->getShowHeader()) + $item->setVisible(false); + break; + case TListItemType::Footer: + if($footerStyle) + $item->getStyle()->mergeWith($footerStyle); + if(!$this->getShowFooter()) + $item->setVisible(false); + break; + case TListItemType::Separator: + if($separatorStyle) + $item->getStyle()->mergeWith($separatorStyle); + break; + case TListItemType::Item: + if($itemStyle) + $item->getStyle()->mergeWith($itemStyle); + break; + case TListItemType::AlternatingItem: + if($alternatingItemStyle) + $item->getStyle()->mergeWith($alternatingItemStyle); + break; + case TListItemType::SelectedItem: + if($selectedItemStyle) + $item->getStyle()->mergeWith($selectedItemStyle); + if($index % 2==1) + { + if($itemStyle) + $item->getStyle()->mergeWith($itemStyle); + } + else + { + if($alternatingItemStyle) + $item->getStyle()->mergeWith($alternatingItemStyle); + } + break; + case TListItemType::EditItem: + if($editItemStyle) + $item->getStyle()->mergeWith($editItemStyle); + if($index % 2==1) + { + if($itemStyle) + $item->getStyle()->mergeWith($itemStyle); + } + else + { + if($alternatingItemStyle) + $item->getStyle()->mergeWith($alternatingItemStyle); + } + break; + case TListItemType::Pager: + if($pagerStyle) + { + $item->getStyle()->mergeWith($pagerStyle); + if($index===0) + { + if($pagerStyle->getPosition()===TDataGridPagerPosition::Bottom || !$pagerStyle->getVisible()) + $item->setVisible(false); + } + else + { + if($pagerStyle->getPosition()===TDataGridPagerPosition::Top || !$pagerStyle->getVisible()) + $item->setVisible(false); + } + } + break; + default: + break; + } + if($this->_columns && $itemType!==TListItemType::Pager) + { + $n=$this->_columns->getCount(); + $cells=$item->getCells(); + for($i=0;$i<$n;++$i) + { + $cell=$cells->itemAt($i); + $column=$this->_columns->itemAt($i); + if(!$column->getVisible()) + $cell->setVisible(false); + else + { + if($itemType===TListItemType::Header) + $style=$column->getHeaderStyle(false); + else if($itemType===TListItemType::Footer) + $style=$column->getFooterStyle(false); + else + $style=$column->getItemStyle(false); + if($style!==null) + $cell->getStyle()->mergeWith($style); + } + } + } + } + } + + /** + * Renders the openning tag for the datagrid control which will render table caption if present. + * @param THtmlWriter the writer used for the rendering purpose + */ + public function renderBeginTag($writer) + { + parent::renderBeginTag($writer); + if(($caption=$this->getCaption())!=='') + { + if(($align=$this->getCaptionAlign())!==TTableCaptionAlign::NotSet) + $writer->addAttribute('align',strtolower($align)); + $writer->renderBeginTag('caption'); + $writer->write($caption); + $writer->renderEndTag(); + } + } + + /** + * Renders the datagrid. + * @param THtmlWriter writer for the rendering purpose + */ + public function render($writer) + { + if($this->getHasControls()) + { + $this->groupCells(); + if($this->_useEmptyTemplate) + { + $control=new TWebControl; + $control->setID($this->getClientID()); + $control->copyBaseAttributes($this); + if($this->getHasStyle()) + $control->getStyle()->copyFrom($this->getStyle()); + $control->renderBeginTag($writer); + $this->renderContents($writer); + $control->renderEndTag($writer); + } + else if($this->getViewState('ItemCount',0)>0) + { + $this->applyItemStyles(); + if($this->_topPager) + { + $this->_topPager->renderControl($writer); + $writer->writeLine(); + } + $this->renderTable($writer); + if($this->_bottomPager) + { + $writer->writeLine(); + $this->_bottomPager->renderControl($writer); + } + } + } + } + + /** + * Renders the tabular data. + * @param THtmlWriter writer + */ + protected function renderTable($writer) + { + $this->renderBeginTag($writer); + if($this->_header && $this->_header->getVisible()) + { + $writer->writeLine(); + if($style=$this->getViewState('TableHeadStyle',null)) + $style->addAttributesToRender($writer); + $writer->renderBeginTag('thead'); + $this->_header->render($writer); + $writer->renderEndTag(); + } + $writer->writeLine(); + if($style=$this->getViewState('TableBodyStyle',null)) + $style->addAttributesToRender($writer); + $writer->renderBeginTag('tbody'); + foreach($this->getItems() as $item) + $item->renderControl($writer); + $writer->renderEndTag(); + + if($this->_footer && $this->_footer->getVisible()) + { + $writer->writeLine(); + if($style=$this->getViewState('TableFootStyle',null)) + $style->addAttributesToRender($writer); + $writer->renderBeginTag('tfoot'); + $this->_footer->render($writer); + $writer->renderEndTag(); + } + + $writer->writeLine(); + $this->renderEndTag($writer); + } +} + +/** + * TDataGridItemEventParameter class + * + * TDataGridItemEventParameter encapsulates the parameter data for + * {@link TDataGrid::onItemCreated OnItemCreated} event of {@link TDataGrid} controls. + * The {@link getItem Item} property indicates the datagrid item related with the event. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @version $Id$ + * @package System.Web.UI.WebControls + * @since 3.0 + */ +class TDataGridItemEventParameter extends TEventParameter +{ + /** + * The TDataGridItem control responsible for the event. + * @var TDataGridItem + */ + private $_item=null; + + /** + * Constructor. + * @param TDataGridItem datagrid item related with the corresponding event + */ + public function __construct(TDataGridItem $item) + { + $this->_item=$item; + } + + /** + * @return TDataGridItem datagrid item related with the corresponding event + */ + public function getItem() + { + return $this->_item; + } +} + +/** + * TDataGridPagerEventParameter class + * + * TDataGridPagerEventParameter encapsulates the parameter data for + * {@link TDataGrid::onPagerCreated OnPagerCreated} event of {@link TDataGrid} controls. + * The {@link getPager Pager} property indicates the datagrid pager related with the event. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @version $Id$ + * @package System.Web.UI.WebControls + * @since 3.0 + */ +class TDataGridPagerEventParameter extends TEventParameter +{ + /** + * The TDataGridPager control responsible for the event. + * @var TDataGridPager + */ + protected $_pager=null; + + /** + * Constructor. + * @param TDataGridPager datagrid pager related with the corresponding event + */ + public function __construct(TDataGridPager $pager) + { + $this->_pager=$pager; + } + + /** + * @return TDataGridPager datagrid pager related with the corresponding event + */ + public function getPager() + { + return $this->_pager; + } +} + +/** + * TDataGridCommandEventParameter class + * + * TDataGridCommandEventParameter encapsulates the parameter data for + * {@link TDataGrid::onItemCommand ItemCommand} event of {@link TDataGrid} controls. + * + * The {@link getItem Item} property indicates the datagrid item related with the event. + * The {@link getCommandSource CommandSource} refers to the control that originally + * raises the Command event. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @version $Id$ + * @package System.Web.UI.WebControls + * @since 3.0 + */ +class TDataGridCommandEventParameter extends TCommandEventParameter +{ + /** + * @var TDataGridItem the TDataGridItem control responsible for the event. + */ + private $_item=null; + /** + * @var TControl the control originally raises the <b>Command</b> event. + */ + private $_source=null; + + /** + * Constructor. + * @param TDataGridItem datagrid item responsible for the event + * @param TControl original event sender + * @param TCommandEventParameter original event parameter + */ + public function __construct($item,$source,TCommandEventParameter $param) + { + $this->_item=$item; + $this->_source=$source; + parent::__construct($param->getCommandName(),$param->getCommandParameter()); + } + + /** + * @return TDataGridItem the TDataGridItem control responsible for the event. + */ + public function getItem() + { + return $this->_item; + } + + /** + * @return TControl the control originally raises the <b>Command</b> event. + */ + public function getCommandSource() + { + return $this->_source; + } +} + +/** + * TDataGridSortCommandEventParameter class + * + * TDataGridSortCommandEventParameter encapsulates the parameter data for + * {@link TDataGrid::onSortCommand SortCommand} event of {@link TDataGrid} controls. + * + * The {@link getCommandSource CommandSource} property refers to the control + * that originally raises the OnCommand event, while {@link getSortExpression SortExpression} + * gives the sort expression carried with the sort command. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @version $Id$ + * @package System.Web.UI.WebControls + * @since 3.0 + */ +class TDataGridSortCommandEventParameter extends TEventParameter +{ + /** + * @var string sort expression + */ + private $_sortExpression=''; + /** + * @var TControl original event sender + */ + private $_source=null; + + /** + * Constructor. + * @param TControl the control originally raises the <b>OnCommand</b> event. + * @param TDataGridCommandEventParameter command event parameter + */ + public function __construct($source,TDataGridCommandEventParameter $param) + { + $this->_source=$source; + $this->_sortExpression=$param->getCommandParameter(); + } + + /** + * @return TControl the control originally raises the <b>OnCommand</b> event. + */ + public function getCommandSource() + { + return $this->_source; + } + + /** + * @return string sort expression + */ + public function getSortExpression() + { + return $this->_sortExpression; + } +} + +/** + * TDataGridPageChangedEventParameter class + * + * TDataGridPageChangedEventParameter encapsulates the parameter data for + * {@link TDataGrid::onPageIndexChanged PageIndexChanged} event of {@link TDataGrid} controls. + * + * The {@link getCommandSource CommandSource} property refers to the control + * that originally raises the OnCommand event, while {@link getNewPageIndex NewPageIndex} + * returns the new page index carried with the page command. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @version $Id$ + * @package System.Web.UI.WebControls + * @since 3.0 + */ +class TDataGridPageChangedEventParameter extends TEventParameter +{ + /** + * @var integer new page index + */ + private $_newIndex; + /** + * @var TControl original event sender + */ + private $_source=null; + + /** + * Constructor. + * @param TControl the control originally raises the <b>OnCommand</b> event. + * @param integer new page index + */ + public function __construct($source,$newPageIndex) + { + $this->_source=$source; + $this->_newIndex=$newPageIndex; + } + + /** + * @return TControl the control originally raises the <b>OnCommand</b> event. + */ + public function getCommandSource() + { + return $this->_source; + } + + /** + * @return integer new page index + */ + public function getNewPageIndex() + { + return $this->_newIndex; + } +} + +/** + * TDataGridItem class + * + * A TDataGridItem control represents an item in the {@link TDataGrid} control, + * such as heading section, footer section, or a data item. + * The index and data value of the item can be accessed via {@link getItemIndex ItemIndex}> + * and {@link getDataItem DataItem} properties, respectively. The type of the item + * is given by {@link getItemType ItemType} property. Property {@link getDataSourceIndex DataSourceIndex} + * gives the index of the item from the bound data source. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @version $Id$ + * @package System.Web.UI.WebControls + * @since 3.0 + */ +class TDataGridItem extends TTableRow implements INamingContainer +{ + /** + * @var integer index of the data item in the Items collection of datagrid + */ + private $_itemIndex=''; + /** + * @var integer index of the item from the bound data source + */ + private $_dataSourceIndex=0; + /** + * type of the TDataGridItem + * @var string + */ + private $_itemType=''; + /** + * value of the data item + * @var mixed + */ + private $_data=null; + + /** + * Constructor. + * @param integer zero-based index of the item in the item collection of datagrid + * @param TListItemType item type + */ + public function __construct($itemIndex,$dataSourceIndex,$itemType) + { + $this->_itemIndex=$itemIndex; + $this->_dataSourceIndex=$dataSourceIndex; + $this->setItemType($itemType); + if($itemType===TListItemType::Header) + $this->setTableSection(TTableRowSection::Header); + else if($itemType===TListItemType::Footer) + $this->setTableSection(TTableRowSection::Footer); + } + + /** + * @return TListItemType item type. + */ + public function getItemType() + { + return $this->_itemType; + } + + /** + * @param TListItemType item type + */ + public function setItemType($value) + { + $this->_itemType=TPropertyValue::ensureEnum($value,'TListItemType'); + } + + /** + * @return integer zero-based index of the item in the item collection of datagrid + */ + public function getItemIndex() + { + return $this->_itemIndex; + } + + /** + * @return integer the index of the datagrid item from the bound data source + */ + public function getDataSourceIndex() + { + return $this->_dataSourceIndex; + } + + /** + * @return mixed data associated with the item + * @since 3.1.0 + */ + public function getData() + { + return $this->_data; + } + + /** + * @param mixed data to be associated with the item + * @since 3.1.0 + */ + public function setData($value) + { + $this->_data=$value; + } + + /** + * This property is deprecated since v3.1.0. + * @return mixed data associated with the item + * @deprecated deprecated since v3.1.0. Use {@link getData} instead. + */ + public function getDataItem() + { + return $this->getData(); + } + + /** + * This property is deprecated since v3.1.0. + * @param mixed data to be associated with the item + * @deprecated deprecated since version 3.1.0. Use {@link setData} instead. + */ + public function setDataItem($value) + { + return $this->setData($value); + } + + /** + * This method overrides parent's implementation by wrapping event parameter + * for <b>OnCommand</b> event with item information. + * @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 TCommandEventParameter) + { + $this->raiseBubbleEvent($this,new TDataGridCommandEventParameter($this,$sender,$param)); + return true; + } + else + return false; + } +} + + +/** + * TDataGridPager class. + * + * TDataGridPager represents a datagrid pager. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @version $Id$ + * @package System.Web.UI.WebControls + * @since 3.0 + */ +class TDataGridPager extends TPanel implements INamingContainer +{ + private $_dataGrid; + + /** + * Constructor. + * @param TDataGrid datagrid object + */ + public function __construct($dataGrid) + { + $this->_dataGrid=$dataGrid; + } + + /** + * This method overrides parent's implementation by wrapping event parameter + * for <b>OnCommand</b> event with item information. + * @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 TCommandEventParameter) + { + $this->raiseBubbleEvent($this,new TDataGridCommandEventParameter($this,$sender,$param)); + return true; + } + else + return false; + } + + /** + * @return TDataGrid the datagrid owning this pager + */ + public function getDataGrid() + { + return $this->_dataGrid; + } + + /** + * @return string item type. + */ + public function getItemType() + { + return TListItemType::Pager; + } +} + + +/** + * TDataGridItemCollection class. + * + * TDataGridItemCollection represents a collection of data grid items. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @version $Id$ + * @package System.Web.UI.WebControls + * @since 3.0 + */ +class TDataGridItemCollection extends TList +{ + /** + * Inserts an item at the specified position. + * This overrides the parent implementation by inserting only TDataGridItem. + * @param integer the speicified position. + * @param mixed new item + * @throws TInvalidDataTypeException if the item to be inserted is not a TDataGridItem. + */ + public function insertAt($index,$item) + { + if($item instanceof TDataGridItem) + parent::insertAt($index,$item); + else + throw new TInvalidDataTypeException('datagriditemcollection_datagriditem_required'); + } +} + +/** + * TDataGridColumnCollection class. + * + * TDataGridColumnCollection represents a collection of data grid columns. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @version $Id$ + * @package System.Web.UI.WebControls + * @since 3.0 + */ +class TDataGridColumnCollection extends TList +{ + /** + * the control that owns this collection. + * @var TControl + */ + private $_o; + + /** + * Constructor. + * @param TDataGrid the control that owns this collection. + */ + public function __construct(TDataGrid $owner) + { + $this->_o=$owner; + } + + /** + * @return TDataGrid the control that owns this collection. + */ + protected function getOwner() + { + return $this->_o; + } + + /** + * Inserts an item at the specified position. + * This overrides the parent implementation by inserting only TDataGridColumn. + * @param integer the speicified position. + * @param mixed new item + * @throws TInvalidDataTypeException if the item to be inserted is not a TDataGridColumn. + */ + public function insertAt($index,$item) + { + if($item instanceof TDataGridColumn) + { + $item->setOwner($this->_o); + parent::insertAt($index,$item); + } + else + throw new TInvalidDataTypeException('datagridcolumncollection_datagridcolumn_required'); + } +} + +/** + * TDataGridPagerMode class. + * TDataGridPagerMode defines the enumerable type for the possible modes that a datagrid pager can take. + * + * The following enumerable values are defined: + * - NextPrev: pager buttons are displayed as next and previous pages + * - Numeric: pager buttons are displayed as numeric page numbers + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @version $Id$ + * @package System.Web.UI.WebControls + * @since 3.0.4 + */ +class TDataGridPagerMode extends TEnumerable +{ + const NextPrev='NextPrev'; + const Numeric='Numeric'; +} + + +/** + * TDataGridPagerButtonType class. + * TDataGridPagerButtonType defines the enumerable type for the possible types of datagrid pager buttons. + * + * The following enumerable values are defined: + * - LinkButton: link buttons + * - PushButton: form submit buttons + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @version $Id$ + * @package System.Web.UI.WebControls + * @since 3.0.4 + */ +class TDataGridPagerButtonType extends TEnumerable +{ + const LinkButton='LinkButton'; + const PushButton='PushButton'; +} + + +/** + * TDataGridPagerPosition class. + * TDataGridPagerPosition defines the enumerable type for the possible positions that a datagrid pager can be located at. + * + * The following enumerable values are defined: + * - Bottom: pager appears only at the bottom of the data grid. + * - Top: pager appears only at the top of the data grid. + * - TopAndBottom: pager appears on both top and bottom of the data grid. + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @version $Id$ + * @package System.Web.UI.WebControls + * @since 3.0.4 + */ +class TDataGridPagerPosition extends TEnumerable +{ + const Bottom='Bottom'; + const Top='Top'; + const TopAndBottom='TopAndBottom'; +} + |