From f86b7d848ced181ea3c94ec1e760f0be3f58a3b1 Mon Sep 17 00:00:00 2001
From: xue <>
Date: Sun, 4 Feb 2007 17:03:45 +0000
Subject: added renderer feature to TDataList.
---
framework/Web/UI/WebControls/TDataList.php | 740 ++++++++++++++++++++++-----
framework/Web/UI/WebControls/TRepeater.php | 12 +-
framework/Web/UI/WebControls/TWebControl.php | 1 +
3 files changed, 610 insertions(+), 143 deletions(-)
(limited to 'framework/Web/UI/WebControls')
diff --git a/framework/Web/UI/WebControls/TDataList.php b/framework/Web/UI/WebControls/TDataList.php
index 63e15ebc..269e626d 100644
--- a/framework/Web/UI/WebControls/TDataList.php
+++ b/framework/Web/UI/WebControls/TDataList.php
@@ -113,7 +113,7 @@ Prado::using('System.Web.UI.WebControls.TRepeatInfo');
class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUser
{
/**
- * Command name that TDataList understands.
+ * Command name that TDataList understands. They are case-insensitive.
*/
const CMD_SELECT='Select';
const CMD_EDIT='Edit';
@@ -137,11 +137,11 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
private $_footerTemplate=null;
private $_separatorTemplate=null;
/**
- * @var TDatListItem header item
+ * @var TControl header item
*/
private $_header=null;
/**
- * @var TDatListItem footer item
+ * @var TControl footer item
*/
private $_footer=null;
@@ -163,6 +163,183 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
return $this->_items?$this->_items->getCount():0;
}
+ /**
+ * @return string the class name for datalist items. Defaults to empty, meaning not set.
+ */
+ public function getItemRenderer()
+ {
+ return $this->getViewState('ItemRenderer','');
+ }
+
+ /**
+ * Sets the item renderer class.
+ *
+ * If not empty, the class will be used to instantiate as datalist items.
+ * This property takes precedence over {@link getItemTemplate ItemTemplate}.
+ *
+ * @param string the renderer class name in namespace format.
+ * @see setItemTemplate
+ */
+ public function setItemRenderer($value)
+ {
+ $this->setViewState('ItemRenderer',$value,'');
+ }
+
+ /**
+ * @return string the class name for alternative datalist items. Defaults to empty, meaning not set.
+ */
+ public function getAlternatingItemRenderer()
+ {
+ return $this->getViewState('AlternatingItemRenderer','');
+ }
+
+ /**
+ * Sets the alternative item renderer class.
+ *
+ * If not empty, the class will be used to instantiate as alternative datalist items.
+ * This property takes precedence over {@link getAlternatingItemTemplate AlternatingItemTemplate}.
+ *
+ * @param string the renderer class name in namespace format.
+ * @see setAlternatingItemTemplate
+ */
+ public function setAlternatingItemRenderer($value)
+ {
+ $this->setViewState('AlternatingItemRenderer',$value,'');
+ }
+
+ /**
+ * @return string the class name for the datalist item being editted. Defaults to empty, meaning not set.
+ */
+ public function getEditItemRenderer()
+ {
+ return $this->getViewState('EditItemRenderer','');
+ }
+
+ /**
+ * Sets the renderer class for the datalist item being editted.
+ *
+ * If not empty, the class will be used to instantiate as the datalist item.
+ * This property takes precedence over {@link getEditItemTemplate EditItemTemplate}.
+ *
+ * @param string the renderer class name in namespace format.
+ * @see setEditItemTemplate
+ */
+ public function setEditItemRenderer($value)
+ {
+ $this->setViewState('EditItemRenderer',$value,'');
+ }
+
+ /**
+ * @return string the class name for the datalist item being selected. Defaults to empty, meaning not set.
+ */
+ public function getSelectedItemRenderer()
+ {
+ return $this->getViewState('SelectedItemRenderer','');
+ }
+
+ /**
+ * Sets the renderer class for the datalist item being selected.
+ *
+ * If not empty, the class will be used to instantiate as the datalist item.
+ * This property takes precedence over {@link getSelectedItemTemplate SelectedItemTemplate}.
+ *
+ * @param string the renderer class name in namespace format.
+ * @see setSelectedItemTemplate
+ */
+ public function setSelectedItemRenderer($value)
+ {
+ $this->setViewState('SelectedItemRenderer',$value,'');
+ }
+
+ /**
+ * @return string the class name for datalist item separators. Defaults to empty, meaning not set.
+ */
+ public function getSeparatorRenderer()
+ {
+ return $this->getViewState('SeparatorRenderer','');
+ }
+
+ /**
+ * Sets the datalist item separator renderer class.
+ *
+ * If not empty, the class will be used to instantiate as datalist item separators.
+ * This property takes precedence over {@link getSeparatorTemplate SeparatorTemplate}.
+ *
+ * @param string the renderer class name in namespace format.
+ * @see setSeparatorTemplate
+ */
+ public function setSeparatorRenderer($value)
+ {
+ $this->setViewState('SeparatorRenderer',$value,'');
+ }
+
+ /**
+ * @return string the class name for datalist header item. Defaults to empty, meaning not set.
+ */
+ public function getHeaderRenderer()
+ {
+ return $this->getViewState('HeaderRenderer','');
+ }
+
+ /**
+ * Sets the datalist header renderer class.
+ *
+ * If not empty, the class will be used to instantiate as datalist header item.
+ * This property takes precedence over {@link getHeaderTemplate HeaderTemplate}.
+ *
+ * @param string the renderer class name in namespace format.
+ * @see setHeaderTemplate
+ */
+ public function setHeaderRenderer($value)
+ {
+ $this->setViewState('HeaderRenderer',$value,'');
+ }
+
+ /**
+ * @return string the class name for datalist footer item. Defaults to empty, meaning not set.
+ */
+ public function getFooterRenderer()
+ {
+ return $this->getViewState('FooterRenderer','');
+ }
+
+ /**
+ * Sets the datalist footer renderer class.
+ *
+ * If not empty, the class will be used to instantiate as datalist footer item.
+ * This property takes precedence over {@link getFooterTemplate FooterTemplate}.
+ *
+ * @param string the renderer class name in namespace format.
+ * @see setFooterTemplate
+ */
+ public function setFooterRenderer($value)
+ {
+ $this->setViewState('FooterRenderer',$value,'');
+ }
+
+ /**
+ * @return string the class name for empty datalist item. Defaults to empty, meaning not set.
+ */
+ public function getEmptyRenderer()
+ {
+ return $this->getViewState('EmptyRenderer','');
+ }
+
+ /**
+ * Sets the datalist empty renderer class.
+ *
+ * The empty renderer is created as the child of the datalist
+ * if data bound to the datalist is empty.
+ * This property takes precedence over {@link getEmptyTemplate EmptyTemplate}.
+ *
+ * @param string the renderer class name in namespace format.
+ * @see setEmptyTemplate
+ */
+ public function setEmptyRenderer($value)
+ {
+ $this->setViewState('EmptyRenderer',$value,'');
+ }
+
/**
* @return ITemplate the template for item
*/
@@ -329,7 +506,7 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
}
/**
- * @return TDataListItem the header item
+ * @return TControl the header item
*/
public function getHeader()
{
@@ -370,7 +547,7 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
}
/**
- * @return TDataListItem the footer item
+ * @return TControl the footer item
*/
public function getFooter()
{
@@ -471,7 +648,7 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
}
/**
- * @return TDataListItem the selected item, null if no item is selected.
+ * @return TControl the selected item, null if no item is selected.
*/
public function getSelectedItem()
{
@@ -531,7 +708,7 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
}
/**
- * @return TDataListItem the edit item
+ * @return TControl the edit item
*/
public function getEditItem()
{
@@ -671,7 +848,7 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
/**
* This method overrides parent's implementation to handle
* {@link onItemCommand OnItemCommand} event which is bubbled from
- * {@link TDataListItem} child controls.
+ * datalist items and their child controls.
* If the event parameter is {@link TDataListCommandEventParameter} and
* the command name is a recognized one, which includes 'select', 'edit',
* 'delete', 'update', and 'cancel' (case-insensitive), then a
@@ -722,7 +899,7 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
* Raises OnItemCreated event.
* This method is invoked after a data list item is created and instantiated with
* template, but before added to the page hierarchy.
- * The {@link TDataListItem} control responsible for the event
+ * The datalist item control responsible for the event
* can be determined from the event parameter.
* If you override this method, be sure to call parent's implementation
* so that event handlers have chance to respond to the event.
@@ -736,7 +913,7 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
/**
* Raises OnItemDataBound event.
* This method is invoked right after an item is data bound.
- * The {@link TDataListItem} control responsible for the event
+ * The datalist item control responsible for the event
* can be determined from the event parameter.
* If you override this method, be sure to call parent's implementation
* so that event handlers have chance to respond to the event.
@@ -750,7 +927,7 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
/**
* Raises OnItemCommand event.
* This method is invoked when a child control of the data list
- * raises an Command event.
+ * raises an OnCommand event.
* @param TDataListCommandEventParameter event parameter
*/
public function onItemCommand($param)
@@ -761,7 +938,7 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
/**
* Raises OnEditCommand event.
* This method is invoked when a child control of the data list
- * raises an Command event and the command name is 'edit' (case-insensitive).
+ * raises an OnCommand event and the command name is 'edit' (case-insensitive).
* @param TDataListCommandEventParameter event parameter
*/
public function onEditCommand($param)
@@ -772,7 +949,7 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
/**
* Raises OnDeleteCommand event.
* This method is invoked when a child control of the data list
- * raises an Command event and the command name is 'delete' (case-insensitive).
+ * raises an OnCommand event and the command name is 'delete' (case-insensitive).
* @param TDataListCommandEventParameter event parameter
*/
public function onDeleteCommand($param)
@@ -783,7 +960,7 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
/**
* Raises OnUpdateCommand event.
* This method is invoked when a child control of the data list
- * raises an Command event and the command name is 'update' (case-insensitive).
+ * raises an OnCommand event and the command name is 'update' (case-insensitive).
* @param TDataListCommandEventParameter event parameter
*/
public function onUpdateCommand($param)
@@ -794,7 +971,7 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
/**
* Raises OnCancelCommand event.
* This method is invoked when a child control of the data list
- * raises an Command event and the command name is 'cancel' (case-insensitive).
+ * raises an OnCommand event and the command name is 'cancel' (case-insensitive).
* @param TDataListCommandEventParameter event parameter
*/
public function onCancelCommand($param)
@@ -866,21 +1043,23 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
}
/**
- * @param string item type
+ * @param TListItemType item type
* @param integer item index
- * @return TDataListItem data list item with the specified item type and index
+ * @return TControl data list item with the specified item type and index
*/
private function getItem($itemType,$index)
{
switch($itemType)
{
- case TListItemType::Header: return $this->getControls()->itemAt(0);
- case TListItemType::Footer: return $this->getControls()->itemAt($this->getControls()->getCount()-1);
case TListItemType::Item:
case TListItemType::AlternatingItem:
case TListItemType::SelectedItem:
case TListItemType::EditItem:
return $this->getItems()->itemAt($index);
+ case TListItemType::Header:
+ return $this->getControls()->itemAt(0);
+ case TListItemType::Footer:
+ return $this->getControls()->itemAt($this->getControls()->getCount()-1);
case TListItemType::Separator:
$i=$index+$index+1;
if($this->_headerTemplate!==null)
@@ -891,45 +1070,143 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
}
/**
- * Creates a data list item and does databinding if needed.
- * This method invokes {@link createItem} to create a new data list item.
+ * Creates a datalist item.
+ * This method invokes {@link createItem} to create a new datalist item.
* @param integer zero-based item index.
* @param TListItemType item type
- * @param boolean whether to do databinding for the item
- * @param mixed data to be associated with the item
- * @return TDataListItem the created item
+ * @return TControl the created item, null if item is not created
*/
- private function createItemInternal($itemIndex,$itemType,$dataBind,$dataItem)
+ private function createItemInternal($itemIndex,$itemType)
{
- $item=$this->createItem($itemIndex,$itemType);
- $this->initializeItem($item);
- $param=new TDataListItemEventParameter($item);
- if($dataBind)
+ if(($item=$this->createItem($itemIndex,$itemType))!==null)
{
- $item->setDataItem($dataItem);
+ $param=new TDataListItemEventParameter($item);
$this->onItemCreated($param);
$this->getControls()->add($item);
- $item->dataBind();
- $this->onItemDataBound($param);
- $item->setDataItem(null);
+ return $item;
}
else
+ return null;
+ }
+
+ /**
+ * Creates a datalist item and performs databinding.
+ * This method invokes {@link createItem} to create a new datalist item.
+ * @param integer zero-based item index.
+ * @param TListItemType item type
+ * @param mixed data to be associated with the item
+ * @return TControl the created item, null if item is not created
+ */
+ private function createItemWithDataInternal($itemIndex,$itemType,$dataItem)
+ {
+ if(($item=$this->createItem($itemIndex,$itemType))!==null)
{
+ $param=new TDataListItemEventParameter($item);
+ if($item instanceof IDataRenderer)
+ $item->setData($dataItem);
$this->onItemCreated($param);
$this->getControls()->add($item);
+ $item->dataBind();
+ $this->onItemDataBound($param);
+ return $item;
}
- return $item;
+ else
+ return null;
}
/**
- * Creates a DataList item instance based on the item type and index.
+ * Creates a datalist item instance based on the item type and index.
* @param integer zero-based item index
* @param TListItemType item type
- * @return TDataListItem created data list item
+ * @return TControl created datalist item
*/
protected function createItem($itemIndex,$itemType)
{
- return new TDataListItem($itemIndex,$itemType);
+ $template=null;
+ $classPath=null;
+ switch($itemType)
+ {
+ case TListItemType::Item :
+ $classPath=$this->getItemRenderer();
+ $template=$this->_itemTemplate;
+ break;
+ case TListItemType::AlternatingItem :
+ if(($classPath=$this->getAlternatingItemRenderer())==='')
+ $classPath=$this->getItemRenderer();
+ $template=$this->_alternatingItemTemplate===null ? $this->_itemTemplate : $this->_alternatingItemTemplate;
+ break;
+ case TListItemType::SelectedItem:
+ if(($classPath=$this->getSelectedItemRenderer())==='')
+ {
+ if(!($itemIndex%2) || ($classPath=$this->getAlternatingItemRenderer())==='')
+ $classPath=$this->getItemRenderer();
+ }
+ if(($template=$this->_selectedItemTemplate)===null)
+ {
+ if(!($itemIndex%2) || ($template=$this->_alternatingItemTemplate)===null)
+ $template=$this->_itemTemplate;
+ }
+ break;
+ case TListItemType::EditItem:
+ if(($classPath=$this->getEditItemRenderer())==='')
+ {
+ if($itemIndex!==$this->getSelectedItemIndex() || ($classPath=$this->getSelectedItemRenderer())==='')
+ if(!($itemIndex%2) || ($classPath=$this->getAlternatingItemRenderer())==='')
+ $classPath=$this->getItemRenderer();
+ }
+ if(($template=$this->_editItemTemplate)===null)
+ {
+ if($itemIndex!==$this->getSelectedItemIndex() || ($template=$this->_selectedItemTemplate)===null)
+ if(!($itemIndex%2) || ($template=$this->_alternatingItemTemplate)===null)
+ $template=$this->_itemTemplate;
+ }
+ break;
+ case TListItemType::Header :
+ $classPath=$this->getHeaderRenderer();
+ $template=$this->_headerTemplate;
+ break;
+ case TListItemType::Footer :
+ $classPath=$this->getFooterRenderer();
+ $template=$this->_footerTemplate;
+ break;
+ case TListItemType::Separator :
+ $classPath=$this->getSeparatorRenderer();
+ $template=$this->_separatorTemplate;
+ break;
+ default:
+ throw new TInvalidDataValueException('datalist_itemtype_unknown',$itemType);
+ }
+ if($classPath!=='')
+ {
+ $item=Prado::createComponent($classPath);
+ if($item instanceof IItemDataRenderer)
+ {
+ $item->setItemIndex($itemIndex);
+ $item->setItemType($itemType);
+ }
+ }
+ else if($template!==null)
+ {
+ $item=new TDataListItem;
+ $item->setItemIndex($itemIndex);
+ $item->setItemType($itemType);
+ $template->instantiateIn($item);
+ }
+ else
+ $item=null;
+
+ return $item;
+ }
+
+ /**
+ * Creates empty datalist content.
+ */
+ protected function createEmptyContent()
+ {
+ if(($classPath=$this->getEmptyRenderer())!=='')
+ $this->getControls()->add(Prado::createComponent($classPath));
+ else if($this->_emptyTemplate!==null)
+ $this->_emptyTemplate->instantiateIn($this);
}
/**
@@ -973,7 +1250,7 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
foreach($this->getControls() as $index=>$item)
{
- if(!($item instanceof TDataListItem))
+ if(!($item instanceof IItemDataRenderer) || !$item->hasProperty('Style'))
continue;
switch($item->getItemType())
{
@@ -1031,55 +1308,6 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
}
}
- /**
- * Initializes a data list item.
- * The item is added as a child of the data list and the corresponding
- * template is instantiated within the item.
- * @param TDataListItem item to be initialized
- */
- protected function initializeItem($item)
- {
- $template=null;
- switch($item->getItemType())
- {
- case TListItemType::Header:
- $template=$this->_headerTemplate;
- break;
- case TListItemType::Footer:
- $template=$this->_footerTemplate;
- break;
- case TListItemType::Item:
- $template=$this->_itemTemplate;
- break;
- case TListItemType::AlternatingItem:
- if(($template=$this->_alternatingItemTemplate)===null)
- $template=$this->_itemTemplate;
- break;
- case TListItemType::Separator:
- $template=$this->_separatorTemplate;
- break;
- case TListItemType::SelectedItem:
- if(($template=$this->_selectedItemTemplate)===null)
- {
- if(!($item->getItemIndex()%2) || ($template=$this->_alternatingItemTemplate)===null)
- $template=$this->_itemTemplate;
- }
- break;
- case TListItemType::EditItem:
- if(($template=$this->_editItemTemplate)===null)
- {
- if($item->getItemIndex()!==$this->getSelectedItemIndex() || ($template=$this->_selectedItemTemplate)===null)
- if(!($item->getItemIndex()%2) || ($template=$this->_alternatingItemTemplate)===null)
- $template=$this->_itemTemplate;
- }
- break;
- default:
- break;
- }
- if($template!==null)
- $template->instantiateIn($item);
- }
-
/**
* Saves item count in viewstate.
* This method is invoked right before control state is to be saved.
@@ -1127,26 +1355,24 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
$items=$this->getItems();
$selectedIndex=$this->getSelectedItemIndex();
$editIndex=$this->getEditItemIndex();
- $hasSeparator=$this->_separatorTemplate!==null;
- if($this->_headerTemplate!==null)
- $this->_header=$this->createItemInternal(-1,TListItemType::Header,false,null);
+ $hasSeparator=$this->_separatorTemplate!==null || $this->getSeparatorRenderer()!=='';
+ $this->_header=$this->createItemInternal(-1,TListItemType::Header);
for($i=0;$i<$itemCount;++$i)
{
if($hasSeparator && $i>0)
- $this->createItemInternal($i-1,TListItemType::Separator,false,null);
+ $this->createItemInternal($i-1,TListItemType::Separator);
if($i===$editIndex)
$itemType=TListItemType::EditItem;
else if($i===$selectedIndex)
$itemType=TListItemType::SelectedItem;
else
$itemType=$i%2?TListItemType::AlternatingItem : TListItemType::Item;
- $items->add($this->createItemInternal($i,$itemType,false,null));
+ $items->add($this->createItemInternal($i,$itemType));
}
- if($this->_footerTemplate!==null)
- $this->_footer=$this->createItemInternal(-1,TListItemType::Footer,false,null);
+ $this->_footer=$this->createItemInternal(-1,TListItemType::Footer);
}
- else if($this->_emptyTemplate!==null)
- $this->_emptyTemplate->instantiateIn($this);
+ else
+ $this->createEmptyContent();
$this->clearChildState();
}
@@ -1164,7 +1390,7 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
$keyField=$this->getDataKeyField();
$itemIndex=0;
$items=$this->getItems();
- $hasSeparator=$this->_separatorTemplate!==null;
+ $hasSeparator=$this->_separatorTemplate!==null || $this->getSeparatorRenderer()!=='';
$selectedIndex=$this->getSelectedItemIndex();
$editIndex=$this->getEditItemIndex();
foreach($data as $key=>$dataItem)
@@ -1173,24 +1399,24 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
$keys->add($this->getDataFieldValue($dataItem,$keyField));
else
$keys->add($key);
- if($itemIndex===0 && $this->_headerTemplate!==null)
- $this->_header=$this->createItemInternal(-1,TListItemType::Header,true,null);
+ if($itemIndex===0)
+ $this->_header=$this->createItemWithDataInternal(-1,TListItemType::Header,null);
if($hasSeparator && $itemIndex>0)
- $this->createItemInternal($itemIndex-1,TListItemType::Separator,true,null);
+ $this->createItemWithDataInternal($itemIndex-1,TListItemType::Separator,null);
if($itemIndex===$editIndex)
$itemType=TListItemType::EditItem;
else if($itemIndex===$selectedIndex)
$itemType=TListItemType::SelectedItem;
else
$itemType=$itemIndex%2?TListItemType::AlternatingItem : TListItemType::Item;
- $items->add($this->createItemInternal($itemIndex,$itemType,true,$dataItem));
+ $items->add($this->createItemWithDataInternal($itemIndex,$itemType,$dataItem));
$itemIndex++;
}
- if($itemIndex>0 && $this->_footerTemplate!==null)
- $this->_footer=$this->createItemInternal(-1,TListItemType::Footer,true,null);
- if($itemIndex===0 && $this->_emptyTemplate!==null)
+ if($itemIndex>0)
+ $this->_footer=$this->createItemWithDataInternal(-1,TListItemType::Footer,null);
+ else
{
- $this->_emptyTemplate->instantiateIn($this);
+ $this->createEmptyContent();
$this->dataBindChildren();
}
$this->setViewState('ItemCount',$itemIndex,0);
@@ -1211,7 +1437,7 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
$repeatInfo=$this->getRepeatInfo();
$repeatInfo->renderRepeater($writer,$this);
}
- else if($this->_emptyTemplate!==null)
+ else if($this->_emptyTemplate!==null || $this->getEmptyRenderer()!=='')
parent::render($writer);
}
}
@@ -1233,22 +1459,22 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
class TDataListItemEventParameter extends TEventParameter
{
/**
- * The TDataListItem control responsible for the event.
- * @var TDataListItem
+ * The datalist item control responsible for the event.
+ * @var TControl
*/
private $_item=null;
/**
* Constructor.
- * @param TDataListItem DataList item related with the corresponding event
+ * @param TControl DataList item related with the corresponding event
*/
- public function __construct(TDataListItem $item)
+ public function __construct($item)
{
$this->_item=$item;
}
/**
- * @return TDataListItem DataList item related with the corresponding event
+ * @return TControl datalist item related with the corresponding event
*/
public function getItem()
{
@@ -1274,17 +1500,17 @@ class TDataListItemEventParameter extends TEventParameter
class TDataListCommandEventParameter extends TCommandEventParameter
{
/**
- * @var TDataListItem the TDataListItem control responsible for the event.
+ * @var TControl the datalist item control responsible for the event.
*/
private $_item=null;
/**
- * @var TControl the control originally raises the Command event.
+ * @var TControl the control originally raises the OnCommand event.
*/
private $_source=null;
/**
* Constructor.
- * @param TDataListItem DataList item responsible for the event
+ * @param TControl datalist item responsible for the event
* @param TControl original event sender
* @param TCommandEventParameter original event parameter
*/
@@ -1296,7 +1522,7 @@ class TDataListCommandEventParameter extends TCommandEventParameter
}
/**
- * @return TDataListItem the TDataListItem control responsible for the event.
+ * @return TControl the datalist item control responsible for the event.
*/
public function getItem()
{
@@ -1304,7 +1530,7 @@ class TDataListCommandEventParameter extends TCommandEventParameter
}
/**
- * @return TControl the control originally raises the Command event.
+ * @return TControl the control originally raises the OnCommand event.
*/
public function getCommandSource()
{
@@ -1326,33 +1552,22 @@ class TDataListCommandEventParameter extends TCommandEventParameter
* @package System.Web.UI.WebControls
* @since 3.0
*/
-class TDataListItem extends TWebControl implements INamingContainer
+class TDataListItem extends TWebControl implements INamingContainer, IItemDataRenderer
{
/**
* index of the data item in the Items collection of DataList
*/
- private $_itemIndex='';
+ private $_itemIndex;
/**
* type of the TDataListItem
* @var TListItemType
*/
private $_itemType;
/**
- * value of the data item
+ * value of the data associated with this item
* @var mixed
*/
- private $_dataItem=null;
-
- /**
- * Constructor.
- * @param integer zero-based index of the item in the item collection of DataList
- * @param TListItemType item type
- */
- public function __construct($itemIndex,$itemType)
- {
- $this->_itemIndex=$itemIndex;
- $this->setItemType($itemType);
- }
+ private $_data;
/**
* Creates a style object for the control.
@@ -1381,7 +1596,7 @@ class TDataListItem extends TWebControl implements INamingContainer
}
/**
- * @return integer zero-based index of the item in the item collection of DataList
+ * @return integer zero-based index of the item in the item collection of datalist
*/
public function getItemIndex()
{
@@ -1389,24 +1604,54 @@ class TDataListItem extends TWebControl implements INamingContainer
}
/**
+ * Sets the zero-based index for the item.
+ * If the item is not in the item collection (e.g. it is a header item), -1 should be used.
+ * @param integer zero-based index of the item.
+ */
+ public function setItemIndex($value)
+ {
+ $this->_itemIndex=TPropertyValue::ensureInteger($value);
+ }
+
+ /**
+ * @return mixed data associated with the item
+ */
+ public function getData()
+ {
+ return $this->_data;
+ }
+
+ /**
+ * @param mixed data to be associated with the item
+ */
+ 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->_dataItem;
+ 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)
{
- $this->_dataItem=$value;
+ return $this->setData($value);
}
/**
* This method overrides parent's implementation by wrapping event parameter
- * for Command event with item information.
+ * 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.
@@ -1424,6 +1669,225 @@ class TDataListItem extends TWebControl implements INamingContainer
}
+
+/**
+ * TDataListItemRenderer class
+ *
+ * TDataListItemRenderer can be used as a convenient base class to
+ * define an item renderer class for {@link TDataList}.
+ *
+ * Because TDataListItemRenderer extends from {@link TTemplateControl}, derived child classes
+ * can have templates to define their presentational layout.
+ *
+ * TDataListItemRenderer implements {@link IItemDataRenderer} interface,
+ * which enables the following properties that are related with data-bound controls:
+ * - {@link getItemIndex ItemIndex}: zero-based index of this control in the datalist item collection.
+ * - {@link getItemType ItemType}: item type of this control, such as TListItemType::AlternatingItem
+ * - {@link getData Data}: data associated with this control
+
+ * @author Qiang Xue
+ * @version $Id$
+ * @package System.Web.UI.WebControls
+ * @since 3.1.0
+ */
+class TDataListItemRenderer extends TTemplateControl implements IItemDataRenderer
+{
+ /**
+ * index of the data item in the Items collection of TDataList
+ * @var integer
+ */
+ private $_itemIndex;
+ /**
+ * type of the TDataListItem
+ * @var TListItemType
+ */
+ private $_itemType;
+ /**
+ * value of the data associated with this item
+ * @var mixed
+ */
+ private $_data;
+
+ /**
+ * @return boolean whether the control has defined any style information
+ */
+ public function getHasStyle()
+ {
+ return $this->getViewState('Style',null)!==null;
+ }
+
+ /**
+ * Creates a style object to be used by the control.
+ * This method may be overriden by controls to provide customized style.
+ * @return TStyle
+ */
+ protected function createStyle()
+ {
+ return new TStyle;
+ }
+
+ /**
+ * @return TStyle the object representing the css style of the control
+ */
+ public function getStyle()
+ {
+ if($style=$this->getViewState('Style',null))
+ return $style;
+ else
+ {
+ $style=$this->createStyle();
+ $this->setViewState('Style',$style,null);
+ return $style;
+ }
+ }
+
+ /**
+ * @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 datalist
+ */
+ public function getItemIndex()
+ {
+ return $this->_itemIndex;
+ }
+
+ /**
+ * Sets the zero-based index for the item.
+ * If the item is not in the item collection (e.g. it is a header item), -1 should be used.
+ * @param integer zero-based index of the item.
+ */
+ public function setItemIndex($value)
+ {
+ $this->_itemIndex=TPropertyValue::ensureInteger($value);
+ }
+
+ /**
+ * @return mixed data associated with the item
+ */
+ public function getData()
+ {
+ return $this->_data;
+ }
+
+ /**
+ * @param mixed data to be associated with the item
+ */
+ public function setData($value)
+ {
+ $this->_data=$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 TDataListCommandEventParameter($this,$sender,$param));
+ return true;
+ }
+ else
+ return false;
+ }
+
+ /**
+ * Returns the tag name used for this control.
+ * By default, the tag name is 'span'.
+ * You can override this method to provide customized tag names.
+ * If the tag name is empty, the opening and closing tag will NOT be rendered.
+ * @return string tag name of the control to be rendered
+ */
+ protected function getTagName()
+ {
+ return 'span';
+ }
+
+ /**
+ * Adds attribute name-value pairs to renderer.
+ * By default, this method renders the style string.
+ * The method can be overriden to provide customized attribute rendering.
+ * @param THtmlWriter the writer used for the rendering purpose
+ */
+ protected function addAttributesToRender($writer)
+ {
+ if($style=$this->getViewState('Style',null))
+ $style->addAttributesToRender($writer);
+ }
+
+ /**
+ * Renders the control.
+ * This method overrides the parent implementation by replacing it with
+ * the following sequence:
+ * - {@link renderBeginTag}
+ * - {@link renderContents}
+ * - {@link renderEndTag}
+ * If the {@link getTagName TagName} is empty, only {@link renderContents} is invoked.
+ * @param THtmlWriter the writer used for the rendering purpose
+ */
+ public function render($writer)
+ {
+ if($this->getTagName()!=='')
+ {
+ $this->renderBeginTag($writer);
+ $this->renderContents($writer);
+ $this->renderEndTag($writer);
+ }
+ else
+ $this->renderContents();
+ }
+
+ /**
+ * Renders the openning tag for the control (including attributes)
+ * This method is invoked when {@link getTagName TagName} is not empty.
+ * @param THtmlWriter the writer used for the rendering purpose
+ */
+ public function renderBeginTag($writer)
+ {
+ $this->addAttributesToRender($writer);
+ $writer->renderBeginTag($this->getTagName());
+ }
+
+ /**
+ * Renders the body content enclosed between the control tag.
+ * By default, child controls and text strings will be rendered.
+ * You can override this method to provide customized content rendering.
+ * @param THtmlWriter the writer used for the rendering purpose
+ */
+ public function renderContents($writer)
+ {
+ parent::renderChildren($writer);
+ }
+
+ /**
+ * Renders the closing tag for the control
+ * This method is invoked when {@link getTagName TagName} is not empty.
+ * @param THtmlWriter the writer used for the rendering purpose
+ */
+ public function renderEndTag($writer)
+ {
+ $writer->renderEndTag();
+ }
+}
+
/**
* TDataListItemCollection class.
*
@@ -1438,14 +1902,14 @@ class TDataListItemCollection extends TList
{
/**
* Inserts an item at the specified position.
- * This overrides the parent implementation by inserting only TDataListItem.
+ * This overrides the parent implementation by inserting only TControl descendants.
* @param integer the speicified position.
* @param mixed new item
- * @throws TInvalidDataTypeException if the item to be inserted is not a TDataListItem.
+ * @throws TInvalidDataTypeException if the item to be inserted is not a TControl descendant.
*/
public function insertAt($index,$item)
{
- if($item instanceof TDataListItem)
+ if($item instanceof TControl)
parent::insertAt($index,$item);
else
throw new TInvalidDataTypeException('datalistitemcollection_datalistitem_required');
diff --git a/framework/Web/UI/WebControls/TRepeater.php b/framework/Web/UI/WebControls/TRepeater.php
index f6093667..2df8343e 100644
--- a/framework/Web/UI/WebControls/TRepeater.php
+++ b/framework/Web/UI/WebControls/TRepeater.php
@@ -453,7 +453,7 @@ class TRepeater extends TDataBoundControl implements INamingContainer
* Creates a repeater item.
* This method invokes {@link createItem} to create a new repeater item.
* @param integer zero-based item index.
- * @param string item type, may be 'Header', 'Footer', 'Empty', 'Item', 'Separator', 'AlternatingItem'.
+ * @param TListItemType item type
* @return TControl the created item, null if item is not created
*/
private function createItemInternal($itemIndex,$itemType)
@@ -473,7 +473,7 @@ class TRepeater extends TDataBoundControl implements INamingContainer
* Creates a repeater item and performs databinding.
* This method invokes {@link createItem} to create a new repeater item.
* @param integer zero-based item index.
- * @param string item type, may be 'Header', 'Footer', 'Empty', 'Item', 'Separator', 'AlternatingItem'.
+ * @param TListItemType item type
* @param mixed data to be associated with the item
* @return TControl the created item, null if item is not created
*/
@@ -497,7 +497,7 @@ class TRepeater extends TDataBoundControl implements INamingContainer
/**
* Creates a repeater item instance based on the item type and index.
* @param integer zero-based item index
- * @param string item type, may be 'Header', 'Footer', 'Empty', 'Item', 'Separator', 'AlternatingItem'.
+ * @param TListItemType item type
* @return TControl created repeater item
*/
protected function createItem($itemIndex,$itemType)
@@ -571,7 +571,7 @@ class TRepeater extends TDataBoundControl implements INamingContainer
*/
public function render($writer)
{
- if($this->_items && $this->_items->getCount() || $this->_emptyTemplate!==null)
+ if($this->_items && $this->_items->getCount() || $this->_emptyTemplate!==null || $this->getEmptyRenderer()!=='')
$this->renderContents($writer);
}
@@ -670,7 +670,10 @@ class TRepeater extends TDataBoundControl implements INamingContainer
if($itemIndex>0)
$this->_footer=$this->createItemWithDataInternal(-1,TListItemType::Footer,null);
else
+ {
$this->createEmptyContent();
+ $this->dataBindChildren();
+ }
$this->setViewState('ItemCount',$itemIndex,0);
}
@@ -981,7 +984,6 @@ class TRepeaterItem extends TControl implements INamingContainer, IItemDataRende
*
* TRepeaterItemRenderer can be used as a convenient base class to
* define an item renderer class for {@link TRepeater}.
- * that implements
*
* Because TRepeaterItemRenderer extends from {@link TTemplateControl}, derived child classes
* can have templates to define their presentational layout.
diff --git a/framework/Web/UI/WebControls/TWebControl.php b/framework/Web/UI/WebControls/TWebControl.php
index 78c1aa98..33393843 100644
--- a/framework/Web/UI/WebControls/TWebControl.php
+++ b/framework/Web/UI/WebControls/TWebControl.php
@@ -247,6 +247,7 @@ class TWebControl extends TControl
/**
* Creates a style object to be used by the control.
* This method may be overriden by controls to provide customized style.
+ * @return TStyle the default style created for TWebControl
*/
protected function createStyle()
{
--
cgit v1.2.3