From 9ac994bb7c2a30c62f08ce005179b0eb0b11ee0a Mon Sep 17 00:00:00 2001 From: xue <> Date: Wed, 21 Jun 2006 12:59:20 +0000 Subject: Added TDataGrid.EmptyTemplate property --- HISTORY | 2 +- framework/Exceptions/messages.txt | 1 + framework/Web/UI/WebControls/TBaseDataList.php | 9 --- framework/Web/UI/WebControls/TDataGrid.php | 88 +++++++++++++++++++++++--- framework/Web/UI/WebControls/TDataList.php | 37 +++-------- framework/Web/UI/WebControls/TRepeater.php | 34 +++++----- 6 files changed, 105 insertions(+), 66 deletions(-) diff --git a/HISTORY b/HISTORY index 3dd5672a..f1c48ae8 100644 --- a/HISTORY +++ b/HISTORY @@ -12,9 +12,9 @@ ENH: Ticket#206 - Added OnValidate, OnError, OnSuccess events to validators (Qia ENH: Ticket#230 - Added TDataList.EmptyTemplate property (Qiang) ENH: Ticket#231 - Added TButton.ButtonType property to allow reset button (Qiang) ENH: Ticket#232 - Allow <%# %> and <%= %> embedded within property values (Qiang) - ENH: TRepeater, TDataList and TDataGrid will store data indices in DataKeys if DataKeyField is not set. (Qiang) ENH: Added TPageService.BasePageClass property (Qiang) +ENH: Added TDataGrid.EmptyTemplate property (Qiang) Version 3.0.1 June 4, 2006 ========================== diff --git a/framework/Exceptions/messages.txt b/framework/Exceptions/messages.txt index 0029669c..b5db3613 100644 --- a/framework/Exceptions/messages.txt +++ b/framework/Exceptions/messages.txt @@ -239,6 +239,7 @@ listcontrolvalidator_invalid_control = {0}.ControlToValidate contains an invalid repeater_template_required = TRepeater.{0} requires a template instance implementing ITemplate interface. datalist_template_required = TDataList.{0} requires a template instance implementing ITemplate interface. +datagrid_template_required = TDataGrid.{0} requires a template instance implementing ITemplate interface. templatecolumn_template_required = TTemplateColumn.{0} requires a template instance implementing ITemplate interface. datagrid_currentpageindex_invalid = TDataGrid.CurrentPageIndex must be no less than 0. diff --git a/framework/Web/UI/WebControls/TBaseDataList.php b/framework/Web/UI/WebControls/TBaseDataList.php index 479fb2ef..a8ab8faf 100644 --- a/framework/Web/UI/WebControls/TBaseDataList.php +++ b/framework/Web/UI/WebControls/TBaseDataList.php @@ -43,15 +43,6 @@ Prado::using('System.Util.TDataFieldAccessor'); */ abstract class TBaseDataList extends TDataBoundControl { - /** - * No body content should be added to data list control. - * This method is invoked when body content is parsed and added to this control. - * @param mixed body content to be added - */ - public function addParsedObject($object) - { - } - /** * Creates a style object for the control. * This method creates a {@link TTableStyle} to be used by the data list control. diff --git a/framework/Web/UI/WebControls/TDataGrid.php b/framework/Web/UI/WebControls/TDataGrid.php index 69798c1a..dae2d2cd 100644 --- a/framework/Web/UI/WebControls/TDataGrid.php +++ b/framework/Web/UI/WebControls/TDataGrid.php @@ -186,6 +186,14 @@ class TDataGrid extends TBaseDataList implements INamingContainer 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 @@ -197,13 +205,15 @@ class TDataGrid extends TBaseDataList implements INamingContainer /** * Adds objects parsed in template to datagrid. - * Only datagrid columns are added into {@link getColumns Columns} collection. + * 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); } /** @@ -682,6 +692,26 @@ class TDataGrid extends TBaseDataList implements INamingContainer $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 @@ -953,6 +983,7 @@ class TDataGrid extends TBaseDataList implements INamingContainer $this->_footer=null; $this->_topPager=null; $this->_bottomPager=null; + $this->_useEmptyTemplate=false; } /** @@ -968,6 +999,17 @@ class TDataGrid extends TBaseDataList implements INamingContainer $ds->setDataSource(new TDummyDataSource($itemCount)); else $ds->setDataSource(new TDummyDataSource($this->getViewState('DataSourceCount',0))); + + if($ds->getCount()===0 && $ds->getCurrentPageIndex()===0 && $this->_emptyTemplate!==null) + { + $this->_emptyTemplate->instantiateIn($this); + $this->_useEmptyTemplate=true; + $this->clearViewState('ItemCount'); + $this->clearViewState('PageCount'); + $this->clearViewState('DataSourceCount'); + return; + } + $columns=new TList($this->getColumns()); $columns->mergeWith($this->_autoColumns); @@ -1020,9 +1062,21 @@ class TDataGrid extends TBaseDataList implements INamingContainer $keyField=$this->getDataKeyField(); $this->_pagedDataSource=$ds=$this->createPagedDataSource(); $ds->setDataSource($data); + $allowPaging=$ds->getAllowPaging(); if($allowPaging && $ds->getCurrentPageIndex()>=$ds->getPageCount()) throw new TInvalidDataValueException('datagrid_currentpageindex_invalid'); + + if($ds->getCount()===0 && $ds->getCurrentPageIndex()===0 && $this->_emptyTemplate!==null) + { + $this->_emptyTemplate->instantiateIn($this); + $this->_useEmptyTemplate=true; + $this->clearViewState('ItemCount'); + $this->clearViewState('PageCount'); + $this->clearViewState('DataSourceCount'); + return; + } + // get all columns if($this->getAutoGenerateColumns()) { @@ -1046,7 +1100,7 @@ class TDataGrid extends TBaseDataList implements INamingContainer $selectedIndex=$this->getSelectedItemIndex(); $editIndex=$this->getEditItemIndex(); $index=0; - $dsIndex=$ds->getAllowPaging()?$ds->getFirstIndexInPage():0; + $dsIndex=$allowPaging?$ds->getFirstIndexInPage():0; foreach($ds as $key=>$data) { if($keyField!=='') @@ -1502,17 +1556,31 @@ class TDataGrid extends TBaseDataList implements INamingContainer { if($this->getHasControls()) { - $this->applyItemStyles(); - if($this->_topPager) + if($this->_useEmptyTemplate) { - $this->_topPager->renderControl($writer); - $writer->writeLine(); + $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); } - $this->renderTable($writer); - if($this->_bottomPager) + else { - $writer->writeLine(); - $this->_bottomPager->renderControl($writer); + $this->applyItemStyles(); + if($this->_topPager) + { + $this->_topPager->renderControl($writer); + $writer->writeLine(); + } + $this->renderTable($writer); + if($this->_bottomPager) + { + $writer->writeLine(); + $this->_bottomPager->renderControl($writer); + } } } } diff --git a/framework/Web/UI/WebControls/TDataList.php b/framework/Web/UI/WebControls/TDataList.php index be1a9130..0dac2be2 100644 --- a/framework/Web/UI/WebControls/TDataList.php +++ b/framework/Web/UI/WebControls/TDataList.php @@ -383,19 +383,6 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs throw new TInvalidDataTypeException('datalist_template_required','EmptyTemplate'); } - /** - * @return TStyle the style for the content representing no data is bounded. - */ - public function getEmptyStyle() - { - if(($style=$this->getViewState('EmptyStyle',null))===null) - { - $style=new TStyle; - $this->setViewState('EmptyStyle',$style,null); - } - return $style; - } - /** * @return ITemplate the separator template */ @@ -969,7 +956,6 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs $headerStyle=$this->getViewState('HeaderStyle',null); $footerStyle=$this->getViewState('FooterStyle',null); - $emptyStyle=$this->getViewState('EmptyStyle',null); $separatorStyle=$this->getViewState('SeparatorStyle',null); foreach($this->getControls() as $index=>$item) @@ -984,10 +970,6 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs if($footerStyle) $item->getStyle()->mergeWith($footerStyle); break; - case 'Empty': - if($emptyStyle) - $item->getStyle()->mergeWith($emptyStyle); - break; case 'Separator': if($separatorStyle) $item->getStyle()->mergeWith($separatorStyle); @@ -1051,9 +1033,6 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs case 'Footer': $template=$this->_footerTemplate; break; - case 'Empty': - $template=$this->_emptyTemplate; - break; case 'Item': $template=$this->_itemTemplate; break; @@ -1152,7 +1131,7 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs $this->_footer=$this->createItemInternal(-1,'Footer',false,null); } else if($this->_emptyTemplate!==null) - $this->createItemInternal(-1,'Empty',false,null); + $this->_emptyTemplate->instantiateIn($this); $this->clearChildState(); } @@ -1195,7 +1174,7 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs if($itemIndex>0 && $this->_footerTemplate!==null) $this->_footer=$this->createItemInternal(-1,'Footer',true,null); if($itemIndex===0 && $this->_emptyTemplate!==null) - $this->createItemInternal(-1,'Empty',true,null); + $this->_emptyTemplate->instantiateIn($this); $this->setViewState('ItemCount',$itemIndex,0); } @@ -1208,14 +1187,14 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs { if($this->getHasControls()) { - $this->applyItemStyles(); - if($this->getItemCount()===0 && $this->_emptyTemplate!==null) - parent::render($writer); - else + if($this->getItemCount()>0) { + $this->applyItemStyles(); $repeatInfo=$this->getRepeatInfo(); $repeatInfo->renderRepeater($writer,$this); } + else if($this->_emptyTemplate!==null) + parent::render($writer); } } } @@ -1376,11 +1355,11 @@ class TDataListItem extends TWebControl implements INamingContainer } /** - * @param string item type. Valid values include 'Header','Footer','Empty','Item','AlternatingItem','SelectedItem','EditItem','Separator','Pager'. + * @param string item type. Valid values include 'Header','Footer','Item','AlternatingItem','SelectedItem','EditItem','Separator','Pager'. */ public function setItemType($value) { - $this->_itemType=TPropertyValue::ensureEnum($value,'Header','Footer','Empty','Item','AlternatingItem','SelectedItem','EditItem','Separator','Pager'); + $this->_itemType=TPropertyValue::ensureEnum($value,'Header','Footer','Item','AlternatingItem','SelectedItem','EditItem','Separator','Pager'); } /** diff --git a/framework/Web/UI/WebControls/TRepeater.php b/framework/Web/UI/WebControls/TRepeater.php index 9c1cc4ac..a2fc01d7 100644 --- a/framework/Web/UI/WebControls/TRepeater.php +++ b/framework/Web/UI/WebControls/TRepeater.php @@ -62,7 +62,6 @@ class TRepeater extends TDataBoundControl implements INamingContainer */ const IT_HEADER='Header'; const IT_FOOTER='Footer'; - const IT_EMPTY='Empty'; const IT_ITEM='Item'; const IT_SEPARATOR='Separator'; const IT_ALTERNATINGITEM='AlternatingItem'; @@ -104,15 +103,6 @@ class TRepeater extends TDataBoundControl implements INamingContainer */ private $_footer=null; - /** - * No body content should be added to repeater. - * This method is invoked when body content is parsed and added to this control. - * @param mixed body content to be added - */ - public function addParsedObject($object) - { - } - /** * @return ITemplate the template for repeater items */ @@ -343,7 +333,6 @@ class TRepeater extends TDataBoundControl implements INamingContainer { case self::IT_HEADER: $template=$this->_headerTemplate; break; case self::IT_FOOTER: $template=$this->_footerTemplate; break; - case self::IT_EMPTY : $template=$this->_emptyTemplate; break; case self::IT_ITEM : $template=$this->_itemTemplate; break; case self::IT_SEPARATOR : $template=$this->_separatorTemplate; break; case self::IT_ALTERNATINGITEM : $template=$this->_alternatingItemTemplate===null ? $this->_itemTemplate : $this->_alternatingItemTemplate; break; @@ -360,7 +349,10 @@ class TRepeater extends TDataBoundControl implements INamingContainer */ public function render($writer) { - $this->renderContents($writer); + if($this->_items && $this->_items->getCount()) + $this->renderContents($writer); + else if($this->_emptyTemplate!==null) + parent::render($writer); } /** @@ -422,7 +414,7 @@ class TRepeater extends TDataBoundControl implements INamingContainer $this->_footer=$this->createItemInternal(-1,self::IT_FOOTER,false,null); } else if($this->_emptyTemplate!==null) - $this->createItemInternal(-1,self::IT_EMPTY,false,null); + $this->_emptyTemplate->instantiateIn($this); $this->clearChildState(); } @@ -460,7 +452,7 @@ class TRepeater extends TDataBoundControl implements INamingContainer if($itemIndex>0 && $this->_footerTemplate!==null) $this->_footer=$this->createItemInternal(-1,self::IT_FOOTER,true,null); if($itemIndex===0 && $this->_emptyTemplate!==null) - $this->createItemInternal(-1,self::IT_EMPTY,true,null); + $this->_emptyTemplate->instantiateIn($this); $this->setViewState('ItemCount',$itemIndex,0); } @@ -677,22 +669,30 @@ class TRepeaterItem extends TControl implements INamingContainer /** * Constructor. * @param integer zero-based index of the item in the item collection of repeater - * @param string item type, can be 'Header','Footer','Empty','Item','AlternatingItem','SelectedItem','EditItem','Separator','Pager'. + * @param string item type, can be 'Header','Footer','Item','AlternatingItem','SelectedItem','EditItem','Separator','Pager'. */ public function __construct($itemIndex,$itemType) { $this->_itemIndex=$itemIndex; - $this->_itemType=$itemType; + $this->setItemType($itemType); } /** - * @return string item type, can be 'Header','Footer','Empty','Item','AlternatingItem','SelectedItem','EditItem','Separator','Pager' + * @return string item type */ public function getItemType() { return $this->_itemType; } + /** + * @param string item type. Valid values include 'Header','Footer','Item','AlternatingItem','SelectedItem','EditItem','Separator','Pager'. + */ + public function setItemType($value) + { + $this->_itemType=TPropertyValue::ensureEnum($value,'Header','Footer','Item','AlternatingItem','SelectedItem','EditItem','Separator','Pager'); + } + /** * @return integer zero-based index of the item in the item collection of repeater */ -- cgit v1.2.3