* @link http://www.pradosoft.com/
* @copyright Copyright © 2005-2007 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.
*
* - 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.
* - Specified in template. For example,
*
*
*
*
*
*
*
* - Manually created in code. Columns can be manipulated via
* the {@link setColumns Columns} property of the datagrid. For example,
*
* $column=new TBoundColumn;
* $datagrid->Columns[]=$column;
*
*
*
* 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} 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
* @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';
/**
* @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';
}
/**
* 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
$pageIndex=TPropertyValue::ensureInteger($p)-1;
$this->onPageIndexChanged(new TDataGridPageChangedEventParameter($sender,$pageIndex));
return true;
}
}
return false;
}
/**
* Raises OnCancelCommand event.
* This method is invoked when a button control raises OnCommand event
* with cancel command name.
* @param TDataGridCommandEventParameter event parameter
*/
public function onCancelCommand($param)
{
$this->raiseEvent('OnCancelCommand',$this,$param);
}
/**
* Raises OnDeleteCommand event.
* This method is invoked when a button control raises OnCommand event
* with delete command name.
* @param TDataGridCommandEventParameter event parameter
*/
public function onDeleteCommand($param)
{
$this->raiseEvent('OnDeleteCommand',$this,$param);
}
/**
* Raises OnEditCommand event.
* This method is invoked when a button control raises OnCommand event
* with edit command name.
* @param TDataGridCommandEventParameter event parameter
*/
public function onEditCommand($param)
{
$this->raiseEvent('OnEditCommand',$this,$param);
}
/**
* Raises OnItemCommand event.
* This method is invoked when a button control raises OnCommand event.
* @param TDataGridCommandEventParameter event parameter
*/
public function onItemCommand($param)
{
$this->raiseEvent('OnItemCommand',$this,$param);
}
/**
* Raises OnSortCommand event.
* This method is invoked when a button control raises OnCommand event
* with sort command name.
* @param TDataGridSortCommandEventParameter event parameter
*/
public function onSortCommand($param)
{
$this->raiseEvent('OnSortCommand',$this,$param);
}
/**
* Raises OnUpdateCommand event.
* This method is invoked when a button control raises OnCommand event
* with update command name.
* @param TDataGridCommandEventParameter event parameter
*/
public function onUpdateCommand($param)
{
$this->raiseEvent('OnUpdateCommand',$this,$param);
}
/**
* Raises OnItemCreated 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 OnPagerCreated 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 OnItemDataBound 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 OnPageIndexChanged 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 TBoundColumn;
$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++;
}
}
private 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 string button type, either LinkButton or PushButton
* @param boolean whether the button should be enabled
* @param string caption of the button
* @param string CommandName corresponding to the OnCommand event of the button
* @param string CommandParameter corresponding to the OnCommand event of the button
* @return mixed the button instance
*/
protected function createPagerButton($buttonType,$enabled,$text,$commandName,$commandParameter)
{
if($buttonType===TDataGridPagerButtonType::LinkButton)
{
if($enabled)
$button=new 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)
{
$label=$this->createPagerButton($buttonType,false,$style->getPrevPageText(),'','');
$controls->add($label);
}
else
{
$button=$this->createPagerButton($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($buttonType,false,$style->getNextPageText(),'','');
$controls->add($label);
}
else
{
$button=$this->createPagerButton($buttonType,true,$style->getNextPageText(),self::CMD_PAGE,self::CMD_PAGE_NEXT);
$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)
{
$prevPageIndex=$startPageIndex-1;
$button=$this->createPagerButton($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($buttonType,false,"$i",'','');
$controls->add($label);
}
else
{
$button=$this->createPagerButton($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($buttonType,true,$style->getNextPageText(),self::CMD_PAGE,"$nextPageIndex");
$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 TBoundColumn;
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
* @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
* @version $Id$
* @package System.Web.UI.WebControls
* @since 3.0
*/
class TDataGridPagerEventParameter extends TEventParameter
{
/**
* The TDataGridPager control responsible for the event.
* @var TDataGridPager
*/
private $_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
* @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 Command 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 Command 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
* @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 OnCommand 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 OnCommand 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
* @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 OnCommand event.
* @param integer new page index
*/
public function __construct($source,$newPageIndex)
{
$this->_source=$source;
$this->_newIndex=$newPageIndex;
}
/**
* @return TControl the control originally raises the OnCommand 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
* @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 OnCommand 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
* @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 OnCommand 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
* @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
* @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
* @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
* @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
* @version $Id$
* @package System.Web.UI.WebControls
* @since 3.0.4
*/
class TDataGridPagerPosition extends TEnumerable
{
const Bottom='Bottom';
const Top='Top';
const TopAndBottom='TopAndBottom';
}
?>