summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxue <>2006-06-26 02:52:44 +0000
committerxue <>2006-06-26 02:52:44 +0000
commitaac749d4fbfdf3508d97f7dfe4d7c2c03597edbb (patch)
tree54895dbe8d89f9572108f0bc5bdf07160c166e0f
parent7e5dd26cd604318cf4b6d624e8080c801bfb38d0 (diff)
Merge from 3.0 branch till 1202.
-rw-r--r--.gitattributes2
-rw-r--r--HISTORY2
-rw-r--r--framework/Web/UI/TPage.php2
-rw-r--r--framework/Web/UI/WebControls/TDataGrid.php17
-rw-r--r--framework/Web/UI/WebControls/TDataList.php3
-rw-r--r--framework/Web/UI/WebControls/TListControl.php28
-rw-r--r--framework/Web/UI/WebControls/TPager.php759
-rw-r--r--framework/Web/UI/WebControls/TPanel.php222
-rw-r--r--framework/Web/UI/WebControls/TPanelStyle.php235
-rw-r--r--framework/Web/UI/WebControls/TRepeater.php3
10 files changed, 1034 insertions, 239 deletions
diff --git a/.gitattributes b/.gitattributes
index 15501094..3c3ac2f0 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1650,7 +1650,9 @@ framework/Web/UI/WebControls/TLiteral.php -text
framework/Web/UI/WebControls/TMarkdown.php -text
framework/Web/UI/WebControls/TMultiView.php -text
framework/Web/UI/WebControls/TOutputCache.php -text
+framework/Web/UI/WebControls/TPager.php -text
framework/Web/UI/WebControls/TPanel.php -text
+framework/Web/UI/WebControls/TPanelStyle.php -text
framework/Web/UI/WebControls/TPlaceHolder.php -text
framework/Web/UI/WebControls/TRadioButton.php -text
framework/Web/UI/WebControls/TRadioButtonList.php -text
diff --git a/HISTORY b/HISTORY
index a041c0b3..477d1a30 100644
--- a/HISTORY
+++ b/HISTORY
@@ -14,6 +14,7 @@ Version 3.0.2 July 2, 2006
BUG: Ticket#182 - List and validator controls cause problem in child classes (Qiang)
BUG: Ticket#191 - Duplicated postbacks occur when using TButton with validators (Qiang)
BUG: Ticket#213 - PRADO Requirements Checker charset error (Qiang)
+BUG: Ticket#234 - Postback target could be out of date (Qiang)
BUG: Ticket#244 - redirect() needs absolute URL (Qiang)
BUG: Ticket#245 - getIsSecureConnection() is not working correctly (Qiang)
CHG: ensureChildControls() is now invoked in TControl::initRecursive (Qiang)
@@ -26,6 +27,7 @@ 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)
+NEW: Added TPager (Qiang)
Version 3.0.1 June 4, 2006
==========================
diff --git a/framework/Web/UI/TPage.php b/framework/Web/UI/TPage.php
index 57c66a31..8839e6a2 100644
--- a/framework/Web/UI/TPage.php
+++ b/framework/Web/UI/TPage.php
@@ -821,7 +821,7 @@ class TPage extends TTemplateControl
$this->_controlsPostDataChanged[]=$control;
}
else if($control instanceof IPostBackEventHandler)
- $this->setPostBackEventTarget($control);
+ $this->_postData->add(self::FIELD_POSTBACK_TARGET,$key); // not calling setPostBackEventTarget() because the control may be removed later
unset($this->_controlsRequiringPostData[$key]);
}
else if($beforeLoad)
diff --git a/framework/Web/UI/WebControls/TDataGrid.php b/framework/Web/UI/WebControls/TDataGrid.php
index dae2d2cd..4fe63f52 100644
--- a/framework/Web/UI/WebControls/TDataGrid.php
+++ b/framework/Web/UI/WebControls/TDataGrid.php
@@ -1049,7 +1049,7 @@ class TDataGrid extends TBaseDataList implements INamingContainer
}
/**
- * Performs databinding to populate data list items from data source.
+ * 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
@@ -1069,8 +1069,9 @@ class TDataGrid extends TBaseDataList implements INamingContainer
if($ds->getCount()===0 && $ds->getCurrentPageIndex()===0 && $this->_emptyTemplate!==null)
{
- $this->_emptyTemplate->instantiateIn($this);
$this->_useEmptyTemplate=true;
+ $this->_emptyTemplate->instantiateIn($this);
+ $this->dataBindChildren();
$this->clearViewState('ItemCount');
$this->clearViewState('PageCount');
$this->clearViewState('DataSourceCount');
@@ -1757,7 +1758,7 @@ class TDataGridCommandEventParameter extends TCommandEventParameter
* {@link TDataGrid::onSortCommand SortCommand} event of {@link TDataGrid} controls.
*
* The {@link getCommandSource CommandSource} property refers to the control
- * that originally raises the Command event, while {@link getSortExpression SortExpression}
+ * that originally raises the OnCommand event, while {@link getSortExpression SortExpression}
* gives the sort expression carried with the sort command.
*
* @author Qiang Xue <qiang.xue@gmail.com>
@@ -1778,7 +1779,7 @@ class TDataGridSortCommandEventParameter extends TEventParameter
/**
* Constructor.
- * @param TControl the control originally raises the <b>Command</b> event.
+ * @param TControl the control originally raises the <b>OnCommand</b> event.
* @param TDataGridCommandEventParameter command event parameter
*/
public function __construct($source,TDataGridCommandEventParameter $param)
@@ -1788,7 +1789,7 @@ class TDataGridSortCommandEventParameter extends TEventParameter
}
/**
- * @return TControl the control originally raises the <b>Command</b> event.
+ * @return TControl the control originally raises the <b>OnCommand</b> event.
*/
public function getCommandSource()
{
@@ -1811,7 +1812,7 @@ class TDataGridSortCommandEventParameter extends TEventParameter
* {@link TDataGrid::onPageIndexChanged PageIndexChanged} event of {@link TDataGrid} controls.
*
* The {@link getCommandSource CommandSource} property refers to the control
- * that originally raises the Command event, while {@link getNewPageIndex NewPageIndex}
+ * that originally raises the OnCommand event, while {@link getNewPageIndex NewPageIndex}
* returns the new page index carried with the page command.
*
* @author Qiang Xue <qiang.xue@gmail.com>
@@ -1832,7 +1833,7 @@ class TDataGridPageChangedEventParameter extends TEventParameter
/**
* Constructor.
- * @param TControl the control originally raises the <b>Command</b> event.
+ * @param TControl the control originally raises the <b>OnCommand</b> event.
* @param integer new page index
*/
public function __construct($source,$newPageIndex)
@@ -1842,7 +1843,7 @@ class TDataGridPageChangedEventParameter extends TEventParameter
}
/**
- * @return TControl the control originally raises the <b>Command</b> event.
+ * @return TControl the control originally raises the <b>OnCommand</b> event.
*/
public function getCommandSource()
{
diff --git a/framework/Web/UI/WebControls/TDataList.php b/framework/Web/UI/WebControls/TDataList.php
index 0dac2be2..b6888225 100644
--- a/framework/Web/UI/WebControls/TDataList.php
+++ b/framework/Web/UI/WebControls/TDataList.php
@@ -1174,7 +1174,10 @@ 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->_emptyTemplate->instantiateIn($this);
+ $this->dataBindChildren();
+ }
$this->setViewState('ItemCount',$itemIndex,0);
}
diff --git a/framework/Web/UI/WebControls/TListControl.php b/framework/Web/UI/WebControls/TListControl.php
index 3ad46db8..b070f26b 100644
--- a/framework/Web/UI/WebControls/TListControl.php
+++ b/framework/Web/UI/WebControls/TListControl.php
@@ -471,7 +471,7 @@ abstract class TListControl extends TDataBoundControl
$this->_items->itemAt($index)->setSelected(true);
}
}
-
+
if($this->getAdapter() instanceof IListControlAdaptee)
$this->getAdapter()->setSelectedIndices($indices);
}
@@ -558,9 +558,9 @@ abstract class TListControl extends TDataBoundControl
throw new TInvalidDataValueException('listcontrol_selectedvalue_invalid',get_class($this),$value);
}
}
-
+
if($this->getAdapter() instanceof IListControlAdaptee)
- $this->getAdapter()->setSelectedValues($values);
+ $this->getAdapter()->setSelectedValues($values);
}
/**
@@ -589,9 +589,9 @@ abstract class TListControl extends TDataBoundControl
foreach($this->_items as $item)
$item->setSelected(false);
}
-
+
if($this->getAdapter() instanceof IListControlAdaptee)
- $this->getAdapter()->clearSelection();
+ $this->getAdapter()->clearSelection();
}
/**
@@ -727,7 +727,7 @@ class TListItemCollection extends TList
$this->insertAt($index,$item);
return $item;
}
-
+
/**
* @return TListItem new item.
*/
@@ -852,15 +852,15 @@ class TListItemCollection extends TList
* @package System.Web.UI.ActiveControls
* @since 3.0
*/
-interface IListControlAdaptee
+interface IListControlAdapter
{
- /**
- * Selects an item based on zero-base index on the client side.
+ /**
+ * Selects an item based on zero-base index on the client side.
* @param integer the index (zero-based) of the item to be selected
*/
public function setSelectedIndex($index);
- /**
- * Selects a list of item based on zero-base indices on the client side.
+ /**
+ * Selects a list of item based on zero-base indices on the client side.
* @param array list of index of items to be selected
*/
public function setSelectedIndices($indices);
@@ -870,13 +870,13 @@ interface IListControlAdaptee
* @param string the value of the item to be selected.
*/
public function setSelectedValue($value);
-
- /**
+
+ /**
* Sets selection by a list of item values on the client side.
* @param array list of the selected item values
*/
public function setSelectedValues($values);
-
+
/**
* Clears all existing selections on the client side.
*/
diff --git a/framework/Web/UI/WebControls/TPager.php b/framework/Web/UI/WebControls/TPager.php
new file mode 100644
index 00000000..f802e8d7
--- /dev/null
+++ b/framework/Web/UI/WebControls/TPager.php
@@ -0,0 +1,759 @@
+<?php
+/**
+ * TPager class file.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2005 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ $Date: $
+ * @package System.Web.UI.WebControls
+ */
+
+Prado::using('System.Web.UI.WebControls.TDataBoundControl');
+Prado::using('System.Web.UI.WebControls.TPanelStyle');
+Prado::using('System.Collections.TPagedDataSource');
+Prado::using('System.Collections.TDummyDataSource');
+
+/**
+ * TPager class.
+ *
+ * TPager creates a pager that controls the paging of the data populated
+ * to a data-bound control specified by {@link setControlToPaginate ControlToPaginate}.
+ * To specify the number of data items displayed on each page, set
+ * the {@link setPageSize PageSize} property, and to specify which
+ * page of data to be displayed, set {@link setCurrentPageIndex CurrentPageIndex}.
+ *
+ * When the size of the original data is too big to be loaded all in the memory,
+ * one can enable custom paging. In custom paging, the total number of data items
+ * is specified manually via {@link setVirtualItemCount VirtualItemCount}, and the data source
+ * only needs to contain the current page of data. To enable custom paging,
+ * set {@link setAllowCustomPaging AllowCustomPaging} to true.
+ *
+ * TPager can be in one of three {@link setMode Mode}:
+ * - NextPrev: a next page and a previous page button are rendered.
+ * - Numeric: a list of page index buttons are rendered.
+ * - List: a dropdown list of page indices are rendered.
+ *
+ * TPager raises an {@link onPageIndexChanged OnPageIndexChanged} event when
+ * the end-user interacts with it and specifies a new page (e.g. clicking
+ * on a page button that leads to a new page.) The new page index may be obtained
+ * from the event parameter's property {@link TPagerPageChangedEventParameter::getNewPageIndex NewPageIndex}.
+ *
+ * When multiple pagers are associated with the same data-bound control,
+ * these pagers will do synchronization among each other so that the interaction
+ * with one pager will automatically update the UI of the other relevant pagers.
+ *
+ * The following example shows a typical usage of TPager:
+ * <code>
+ * $pager->ControlToPaginate="Path.To.Control";
+ * $pager->DataSource=$data;
+ * $pager->dataBind();
+ * </code>
+ * Note, the data is assigned to the pager and dataBind() is invoked against the pager.
+ * Without the pager, one has to set datasource for the target control and call
+ * its dataBind() directly.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Revision: $ $Date: $
+ * @package System.Web.UI.WebControls
+ * @since 3.0.2
+ */
+class TPager extends TDataBoundControl implements INamingContainer
+{
+ /**
+ * Command name that TPager understands.
+ */
+ const CMD_PAGE='Page';
+ const CMD_PAGE_NEXT='Next';
+ const CMD_PAGE_PREV='Previous';
+ const CMD_PAGE_FIRST='First';
+ const CMD_PAGE_LAST='Last';
+
+ /**
+ * @var array list of all pagers, used to synchronize their appearance
+ */
+ static private $_pagers=array();
+
+ /**
+ * Registers the pager itself to a global list.
+ * This method overrides the parent implementation and is invoked during
+ * OnInit control lifecycle.
+ * @param mixed event parameter
+ */
+ public function onInit($param)
+ {
+ parent::onInit($param);
+ self::$_pagers[]=$this;
+ }
+
+ /**
+ * Unregisters the pager from a global list.
+ * This method overrides the parent implementation and is invoked during
+ * OnUnload control lifecycle.
+ * @param mixed event parameter
+ */
+ public function onUnload($param)
+ {
+ parent::onUnload($param);
+ if(($index=array_search($this,self::$_pagers,true))!==false)
+ unset(self::$_pagers[$index]);
+ }
+
+ /**
+ * Restores the pager state.
+ * This method overrides the parent implementation and is invoked when
+ * the control is loading persistent state.
+ */
+ public function loadState()
+ {
+ parent::loadState();
+ if(!$this->getEnableViewState(true))
+ return;
+ if(!$this->getIsDataBound())
+ $this->restoreFromViewState();
+ }
+
+ /**
+ * @return string the ID path of the control whose content would be paginated.
+ */
+ public function getControlToPaginate()
+ {
+ return $this->getViewState('ControlToPaginate','');
+ }
+
+ /**
+ * Sets the ID path of the control whose content would be paginated.
+ * The ID path is the dot-connected IDs of the controls reaching from
+ * the pager's naming container to the target control.
+ * @param string the ID path
+ */
+ public function setControlToPaginate($value)
+ {
+ $this->setViewState('ControlToPaginate',$value,'');
+ }
+
+ /**
+ * @return integer the zero-based index of the current page. Defaults to 0.
+ */
+ public function getCurrentPageIndex()
+ {
+ return $this->getViewState('CurrentPageIndex',0);
+ }
+
+ /**
+ * @param integer the zero-based index of the current page
+ * @throws TInvalidDataValueException if the value is less than 0
+ */
+ public function setCurrentPageIndex($value)
+ {
+ if(($value=TPropertyValue::ensureInteger($value))<0)
+ throw new TInvalidDataValueException('pager_currentpageindex_invalid');
+ $this->setViewState('CurrentPageIndex',$value,0);
+ }
+
+ /**
+ * @return integer the number of data items on each page. Defaults to 10.
+ */
+ public function getPageSize()
+ {
+ return $this->getViewState('PageSize',10);
+ }
+
+ /**
+ * @param integer the number of data items on each page.
+ * @throws TInvalidDataValueException if the value is less than 1
+ */
+ public function setPageSize($value)
+ {
+ if(($value=TPropertyValue::ensureInteger($value))<1)
+ throw new TInvalidDataValueException('pager_pagesize_invalid');
+ $this->setViewState('PageSize',TPropertyValue::ensureInteger($value),10);
+ }
+
+ /**
+ * @return integer number of pages
+ */
+ public function getPageCount()
+ {
+ if(($count=$this->getItemCount())<1)
+ return 1;
+ else
+ {
+ $pageSize=$this->getPageSize();
+ return (int)(($count+$pageSize-1)/$pageSize);
+ }
+ }
+
+ /**
+ * @return boolean whether the custom paging is enabled. Defaults to false.
+ */
+ public function getAllowCustomPaging()
+ {
+ return $this->getViewState('AllowCustomPaging',false);
+ }
+
+ /**
+ * Sets a value indicating whether the custom paging should be enabled.
+ * When the pager is in custom paging mode, the {@link setVirtualItemCount VirtualItemCount}
+ * property is used to determine the paging, and the data items in the
+ * {@link setDataSource DataSource} are considered to be in the current page.
+ * @param boolean whether the custom paging is enabled
+ */
+ public function setAllowCustomPaging($value)
+ {
+ $this->setViewState('AllowCustomPaging',TPropertyValue::ensureBoolean($value),false);
+ }
+
+ /**
+ * @return integer virtual number of data items in the data source. Defaults to 0.
+ * @see setAllowCustomPaging
+ */
+ public function getVirtualItemCount()
+ {
+ return $this->getViewState('VirtualItemCount',0);
+ }
+
+ /**
+ * @param integer virtual number of data items in the data source.
+ * @throws TInvalidDataValueException if the value is less than 0
+ * @see setAllowCustomPaging
+ */
+ public function setVirtualItemCount($value)
+ {
+ if(($value=TPropertyValue::ensureInteger($value))<0)
+ throw new TInvalidDataValueException('pager_virtualitemcount_invalid');
+ $this->setViewState('VirtualItemCount',$value,0);
+ }
+
+ /**
+ * @return integer total number of items in the datasource.
+ */
+ public function getItemCount()
+ {
+ return $this->getViewState('ItemCount',0);
+ }
+
+ /**
+ * @return string pager mode. Defaults to 'NextPrev'.
+ */
+ public function getMode()
+ {
+ return $this->getViewState('Mode','NextPrev');
+ }
+
+ /**
+ * @param string pager mode. Valid values include 'NextPrev', 'Numeric' and 'List'.
+ */
+ public function setMode($value)
+ {
+ $this->setViewState('Mode',TPropertyValue::ensureEnum($value,'NextPrev','Numeric','List'),'NextPrev');
+ }
+
+ /**
+ * @return string the type of command button for paging. Defaults to 'LinkButton'.
+ */
+ public function getButtonType()
+ {
+ return $this->getViewState('ButtonType','LinkButton');
+ }
+
+ /**
+ * @param string the type of command button for paging. Valid values include 'LinkButton' and 'PushButton'.
+ */
+ public function setButtonType($value)
+ {
+ $this->setViewState('ButtonType',TPropertyValue::ensureEnum($value,'LinkButton','PushButton'));
+ }
+
+ /**
+ * @return string text for the next page button. Defaults to '>'.
+ */
+ public function getNextPageText()
+ {
+ return $this->getViewState('NextPageText','>');
+ }
+
+ /**
+ * @param string text for the next page button.
+ */
+ public function setNextPageText($value)
+ {
+ $this->setViewState('NextPageText',$value,'>');
+ }
+
+ /**
+ * @return string text for the previous page button. Defaults to '<'.
+ */
+ public function getPrevPageText()
+ {
+ return $this->getViewState('PrevPageText','<');
+ }
+
+ /**
+ * @param string text for the next page button.
+ */
+ public function setPrevPageText($value)
+ {
+ $this->setViewState('PrevPageText',$value,'<');
+ }
+
+ /**
+ * @return string text for the first page button. Defaults to '<<'.
+ */
+ public function getFirstPageText()
+ {
+ return $this->getViewState('FirstPageText','<<');
+ }
+
+ /**
+ * @param string text for the first page button. If empty, the first page button will not be rendered.
+ */
+ public function setFirstPageText($value)
+ {
+ $this->setViewState('FirstPageText',$value,'<<');
+ }
+
+ /**
+ * @return string text for the last page button. Defaults to '>>'.
+ */
+ public function getLastPageText()
+ {
+ return $this->getViewState('LastPageText','>>');
+ }
+
+ /**
+ * @param string text for the last page button. If empty, the last page button will not be rendered.
+ */
+ public function setLastPageText($value)
+ {
+ $this->setViewState('LastPageText',$value,'>>');
+ }
+
+ /**
+ * @return integer maximum number of pager buttons to be displayed. Defaults to 10.
+ */
+ public function getPageButtonCount()
+ {
+ return $this->getViewState('PageButtonCount',10);
+ }
+
+ /**
+ * @param integer maximum number of pager buttons to be displayed
+ * @throws TInvalidDataValueException if the value is less than 1.
+ */
+ public function setPageButtonCount($value)
+ {
+ if(($value=TPropertyValue::ensureInteger($value))<1)
+ throw new TInvalidDataValueException('pager_pagebuttoncount_invalid');
+ $this->setViewState('PageButtonCount',$value,10);
+ }
+
+ /**
+ * @return TPagedDataSource creates a paged data source
+ */
+ private function createPagedDataSource()
+ {
+ $ds=new TPagedDataSource;
+ $ds->setAllowPaging(true);
+ $customPaging=$this->getAllowCustomPaging();
+ $ds->setAllowCustomPaging($customPaging);
+ $ds->setCurrentPageIndex($this->getCurrentPageIndex());
+ $ds->setPageSize($this->getPageSize());
+ if($customPaging)
+ $ds->setVirtualItemCount($this->getVirtualItemCount());
+ return $ds;
+ }
+
+ /**
+ * Removes the existing child controls.
+ */
+ protected function reset()
+ {
+ $this->getControls()->clear();
+ }
+
+ /**
+ * Restores the pager from viewstate.
+ */
+ protected function restoreFromViewState()
+ {
+ $this->reset();
+ $ds=$this->createPagedDataSource();
+ $ds->setDataSource(new TDummyDataSource($this->getItemCount()));
+ $this->buildPager($ds);
+ }
+
+ /**
+ * Performs databinding to populate data 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();
+
+ $controlID=$this->getControlToPaginate();
+ if(($targetControl=$this->getNamingContainer()->findControl($controlID))===null || !($targetControl instanceof TDataBoundControl))
+ throw new TConfigurationException('pager_controltopaginate_invalid',$controlID);
+
+ $ds=$this->createPagedDataSource();
+ $ds->setDataSource($this->getDataSource());
+ $this->setViewState('ItemCount',$ds->getDataSourceCount());
+
+ $this->buildPager($ds);
+ $this->synchronizePagers($targetControl,$ds);
+
+ $targetControl->setDataSource($ds);
+ $targetControl->dataBind();
+ }
+
+ /**
+ * Synchronizes the state of all pagers who have the same {@link getControlToPaginate ControlToPaginate}.
+ * @param TDataBoundControl the control whose content is to be paginated
+ * @param TPagedDataSource the paged data source associated with the pager
+ */
+ protected function synchronizePagers($targetControl,$dataSource)
+ {
+ foreach(self::$_pagers as $pager)
+ {
+ if($pager!==$this && $pager->getNamingContainer()->findControl($pager->getControlToPaginate())===$targetControl)
+ {
+ $pager->reset();
+ $pager->setCurrentPageIndex($dataSource->getCurrentPageIndex());
+ $customPaging=$dataSource->getAllowCustomPaging();
+ $pager->setAllowCustomPaging($customPaging);
+ $pager->setViewState('ItemCount',$dataSource->getDataSourceCount());
+ if($customPaging)
+ $pager->setVirtualItemCount($dataSource->getVirtualItemCount());
+ $pager->buildPager($dataSource);
+ }
+ }
+ }
+
+ /**
+ * Builds the pager content based on the pager mode.
+ * Current implementation includes building 'NextPrev', 'Numeric' and 'List' pagers.
+ * Derived classes may override this method to provide additional pagers.
+ * @param TPagedDataSource data source bound to the target control
+ */
+ protected function buildPager($dataSource)
+ {
+ switch($this->getMode())
+ {
+ case 'NextPrev':
+ $this->buildNextPrevPager($dataSource);
+ break;
+ case 'Numeric':
+ $this->buildNumericPager($dataSource);
+ break;
+ case 'List':
+ $this->buildListPager($dataSource);
+ 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==='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 TPagedDataSource data source bound to the pager
+ */
+ protected function buildNextPrevPager($dataSource)
+ {
+ $buttonType=$this->getButtonType();
+ $controls=$this->getControls();
+ if($dataSource->getIsFirstPage())
+ {
+ if(($text=$this->getFirstPageText())!=='')
+ {
+ $label=$this->createPagerButton($buttonType,false,$text,'','');
+ $controls->add($label);
+ $controls->add("\n");
+ }
+ $label=$this->createPagerButton($buttonType,false,$this->getPrevPageText(),'','');
+ $controls->add($label);
+ }
+ else
+ {
+ if(($text=$this->getFirstPageText())!=='')
+ {
+ $button=$this->createPagerButton($buttonType,true,$text,self::CMD_PAGE_FIRST,'');
+ $controls->add($button);
+ $controls->add("\n");
+ }
+ $button=$this->createPagerButton($buttonType,true,$this->getPrevPageText(),self::CMD_PAGE_PREV,'');
+ $controls->add($button);
+ }
+ $controls->add("\n");
+ if($dataSource->getIsLastPage())
+ {
+ $label=$this->createPagerButton($buttonType,false,$this->getNextPageText(),'','');
+ $controls->add($label);
+ if(($text=$this->getLastPageText())!=='')
+ {
+ $controls->add("\n");
+ $label=$this->createPagerButton($buttonType,false,$text,'','');
+ $controls->add($label);
+ }
+ }
+ else
+ {
+ $button=$this->createPagerButton($buttonType,true,$this->getNextPageText(),self::CMD_PAGE_NEXT,'');
+ $controls->add($button);
+ if(($text=$this->getLastPageText())!=='')
+ {
+ $controls->add("\n");
+ $button=$this->createPagerButton($buttonType,true,$text,self::CMD_PAGE_LAST,'');
+ $controls->add($button);
+ }
+ }
+ }
+
+ /**
+ * Builds a numeric pager
+ * @param TPagedDataSource data source bound to the pager
+ */
+ protected function buildNumericPager($dataSource)
+ {
+ $buttonType=$this->getButtonType();
+ $controls=$this->getControls();
+ $pageCount=$dataSource->getPageCount();
+ $pageIndex=$dataSource->getCurrentPageIndex()+1;
+ $maxButtonCount=$this->getPageButtonCount();
+ $buttonCount=$maxButtonCount>$pageCount?$pageCount:$maxButtonCount;
+ $startPageIndex=1;
+ $endPageIndex=$buttonCount;
+ if($pageIndex>$endPageIndex)
+ {
+ $startPageIndex=((int)(($pageIndex-1)/$maxButtonCount))*$maxButtonCount+1;
+ if(($endPageIndex=$startPageIndex+$maxButtonCount-1)>$pageCount)
+ $endPageIndex=$pageCount;
+ if($endPageIndex-$startPageIndex+1<$maxButtonCount)
+ {
+ if(($startPageIndex=$endPageIndex-$maxButtonCount+1)<1)
+ $startPageIndex=1;
+ }
+ }
+
+ if($startPageIndex>1)
+ {
+ if(($text=$this->getFirstPageText())!=='')
+ {
+ $button=$this->createPagerButton($buttonType,true,$text,self::CMD_PAGE_FIRST,'');
+ $controls->add($button);
+ $controls->add("\n");
+ }
+ $prevPageIndex=$startPageIndex-1;
+ $button=$this->createPagerButton($buttonType,true,$this->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,$this->getNextPageText(),self::CMD_PAGE,"$nextPageIndex");
+ $controls->add($button);
+ if(($text=$this->getLastPageText())!=='')
+ {
+ $controls->add("\n");
+ $button=$this->createPagerButton($buttonType,true,$text,self::CMD_PAGE_LAST,'');
+ $controls->add($button);
+ }
+ }
+ }
+
+ /**
+ * Builds a dropdown list pager
+ * @param TPagedDataSource data source bound to the pager
+ */
+ protected function buildListPager($dataSource)
+ {
+ $list=new TDropDownList;
+ $this->getControls()->add($list);
+ $list->setDataSource(range(1,$dataSource->getPageCount()));
+ $list->dataBind();
+ $list->setSelectedIndex($dataSource->getCurrentPageIndex());
+ $list->setAutoPostBack(true);
+ $list->attachEventHandler('OnSelectedIndexChanged',array($this,'listIndexChanged'));
+ }
+
+ /**
+ * Event handler to the OnSelectedIndexChanged event of the dropdown list.
+ * This handler will raise {@link onPageIndexChanged OnPageIndexChanged} event.
+ * @param TDropDownList the dropdown list control raising the event
+ * @param TEventParameter event parameter
+ */
+ public function listIndexChanged($sender,$param)
+ {
+ $pageIndex=$sender->getSelectedIndex();
+ $this->onPageIndexChanged(new TPagerPageChangedEventParameter($sender,$pageIndex));
+ }
+
+ /**
+ * This event is raised when page index is changed due to a page button click.
+ * @param TPagerPageChangedEventParameter event parameter
+ */
+ public function onPageIndexChanged($param)
+ {
+ $this->raiseEvent('OnPageIndexChanged',$this,$param);
+ }
+
+ /**
+ * Processes a bubbled event.
+ * This method overrides parent's implementation by wrapping event parameter
+ * for <b>OnCommand</b> event with item information.
+ * @param TControl the sender of the event
+ * @param TEventParameter event parameter
+ * @return boolean whether the event bubbling should stop here.
+ */
+ public function bubbleEvent($sender,$param)
+ {
+ if($param instanceof TCommandEventParameter)
+ {
+ $command=$param->getCommandName();
+ if(strcasecmp($command,self::CMD_PAGE)===0)
+ {
+ $pageIndex=TPropertyValue::ensureInteger($param->getCommandParameter())-1;
+ $this->onPageIndexChanged(new TPagerPageChangedEventParameter($sender,$pageIndex));
+ return true;
+ }
+ else if(strcasecmp($command,self::CMD_PAGE_NEXT)===0)
+ {
+ $pageIndex=$this->getCurrentPageIndex()+1;
+ $this->onPageIndexChanged(new TPagerPageChangedEventParameter($sender,$pageIndex));
+ return true;
+ }
+ else if(strcasecmp($command,self::CMD_PAGE_PREV)===0)
+ {
+ $pageIndex=$this->getCurrentPageIndex()-1;
+ $this->onPageIndexChanged(new TPagerPageChangedEventParameter($sender,$pageIndex));
+ return true;
+ }
+ else if(strcasecmp($command,self::CMD_PAGE_FIRST)===0)
+ {
+ $this->onPageIndexChanged(new TPagerPageChangedEventParameter($sender,0));
+ return true;
+ }
+ else if(strcasecmp($command,self::CMD_PAGE_LAST)===0)
+ {
+ $this->onPageIndexChanged(new TPagerPageChangedEventParameter($sender,$this->getPageCount()-1));
+ return true;
+ }
+ return false;
+ }
+ else
+ return false;
+ }
+}
+
+/**
+ * TPagerPageChangedEventParameter class
+ *
+ * TPagerPageChangedEventParameter encapsulates the parameter data for
+ * {@link TPager::onPageIndexChanged PageIndexChanged} event of {@link TPager} controls.
+ *
+ * The {@link getCommandSource CommandSource} property refers to the control
+ * that originally raises the OnCommand event, while {@link getNewPageIndex NewPageIndex}
+ * returns the new page index carried with the page command.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Revision: $ $Date: $
+ * @package System.Web.UI.WebControls
+ * @since 3.0.2
+ */
+class TPagerPageChangedEventParameter extends TEventParameter
+{
+ /**
+ * @var integer new page index
+ */
+ private $_newIndex;
+ /**
+ * @var TControl original event sender
+ */
+ private $_source=null;
+
+ /**
+ * Constructor.
+ * @param TControl the control originally raises the <b>OnCommand</b> event.
+ * @param integer new page index
+ */
+ public function __construct($source,$newPageIndex)
+ {
+ $this->_source=$source;
+ $this->_newIndex=$newPageIndex;
+ }
+
+ /**
+ * @return TControl the control originally raises the <b>OnCommand</b> event.
+ */
+ public function getCommandSource()
+ {
+ return $this->_source;
+ }
+
+ /**
+ * @return integer new page index
+ */
+ public function getNewPageIndex()
+ {
+ return $this->_newIndex;
+ }
+}
+
+?> \ No newline at end of file
diff --git a/framework/Web/UI/WebControls/TPanel.php b/framework/Web/UI/WebControls/TPanel.php
index 03f0a3a3..27006b94 100644
--- a/framework/Web/UI/WebControls/TPanel.php
+++ b/framework/Web/UI/WebControls/TPanel.php
@@ -11,6 +11,11 @@
*/
/**
+ * Includes TPanelStyle class file
+ */
+Prado::using('System.Web.UI.WebControls.TPanelStyle');
+
+/**
* TPanel class
*
* TPanel represents a component that acts as a container for other component.
@@ -52,6 +57,7 @@ class TPanel extends TWebControl
/**
* Creates a style object to be used by the control.
* This method overrides the parent impementation by creating a TPanelStyle object.
+ * @return TPanelStyle the style used by TPanel.
*/
protected function createStyle()
{
@@ -228,220 +234,4 @@ class TPanel extends TWebControl
}
}
-/**
- * TPanelStyle class.
- * TPanelStyle represents the CSS style specific for panel HTML tag.
- *
- * @author Qiang Xue <qiang.xue@gmail.com>
- * @version $Revision: $ $Date: $
- * @package System.Web.UI.WebControls
- * @since 3.0
- */
-class TPanelStyle extends TStyle
-{
- /**
- * @var string the URL of the background image for the panel component
- */
- private $_backImageUrl=null;
- /**
- * @var string alignment of the content in the panel.
- */
- private $_direction=null;
- /**
- * @var string horizontal alignment of the contents within the panel
- */
- private $_horizontalAlign=null;
- /**
- * @var string visibility and position of scroll bars
- */
- private $_scrollBars=null;
- /**
- * @var boolean whether the content wraps within the panel
- */
- private $_wrap=null;
-
- /**
- * Adds attributes related to CSS styles to renderer.
- * This method overrides the parent implementation.
- * @param THtmlWriter the writer used for the rendering purpose
- */
- public function addAttributesToRender($writer)
- {
- if(($url=trim($this->getBackImageUrl()))!=='')
- $this->setStyleField('background-image','url('.$url.')');
-
- switch($this->getScrollBars())
- {
- case 'Horizontal': $this->setStyleField('overflow-x','scroll'); break;
- case 'Vertical': $this->setStyleField('overflow-y','scroll'); break;
- case 'Both': $this->setStyleField('overflow','scroll'); break;
- case 'Auto': $this->setStyleField('overflow','auto'); break;
- }
-
- if(($align=$this->getHorizontalAlign())!=='NotSet')
- $this->setStyleField('text-align',strtolower($align));
-
- if(!$this->getWrap())
- $this->setStyleField('white-space','nowrap');
-
- if(($direction=$this->getDirection())!=='NotSet')
- {
- if($direction==='LeftToRight')
- $this->setStyleField('direction','ltr');
- else
- $this->setStyleField('direction','rtl');
- }
-
- parent::addAttributesToRender($writer);
- }
-
- /**
- * @return string the URL of the background image for the panel component.
- */
- public function getBackImageUrl()
- {
- return $this->_backImageUrl===null?'':$this->_backImageUrl;
- }
-
- /**
- * Sets the URL of the background image for the panel component.
- * @param string the URL
- */
- public function setBackImageUrl($value)
- {
- $this->_backImageUrl=$value;
- }
-
- /**
- * @return string alignment of the content in the panel. Defaults to 'NotSet'.
- */
- public function getDirection()
- {
- return $this->_direction===null?'NotSet':$this->_direction;
- }
-
- /**
- * @param string alignment of the content in the panel.
- * Valid values include 'NotSet', 'LeftToRight', 'RightToLeft'.
- */
- public function setDirection($value)
- {
- $this->_direction=TPropertyValue::ensureEnum($value,array('NotSet','LeftToRight','RightToLeft'));
- }
-
- /**
- * @return boolean whether the content wraps within the panel. Defaults to true.
- */
- public function getWrap()
- {
- return $this->_wrap===null?true:$this->_wrap;
- }
-
- /**
- * Sets the value indicating whether the content wraps within the panel.
- * @param boolean whether the content wraps within the panel.
- */
- public function setWrap($value)
- {
- $this->_wrap=TPropertyValue::ensureBoolean($value);
- }
-
- /**
- * @return string the horizontal alignment of the contents within the panel, defaults to 'NotSet'.
- */
- public function getHorizontalAlign()
- {
- return $this->_horizontalAlign===null?'NotSet':$this->_horizontalAlign;
- }
-
- /**
- * Sets the horizontal alignment of the contents within the panel.
- * Valid values include 'NotSet', 'Justify', 'Left', 'Right', 'Center'
- * @param string the horizontal alignment
- */
- public function setHorizontalAlign($value)
- {
- $this->_horizontalAlign=TPropertyValue::ensureEnum($value,array('NotSet','Left','Right','Center','Justify'));
- }
-
- /**
- * @return string the visibility and position of scroll bars in a panel control, defaults to None.
- */
- public function getScrollBars()
- {
- return $this->_scrollBars===null?'None':$this->_scrollBars;
- }
-
- /**
- * @param string the visibility and position of scroll bars in a panel control.
- * Valid values include None, Auto, Both, Horizontal and Vertical.
- */
- public function setScrollBars($value)
- {
- $this->_scrollBars=TPropertyValue::ensureEnum($value,array('None','Auto','Both','Horizontal','Vertical'));
- }
-
- /**
- * Sets the style attributes to default values.
- * This method overrides the parent implementation by
- * resetting additional TTableStyle specific attributes.
- */
- public function reset()
- {
- parent::reset();
- $this->_backImageUrl=null;
- $this->_direction=null;
- $this->_horizontalAlign=null;
- $this->_scrollBars=null;
- $this->_wrap=null;
- }
-
- /**
- * Copies the fields in a new style to this style.
- * If a style field is set in the new style, the corresponding field
- * in this style will be overwritten.
- * @param TStyle the new style
- */
- public function copyFrom($style)
- {
- parent::copyFrom($style);
- if($style instanceof TPanelStyle)
- {
- if($style->_backImageUrl!==null)
- $this->_backImageUrl=$style->_backImageUrl;
- if($style->_direction!==null)
- $this->_direction=$style->_direction;
- if($style->_horizontalAlign!==null)
- $this->_horizontalAlign=$style->_horizontalAlign;
- if($style->_scrollBars!==null)
- $this->_scrollBars=$style->_scrollBars;
- if($style->_wrap!==null)
- $this->_wrap=$style->_wrap;
- }
- }
-
- /**
- * Merges the style with a new one.
- * If a style field is not set in this style, it will be overwritten by
- * the new one.
- * @param TStyle the new style
- */
- public function mergeWith($style)
- {
- parent::mergeWith($style);
- if($style instanceof TPanelStyle)
- {
- if($this->_backImageUrl===null && $style->_backImageUrl!==null)
- $this->_backImageUrl=$style->_backImageUrl;
- if($this->_direction===null && $style->_direction!==null)
- $this->_direction=$style->_direction;
- if($this->_horizontalAlign===null && $style->_horizontalAlign!==null)
- $this->_horizontalAlign=$style->_horizontalAlign;
- if($this->_scrollBars===null && $style->_scrollBars!==null)
- $this->_scrollBars=$style->_scrollBars;
- if($this->_wrap===null && $style->_wrap!==null)
- $this->_wrap=$style->_wrap;
- }
- }
-}
?> \ No newline at end of file
diff --git a/framework/Web/UI/WebControls/TPanelStyle.php b/framework/Web/UI/WebControls/TPanelStyle.php
new file mode 100644
index 00000000..02f366b8
--- /dev/null
+++ b/framework/Web/UI/WebControls/TPanelStyle.php
@@ -0,0 +1,235 @@
+<?php
+/**
+ * TPanelStyle class file
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2005 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ $Date: $
+ * @package System.Web.UI.WebControls
+ */
+
+/**
+ * Includes TStyle class file
+ */
+Prado::using('System.Web.UI.WebControls.TStyle');
+
+/**
+ * TPanelStyle class.
+ * TPanelStyle represents the CSS style specific for panel HTML tag.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Revision: $ $Date: $
+ * @package System.Web.UI.WebControls
+ * @since 3.0
+ */
+class TPanelStyle extends TStyle
+{
+ /**
+ * @var string the URL of the background image for the panel component
+ */
+ private $_backImageUrl=null;
+ /**
+ * @var string alignment of the content in the panel.
+ */
+ private $_direction=null;
+ /**
+ * @var string horizontal alignment of the contents within the panel
+ */
+ private $_horizontalAlign=null;
+ /**
+ * @var string visibility and position of scroll bars
+ */
+ private $_scrollBars=null;
+ /**
+ * @var boolean whether the content wraps within the panel
+ */
+ private $_wrap=null;
+
+ /**
+ * Adds attributes related to CSS styles to renderer.
+ * This method overrides the parent implementation.
+ * @param THtmlWriter the writer used for the rendering purpose
+ */
+ public function addAttributesToRender($writer)
+ {
+ if(($url=trim($this->getBackImageUrl()))!=='')
+ $this->setStyleField('background-image','url('.$url.')');
+
+ switch($this->getScrollBars())
+ {
+ case 'Horizontal': $this->setStyleField('overflow-x','scroll'); break;
+ case 'Vertical': $this->setStyleField('overflow-y','scroll'); break;
+ case 'Both': $this->setStyleField('overflow','scroll'); break;
+ case 'Auto': $this->setStyleField('overflow','auto'); break;
+ }
+
+ if(($align=$this->getHorizontalAlign())!=='NotSet')
+ $this->setStyleField('text-align',strtolower($align));
+
+ if(!$this->getWrap())
+ $this->setStyleField('white-space','nowrap');
+
+ if(($direction=$this->getDirection())!=='NotSet')
+ {
+ if($direction==='LeftToRight')
+ $this->setStyleField('direction','ltr');
+ else
+ $this->setStyleField('direction','rtl');
+ }
+
+ parent::addAttributesToRender($writer);
+ }
+
+ /**
+ * @return string the URL of the background image for the panel component.
+ */
+ public function getBackImageUrl()
+ {
+ return $this->_backImageUrl===null?'':$this->_backImageUrl;
+ }
+
+ /**
+ * Sets the URL of the background image for the panel component.
+ * @param string the URL
+ */
+ public function setBackImageUrl($value)
+ {
+ $this->_backImageUrl=$value;
+ }
+
+ /**
+ * @return string alignment of the content in the panel. Defaults to 'NotSet'.
+ */
+ public function getDirection()
+ {
+ return $this->_direction===null?'NotSet':$this->_direction;
+ }
+
+ /**
+ * @param string alignment of the content in the panel.
+ * Valid values include 'NotSet', 'LeftToRight', 'RightToLeft'.
+ */
+ public function setDirection($value)
+ {
+ $this->_direction=TPropertyValue::ensureEnum($value,array('NotSet','LeftToRight','RightToLeft'));
+ }
+
+ /**
+ * @return boolean whether the content wraps within the panel. Defaults to true.
+ */
+ public function getWrap()
+ {
+ return $this->_wrap===null?true:$this->_wrap;
+ }
+
+ /**
+ * Sets the value indicating whether the content wraps within the panel.
+ * @param boolean whether the content wraps within the panel.
+ */
+ public function setWrap($value)
+ {
+ $this->_wrap=TPropertyValue::ensureBoolean($value);
+ }
+
+ /**
+ * @return string the horizontal alignment of the contents within the panel, defaults to 'NotSet'.
+ */
+ public function getHorizontalAlign()
+ {
+ return $this->_horizontalAlign===null?'NotSet':$this->_horizontalAlign;
+ }
+
+ /**
+ * Sets the horizontal alignment of the contents within the panel.
+ * Valid values include 'NotSet', 'Justify', 'Left', 'Right', 'Center'
+ * @param string the horizontal alignment
+ */
+ public function setHorizontalAlign($value)
+ {
+ $this->_horizontalAlign=TPropertyValue::ensureEnum($value,array('NotSet','Left','Right','Center','Justify'));
+ }
+
+ /**
+ * @return string the visibility and position of scroll bars in a panel control, defaults to None.
+ */
+ public function getScrollBars()
+ {
+ return $this->_scrollBars===null?'None':$this->_scrollBars;
+ }
+
+ /**
+ * @param string the visibility and position of scroll bars in a panel control.
+ * Valid values include None, Auto, Both, Horizontal and Vertical.
+ */
+ public function setScrollBars($value)
+ {
+ $this->_scrollBars=TPropertyValue::ensureEnum($value,array('None','Auto','Both','Horizontal','Vertical'));
+ }
+
+ /**
+ * Sets the style attributes to default values.
+ * This method overrides the parent implementation by
+ * resetting additional TTableStyle specific attributes.
+ */
+ public function reset()
+ {
+ parent::reset();
+ $this->_backImageUrl=null;
+ $this->_direction=null;
+ $this->_horizontalAlign=null;
+ $this->_scrollBars=null;
+ $this->_wrap=null;
+ }
+
+ /**
+ * Copies the fields in a new style to this style.
+ * If a style field is set in the new style, the corresponding field
+ * in this style will be overwritten.
+ * @param TStyle the new style
+ */
+ public function copyFrom($style)
+ {
+ parent::copyFrom($style);
+ if($style instanceof TPanelStyle)
+ {
+ if($style->_backImageUrl!==null)
+ $this->_backImageUrl=$style->_backImageUrl;
+ if($style->_direction!==null)
+ $this->_direction=$style->_direction;
+ if($style->_horizontalAlign!==null)
+ $this->_horizontalAlign=$style->_horizontalAlign;
+ if($style->_scrollBars!==null)
+ $this->_scrollBars=$style->_scrollBars;
+ if($style->_wrap!==null)
+ $this->_wrap=$style->_wrap;
+ }
+ }
+
+ /**
+ * Merges the style with a new one.
+ * If a style field is not set in this style, it will be overwritten by
+ * the new one.
+ * @param TStyle the new style
+ */
+ public function mergeWith($style)
+ {
+ parent::mergeWith($style);
+ if($style instanceof TPanelStyle)
+ {
+ if($this->_backImageUrl===null && $style->_backImageUrl!==null)
+ $this->_backImageUrl=$style->_backImageUrl;
+ if($this->_direction===null && $style->_direction!==null)
+ $this->_direction=$style->_direction;
+ if($this->_horizontalAlign===null && $style->_horizontalAlign!==null)
+ $this->_horizontalAlign=$style->_horizontalAlign;
+ if($this->_scrollBars===null && $style->_scrollBars!==null)
+ $this->_scrollBars=$style->_scrollBars;
+ if($this->_wrap===null && $style->_wrap!==null)
+ $this->_wrap=$style->_wrap;
+ }
+ }
+}
+
+?> \ No newline at end of file
diff --git a/framework/Web/UI/WebControls/TRepeater.php b/framework/Web/UI/WebControls/TRepeater.php
index a2fc01d7..eb599341 100644
--- a/framework/Web/UI/WebControls/TRepeater.php
+++ b/framework/Web/UI/WebControls/TRepeater.php
@@ -452,7 +452,10 @@ 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->_emptyTemplate->instantiateIn($this);
+ $this->dataBindChildren();
+ }
$this->setViewState('ItemCount',$itemIndex,0);
}