summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxue <>2006-01-17 23:58:54 +0000
committerxue <>2006-01-17 23:58:54 +0000
commit54900d0145dfda07bde40dc6e1f0b31935b55444 (patch)
treec34892281f5ffa9f3c907e5ef48c05720707ef5d
parent3ea0de54c63f5f9ed02e259a789b01952041cfbd (diff)
-rw-r--r--.gitattributes3
-rw-r--r--demos/quickstart/protected/controls/TopicList.tpl2
-rw-r--r--demos/quickstart/protected/pages/Controls/DataGrid.page9
-rw-r--r--demos/quickstart/protected/pages/Controls/Samples/TDataGrid/Sample1.page14
-rw-r--r--demos/quickstart/protected/pages/Controls/Samples/TDataGrid/Sample1.php25
-rw-r--r--framework/Collections/TList.php4
-rw-r--r--framework/Collections/TMap.php4
-rw-r--r--framework/Collections/TPagedDataSource.php4
-rw-r--r--framework/Web/UI/TControl.php2
-rw-r--r--framework/Web/UI/WebControls/TBaseDataList.php40
-rw-r--r--framework/Web/UI/WebControls/TBoundColumn.php8
-rw-r--r--framework/Web/UI/WebControls/TDataGrid.php443
-rw-r--r--framework/Web/UI/WebControls/TDataGridColumn.php4
-rw-r--r--framework/Web/UI/WebControls/TDataList.php28
-rw-r--r--framework/Web/UI/WebControls/TTable.php72
15 files changed, 605 insertions, 57 deletions
diff --git a/.gitattributes b/.gitattributes
index 33f32358..e3cbd8ed 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -36,6 +36,7 @@ demos/quickstart/protected/pages/Configurations/Templates1.page -text
demos/quickstart/protected/pages/Configurations/Templates2.page -text
demos/quickstart/protected/pages/Configurations/Templates3.page -text
demos/quickstart/protected/pages/Construction.page -text
+demos/quickstart/protected/pages/Controls/DataGrid.page -text
demos/quickstart/protected/pages/Controls/DataList.page -text
demos/quickstart/protected/pages/Controls/List.page -text
demos/quickstart/protected/pages/Controls/Overview.page -text
@@ -48,6 +49,8 @@ demos/quickstart/protected/pages/Controls/Samples/TCompareValidator/Home.page -t
demos/quickstart/protected/pages/Controls/Samples/TCompareValidator/Home.php -text
demos/quickstart/protected/pages/Controls/Samples/TCustomValidator/Home.page -text
demos/quickstart/protected/pages/Controls/Samples/TCustomValidator/Home.php -text
+demos/quickstart/protected/pages/Controls/Samples/TDataGrid/Sample1.page -text
+demos/quickstart/protected/pages/Controls/Samples/TDataGrid/Sample1.php -text
demos/quickstart/protected/pages/Controls/Samples/TDataList/Sample1.page -text
demos/quickstart/protected/pages/Controls/Samples/TDataList/Sample1.php -text
demos/quickstart/protected/pages/Controls/Samples/TDropDownList/Home.page -text
diff --git a/demos/quickstart/protected/controls/TopicList.tpl b/demos/quickstart/protected/controls/TopicList.tpl
index c7e36184..f9992425 100644
--- a/demos/quickstart/protected/controls/TopicList.tpl
+++ b/demos/quickstart/protected/controls/TopicList.tpl
@@ -38,7 +38,7 @@
<a href="?page=Controls.Validation">Validation Controls</a><br/>
<a href="?page=Controls.Repeater">TRepeater</a><br/>
<a href="?page=Controls.DataList">TDataList</a><br/>
-<a href="?page=Construction">TDataGrid</a><br/>
+<a href="?page=Controls.DataGrid">TDataGrid</a><br/>
<a href="?page=Construction">Active Controls</a><br/>
<a href="?page=Construction">Authoring New Controls</a><br/>
</div>
diff --git a/demos/quickstart/protected/pages/Controls/DataGrid.page b/demos/quickstart/protected/pages/Controls/DataGrid.page
new file mode 100644
index 00000000..9170fe45
--- /dev/null
+++ b/demos/quickstart/protected/pages/Controls/DataGrid.page
@@ -0,0 +1,9 @@
+<com:TContent ID="body" >
+
+<h1>TDataGrid</h1>
+<p>
+TBC
+</p>
+<com:RunBar PagePath="Controls.Samples.TDataGrid.Sample1" />
+
+</com:TContent> \ No newline at end of file
diff --git a/demos/quickstart/protected/pages/Controls/Samples/TDataGrid/Sample1.page b/demos/quickstart/protected/pages/Controls/Samples/TDataGrid/Sample1.page
new file mode 100644
index 00000000..5c24405e
--- /dev/null
+++ b/demos/quickstart/protected/pages/Controls/Samples/TDataGrid/Sample1.page
@@ -0,0 +1,14 @@
+<com:TContent ID="body">
+
+<h1>TDataGrid Sample 1</h1>
+
+<com:TDataGrid
+ ID="DataGrid"
+ ItemStyle.BackColor="blue"
+ ItemStyle.Font.Italic="true"
+ ItemStyle.ForeColor="white"
+ AlternatingItemStyle.BackColor="green"
+ SelectedItemStyle.BackColor="red">
+</com:TDataGrid>
+
+</com:TContent> \ No newline at end of file
diff --git a/demos/quickstart/protected/pages/Controls/Samples/TDataGrid/Sample1.php b/demos/quickstart/protected/pages/Controls/Samples/TDataGrid/Sample1.php
new file mode 100644
index 00000000..bf11b133
--- /dev/null
+++ b/demos/quickstart/protected/pages/Controls/Samples/TDataGrid/Sample1.php
@@ -0,0 +1,25 @@
+<?php
+
+class Sample1 extends TPage
+{
+ protected function getDataSource()
+ {
+ return array(
+ array('name'=>'John','age'=>'31'),
+ array('name'=>'Bea','age'=>'35'),
+ array('name'=>'Rose','age'=>'33'),
+ array('name'=>'Diane','age'=>'37'),
+ array('name'=>'Bob','age'=>'30'),
+ );
+ }
+
+ public function onLoad($param)
+ {
+ parent::onLoad($param);
+ $this->DataGrid->DataSource=$this->getDataSource();
+ $this->DataGrid->SelectedItemIndex=2;
+ $this->DataGrid->dataBind();
+ }
+}
+
+?> \ No newline at end of file
diff --git a/framework/Collections/TList.php b/framework/Collections/TList.php
index b9fbd589..2946053b 100644
--- a/framework/Collections/TList.php
+++ b/framework/Collections/TList.php
@@ -246,7 +246,7 @@ class TList extends TComponent implements IteratorAggregate,ArrayAccess
foreach($data as $item)
$this->add($item);
}
- else
+ else if($data!==null)
throw new TInvalidDataTypeException('list_data_not_iterable');
}
@@ -263,7 +263,7 @@ class TList extends TComponent implements IteratorAggregate,ArrayAccess
foreach($data as $item)
$this->add($item);
}
- else
+ else if($data!==null)
throw new TInvalidDataTypeException('list_data_not_iterable');
}
diff --git a/framework/Collections/TMap.php b/framework/Collections/TMap.php
index 73665136..d5a44322 100644
--- a/framework/Collections/TMap.php
+++ b/framework/Collections/TMap.php
@@ -180,7 +180,7 @@ class TMap extends TComponent implements IteratorAggregate,ArrayAccess
foreach($data as $key=>$value)
$this->add($key,$value);
}
- else
+ else if($data!==null)
throw new TInvalidDataTypeException('map_data_not_iterable');
}
@@ -197,7 +197,7 @@ class TMap extends TComponent implements IteratorAggregate,ArrayAccess
foreach($data as $key=>$value)
$this->add($key,$value);
}
- else
+ else if($data!==null)
throw new TInvalidDataTypeException('map_data_not_iterable');
}
diff --git a/framework/Collections/TPagedDataSource.php b/framework/Collections/TPagedDataSource.php
index 5632e778..71e7c9e6 100644
--- a/framework/Collections/TPagedDataSource.php
+++ b/framework/Collections/TPagedDataSource.php
@@ -42,8 +42,10 @@ class TPagedDataSource extends TComponent implements IteratorAggregate
{
if(!($value instanceof TMap) && !($value instanceof TList))
{
- if(is_array($value) || ($value instanceof Traversable))
+ if(is_array($value))
$value=new TMap($value);
+ else if($value instanceof Traversable)
+ $value=new TList($value);
else if($value!==null)
throw new TInvalidDataTypeException('pageddatasource_datasource_invalid');
}
diff --git a/framework/Web/UI/TControl.php b/framework/Web/UI/TControl.php
index 382e3811..26aa5dc4 100644
--- a/framework/Web/UI/TControl.php
+++ b/framework/Web/UI/TControl.php
@@ -953,7 +953,7 @@ class TControl extends TComponent
$namingContainer->clearNameTable();
}
- if($this->_stage>=self::CS_INITIALIZED)
+ if($this->_stage>=self::CS_CHILD_INITIALIZED)
{
$control->initRecursive($namingContainer);
if($this->_stage>=self::CS_STATE_LOADED)
diff --git a/framework/Web/UI/WebControls/TBaseDataList.php b/framework/Web/UI/WebControls/TBaseDataList.php
index f5a09815..351fbbc9 100644
--- a/framework/Web/UI/WebControls/TBaseDataList.php
+++ b/framework/Web/UI/WebControls/TBaseDataList.php
@@ -43,11 +43,6 @@ Prado::using('System.Web.UI.WebControls.TDataBoundControl');
abstract class TBaseDataList extends TDataBoundControl
{
/**
- * @var TList list of key values
- */
- private $_dataKeys=null;
-
- /**
* 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
@@ -200,9 +195,38 @@ abstract class TBaseDataList extends TDataBoundControl
*/
public function getDataKeys()
{
- if(!$this->_dataKeys)
- $this->_dataKeys=new TList;
- return $this->_dataKeys;
+ if(($dataKeys=$this->getViewState('DataKeys',null))===null)
+ {
+ $dataKeys=new TList;
+ $this->setViewState('DataKeys',$dataKeys,null);
+ }
+ return $dataKeys;
+ }
+
+ /**
+ * Returns the value of the data at the specified field.
+ * If data is an array, TMap or TList, the value will be returned at the index
+ * of the specified field. If the data is a component with a property named
+ * as the field name, the property value will be returned.
+ * Otherwise, an exception will be raised.
+ * @param mixed data item
+ * @param mixed field name
+ * @return mixed data value at the specified field
+ * @throws TInvalidDataValueException if the data is invalid
+ */
+ protected function getDataFieldValue($data,$field)
+ {
+ if(is_array($data))
+ return $data[$field];
+ else if(($data instanceof TMap) || ($data instanceof TList))
+ return $data->itemAt($field);
+ else if(($data instanceof TComponent) && $data->canGetProperty($field))
+ {
+ $getter='get'.$field;
+ return $data->$getter();
+ }
+ else
+ throw new TInvalidDataValueException('basedatalist_datafield_invalid');
}
/**
diff --git a/framework/Web/UI/WebControls/TBoundColumn.php b/framework/Web/UI/WebControls/TBoundColumn.php
index 729f21fd..84f52034 100644
--- a/framework/Web/UI/WebControls/TBoundColumn.php
+++ b/framework/Web/UI/WebControls/TBoundColumn.php
@@ -107,11 +107,14 @@ class TBoundColumn extends TDataGridColumn
$cell->getControls()->add($textBox);
$control=$textBox;
}
+ if(($dataField=$this->getDataField())!=='')
+ $control->attachEventHandler('DataBinding',array($this,'dataBindColumn'));
+ break;
case 'Item':
case 'AlternatingItem':
case 'SelectedItem':
if(($dataField=$this->getDataField())!=='')
- $control->attachEventHandler('DataBinding',array($this,'dataBindColumn'));
+ $cell->attachEventHandler('DataBinding',array($this,'dataBindColumn'));
break;
}
}
@@ -120,8 +123,9 @@ class TBoundColumn extends TDataGridColumn
{
$item=$sender->getNamingContainer();
$data=$item->getDataItem();
+ $formatString=$this->getDataFormatString();
if(($field=$this->getDataField())!=='')
- $value=$this->formatDataValue($this->getDataFieldValue($data,$field));
+ $value=$this->formatDataValue($formatString,$this->getDataFieldValue($data,$field));
else
$value=$this->formatDataValue($data);
if(($sender instanceof TTableCell) || ($sender instanceof TTextBox))
diff --git a/framework/Web/UI/WebControls/TDataGrid.php b/framework/Web/UI/WebControls/TDataGrid.php
index 205b97a0..f25f8036 100644
--- a/framework/Web/UI/WebControls/TDataGrid.php
+++ b/framework/Web/UI/WebControls/TDataGrid.php
@@ -10,6 +10,10 @@
* @package System.Web.UI.WebControls
*/
+Prado::using('System.Web.UI.WebControls.TBaseDataList');
+Prado::using('System.Collections.TPagedDataSource');
+Prado::using('System.Web.UI.WebControls.TTable');
+
/**
* TDataGrid class
*
@@ -74,7 +78,7 @@
* datasource. The number of pages <b>PageCount</b> is calculated based the item number and the
* <b>PageSize</b> property. The datagrid will manage which section of the data source to be displayed
* based on the <b>CurrentPageIndex</b> property.
- * The second approach calculates the page number based on the <b>VirtualItemCount</b> property and
+ * The second approach calculates the page number based on the <b>VirtualCount</b> property and
* the <b>PageSize</b> property. The datagrid will always display from the beginning of the datasource
* upto the number of <b>PageSize> data items. This approach is especially useful when the datasource may
* contain too many data items to be managed by the datagrid efficiently.
@@ -119,6 +123,12 @@ class TDataGrid extends TBaseDataList
return 'table';
}
+ public function addParsedObject($object)
+ {
+ if($object instanceof TDataGridColumn)
+ $this->getColumns()->add($object);
+ }
+
public function getColumns()
{
if(!$this->_columns)
@@ -126,6 +136,13 @@ class TDataGrid extends TBaseDataList
return $this->_columns;
}
+ public function getAutoColumns()
+ {
+ if(!$this->_autoColumns)
+ $this->_autoColumns=new TDataGridColumnCollection;
+ return $this->_autoColumns;
+ }
+
public function getItems()
{
if(!$this->_items)
@@ -140,7 +157,10 @@ class TDataGrid extends TBaseDataList
*/
protected function createStyle()
{
- return new TTableStyle;
+ $style=new TTableStyle;
+ $style->setGridLines('Both');
+ $style->setCellSpacing(0);
+ return $style;
}
/**
@@ -483,19 +503,19 @@ class TDataGrid extends TBaseDataList
/**
* @return integer virtual number of items in the grid. Defaults to 0, meaning not set.
*/
- public function getVirtualItemCount()
+ public function getVirtualCount()
{
- return $this->getViewState('VirtualItemCount',0);
+ return $this->getViewState('VirtualCount',0);
}
/**
* @param integer virtual number of items in the grid
*/
- public function setVirtualItemCount($value)
+ public function setVirtualCount($value)
{
if(($value=TPropertyValue::ensureInteger($value))<0)
- throw new TInvalidDataValueException('datagrid_virtualitemcount_invalid');
- $this->setViewState('VirtualItemCount',$value,0);
+ throw new TInvalidDataValueException('datagrid_virtualcount_invalid');
+ $this->setViewState('VirtualCount',$value,0);
}
/**
@@ -515,11 +535,11 @@ class TDataGrid extends TBaseDataList
}
/**
- * @return boolean whether the footer should be displayed Defaults to true.
+ * @return boolean whether the footer should be displayed. Defaults to false.
*/
public function getShowFooter()
{
- return $this->getViewState('ShowFooter',true);
+ return $this->getViewState('ShowFooter',false);
}
/**
@@ -527,7 +547,7 @@ class TDataGrid extends TBaseDataList
*/
public function setShowFooter($value)
{
- $this->setViewState('ShowFooter',TPropertyValue::ensureBoolean($value),true);
+ $this->setViewState('ShowFooter',TPropertyValue::ensureBoolean($value),false);
}
/**
@@ -693,13 +713,386 @@ class TDataGrid extends TBaseDataList
{
$this->raiseEvent('PageIndexChanged',$this,$param);
}
+
+ /**
+ * Saves item count in viewstate.
+ * This method is invoked right before control state is to be saved.
+ * @param mixed event parameter
+ */
+ protected function onSaveState($param)
+ {
+ if($this->_items)
+ $this->setViewState('ItemCount',$this->_items->getCount(),0);
+ else
+ $this->clearViewState('ItemCount');
+ }
+
+ /**
+ * Loads item count information from viewstate.
+ * This method is invoked right after control state is loaded.
+ * @param mixed event parameter
+ */
+ protected function onLoadState($param)
+ {
+ if(!$this->getIsDataBound())
+ $this->restoreItemsFromViewState();
+ $this->clearViewState('ItemCount');
+ }
+
+ private function createPagedDataSource()
+ {
+ $ds=new TPagedDataSource;
+ $ds->setCurrentPageIndex($this->getCurrentPageIndex());
+ $ds->setPageSize($this->getPageSize());
+ $ds->setAllowPaging($this->getAllowPaging());
+ $ds->setAllowCustomPaging($this->getAllowCustomPaging());
+ $ds->setVirtualCount($this->getVirtualCount());
+ return $ds;
+ }
+
+ /**
+ * Clears up all items in the data list.
+ */
+ public function reset()
+ {
+ $this->getControls()->clear();
+ $this->getItems()->clear();
+ $this->_header=null;
+ $this->_footer=null;
+ }
+
+ protected function restoreGridFromViewState()
+ {
+ $this->reset();
+ $this->_pagedDataSource=$ds=$this->createPagedDataSource();
+ // set dummy data source
+ // create columns from viewstate
+ if($columns->getCount()>0)
+ {
+ foreach($columns as $column)
+ $column->initialize();
+ $allowPaging=$ds->getAllowPaging();
+ if($allowPaging)
+ // create pager
+ // create header
+ // may need to use the first row of data to build items here
+ $selectedIndex=$this->getSelectedItemIndex();
+ $editIndex=$this->getEditItemIndex();
+ $index=0;
+ foreach($ds as $data)
+ {
+ if($index===$editIndex)
+ $itemType='EditItem';
+ else if($index===$selectedIndex)
+ $itemType='SelectedItem';
+ else if($index % 2)
+ $itemType='AlternatingItem';
+ else
+ $itemType='Item';
+ // create item
+ $index++;
+ }
+ // create footer
+ // create pager
+ }
+ $this->_pagedDataSource=null;
+ }
+
+ /**
+ * Performs databinding to populate data list items from data source.
+ * This method is invoked by dataBind().
+ * You may override this function to provide your own way of data population.
+ * @param Traversable the data
+ */
+ protected function performDataBinding($data)
+ {
+ $this->reset();
+ $keys=$this->getDataKeys();
+ $keys->clear();
+ $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');
+ $columns=$this->getAllColumns($ds);
+ $items=$this->getItems();
+
+ if(($columnCount=$columns->getCount())>0)
+ {
+ foreach($columns as $column)
+ $column->initialize();
+ $allowPaging=$ds->getAllowPaging();
+ if($allowPaging)
+ $this->createPager(-1,-1,$columnCount,$ds);
+ $this->createItemInternal(-1,-1,'Header',true,null,$columns);
+ $selectedIndex=$this->getSelectedItemIndex();
+ $editIndex=$this->getEditItemIndex();
+ $index=0;
+ $dsIndex=$ds->getAllowPaging()?$ds->getFirstIndexInPage():0;
+ foreach($ds as $data)
+ {
+ if($keyField!=='')
+ $keys->add($this->getDataFieldValue($data,$keyField));
+ if($index===$editIndex)
+ $itemType='EditItem';
+ else if($index===$selectedIndex)
+ $itemType='SelectedItem';
+ else if($index % 2)
+ $itemType='AlternatingItem';
+ else
+ $itemType='Item';
+ $items->add($this->createItemInternal($index,$dsIndex,$itemType,true,$data,$columns));
+ $index++;
+ $dsIndex++;
+ }
+ $this->createItemInternal(-1,-1,'Footer',true,null,$columns);
+ if($allowPaging)
+ $this->createPager(-1,-1,$columnCount,$ds);
+ $this->setViewState('ItemCount',$index,0);
+ $this->setViewState('PageCount',$ds->getPageCount(),0);
+ $this->setViewState('DataSourceCount',$ds->getDataSourceCount(),0);
+ }
+ else
+ {
+ $this->setViewState('ItemCount',$index,0);
+ $this->setViewState('PageCount',0,0);
+ $this->setViewState('DataSourceCount',0,0);
+ }
+ $this->_pagedDataSource=null;
+ }
+
+ /**
+ * Creates a datagrid item instance based on the item type and index.
+ * @param integer zero-based item index
+ * @param string item type, may be 'Header', 'Footer', 'Item', 'Separator', 'AlternatingItem', 'SelectedItem', 'EditItem'.
+ * @return TDataGridItem created data list item
+ */
+ protected function createItem($itemIndex,$dataSourceIndex,$itemType)
+ {
+ return new TDataGridItem($itemIndex,$dataSourceIndex,$itemType);
+ }
+
+ private function createItemInternal($itemIndex,$dataSourceIndex,$itemType,$dataBind,$dataItem,$columns)
+ {
+ $item=$this->createItem($itemIndex,$dataSourceIndex,$itemType);
+ $this->initializeItem($item,$columns);
+ $param=new TDataGridItemEventParameter($item);
+ if($dataBind)
+ {
+ $item->setDataItem($dataItem);
+ $this->onItemCreated($param);
+ $this->getControls()->add($item);
+ $item->dataBind();
+ $this->onItemDataBound($param);
+ $item->setDataItem(null);
+ }
+ else
+ {
+ $this->onItemCreated($param);
+ $this->getControls()->add($item);
+ }
+ return $item;
+ }
+
+ protected function initializeItem($item,$columns)
+ {
+ $cells=$item->getCells();
+ $itemType=$item->getItemType();
+ $index=0;
+ foreach($columns as $column)
+ {
+ if($itemType==='Header')
+ $cell=new TTableHeaderCell;
+ else
+ $cell=new TTableCell;
+ $column->initializeCell($cell,$index,$itemType);
+ $cells->add($cell);
+ $index++;
+ }
+ }
+
+ private function createPager($itemIndex,$dataSourceIndex,$columnSpan,$pagedDataSource)
+ {
+ $item=$this->createItem($itemIndex,$dataSourceIndex,'Pager');
+ $this->initializePager($item,$columnSpan,$pagedDataSource);
+ $this->onItemCreated(new TDataGridItemEventParameter($item));
+ $this->getControls()->add($item);
+ return $item;
+ }
+
+ protected function initializePager($pager,$columnSpan,$pagedDataSource)
+ {
+ $cell=new TTableCell;
+ if($columnSpan>1)
+ $cell->setColumnSpan($columnSpan);
+ $this->buildPager($cell,$pagedDataSource);
+ $pager->getCells()->add($cell);
+ }
+
+ protected function buildPager($cell,$dataSource)
+ {
+ switch($this->getPagerStyle()->getMode())
+ {
+ case 'NextPrev':
+ $this->buildNextPrevPager($cell,$dataSource);
+ break;
+ case 'Numeric':
+ $this->buildNumericPager($cell,$dataSource);
+ break;
+ }
+ }
+
+ protected function buildNextPrevPager($cell,$dataSource)
+ {
+ $style=$this->getPagerStyle();
+ $controls=$cell->getControls();
+ if($dataSource->getIsFirstPage())
+ {
+ $label=new TLabel;
+ $label->setText($style->getPrevPageText());
+ $controls->add($label);
+ }
+ else
+ {
+ $button=new TLinkButton;
+ $button->setText($style->getPrevPageText());
+ $button->setCommandName('page');
+ $button->setCommandParameter('prev');
+ $button->setCausesValidation(false);
+ $controls->add($button);
+ }
+ $controls->add('&nbsp;');
+ if($dataSource->getIsLastPage())
+ {
+ $label=new TLabel;
+ $label->setText($style->getNextPageText());
+ $controls->add($label);
+ }
+ else
+ {
+ $button=new TLinkButton;
+ $button->setText($style->getNextPageText());
+ $button->setCommandName('page');
+ $button->setCommandParameter('next');
+ $button->setCausesValidation(false);
+ $controls->add($button);
+ }
+ }
+
+ protected function buildNumericPager($cell,$dataSource)
+ {
+ $style=$this->getPagerStyle();
+ $controls=$cell->getControls();
+ $pageCount=$dataSource->getPageCount();
+ $pageIndex=$dataSource->getCurrentPageIndex()+1;
+ $maxButtonCount=$style->getPageButtonCount();
+ $buttonCount=$maxButtonCount>$pageCount?$pageCount:$maxButtonCount;
+ $startPageIndex=1;
+ $endPageIndex=$buttonCount;
+ if($pageIndex>$endPageIndex)
+ {
+ $startPageIndex=((int)($pageIndex/$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)
+ {
+ $button=new TLinkButton;
+ $button->setText('...');
+ $button->setCommandName('page');
+ $button->setCommandParameter($startPageIndex-1);
+ $button->setCausesValidation(false);
+ $controls->add($button);
+ $controls->add('&nbsp;');
+ }
+
+ for($i=$startPageIndex;$i<=$endPageIndex;++$i)
+ {
+ if($i===$pageIndex)
+ {
+ $label=new TLabel;
+ $label->setText("$i");
+ $controls->add($label);
+ }
+ else
+ {
+ $button=new TLinkButton;
+ $button->setText("$i");
+ $button->setCommandName('page');
+ $button->setCommandParameter($i);
+ $button->setCausesValidation(false);
+ $controls->add($button);
+ }
+ if($i<$endPageIndex)
+ $controls->add('&nbsp;');
+ }
+
+ if($pageCount>$endPageIndex)
+ {
+ $controls->add('&nbsp;');
+ $button=new TLinkButton;
+ $button->setText('...');
+ $button->setCommandName('page');
+ $button->setCommandParameter($endPageIndex+1);
+ $button->setCausesValidation(false);
+ $controls->add($button);
+ }
+ }
+
+ protected function getAllColumns($dataSource)
+ {
+ $list=new TList($this->getColumns());
+ $list->mergeWith($this->createAutoColumns($dataSource));
+ return $list;
+ }
+
+ protected function createAutoColumns($dataSource)
+ {
+ if(!$dataSource || $dataSource->getCount()<=0)
+ return null;
+ $autoColumns=$this->getAutoColumns();
+ $autoColumns->clear();
+ foreach($dataSource as $row)
+ {
+ foreach($row as $key=>$value)
+ {
+ $column=new TBoundColumn;
+ if(is_string($key))
+ {
+ $column->setHeaderText($key);
+ $column->setDataField($key);
+ $column->setSortExpression($key);
+ $column->setOwner($this);
+ $autoColumns->add($column);
+ }
+ else
+ {
+ $column->setHeaderText('Item');
+ $column->setDataField($key);
+ $column->setSortExpression('Item');
+ $column->setOwner($this);
+ $autoColumns->add($column);
+ }
+ }
+ break;
+ }
+ return $autoColumns;
+ }
}
+
/**
* TDataGridItemEventParameter class
*
* TDataGridItemEventParameter encapsulates the parameter data for
* {@link TDataGrid::onItemCreated ItemCreated} event of {@link TDataGrid} controls.
- * The {@link getItem Item} property indicates the DataList item related with the event.
+ * The {@link getItem Item} property indicates the datagrid item related with the event.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Revision: $ $Date: $
@@ -716,7 +1109,7 @@ class TDataGridItemEventParameter extends TEventParameter
/**
* Constructor.
- * @param TDataGridItem DataList item related with the corresponding event
+ * @param TDataGridItem datagrid item related with the corresponding event
*/
public function __construct(TDataGridItem $item)
{
@@ -724,7 +1117,7 @@ class TDataGridItemEventParameter extends TEventParameter
}
/**
- * @return TDataGridItem DataList item related with the corresponding event
+ * @return TDataGridItem datagrid item related with the corresponding event
*/
public function getItem()
{
@@ -738,7 +1131,7 @@ class TDataGridItemEventParameter extends TEventParameter
* TDataGridCommandEventParameter encapsulates the parameter data for
* {@link TDataGrid::onItemCommand ItemCommand} event of {@link TDataGrid} controls.
*
- * The {@link getItem Item} property indicates the DataList item related with the event.
+ * The {@link getItem Item} property indicates the datagrid item related with the event.
* The {@link getCommandSource CommandSource} refers to the control that originally
* raises the Command event.
*
@@ -760,7 +1153,7 @@ class TDataGridCommandEventParameter extends TCommandEventParameter
/**
* Constructor.
- * @param TDataGridItem DataList item responsible for the event
+ * @param TDataGridItem datagrid item responsible for the event
* @param TControl original event sender
* @param TCommandEventParameter original event parameter
*/
@@ -903,7 +1296,7 @@ class TDataGridPageChangedEventParameter extends TEventParameter
* such as heading section, footer section, or a data item.
* The index and data value of the item can be accessed via {@link getItemIndex ItemIndex}>
* and {@link getDataItem DataItem} properties, respectively. The type of the item
- * is given by {@link getItemType ItemType} property. Property {@link getDataSetIndex DataSetIndex}
+ * is given by {@link getItemType ItemType} property. Property {@link getDataSourceIndex DataSourceIndex}
* gives the index of the item from the bound data source.
*
* @author Qiang Xue <qiang.xue@gmail.com>
@@ -914,13 +1307,13 @@ class TDataGridPageChangedEventParameter extends TEventParameter
class TDataGridItem extends TTableRow implements INamingContainer
{
/**
- * @var integer index of the data item in the Items collection of DataList
+ * @var integer index of the data item in the Items collection of datagrid
*/
private $_itemIndex='';
/**
* @var integer index of the item from the bound data source
*/
- private $_dataSetIndex=0;
+ private $_dataSourceIndex=0;
/**
* type of the TDataGridItem
* @var string
@@ -934,13 +1327,13 @@ class TDataGridItem extends TTableRow implements INamingContainer
/**
* Constructor.
- * @param integer zero-based index of the item in the item collection of DataList
+ * @param integer zero-based index of the item in the item collection of datagrid
* @param string item type, can be 'Header','Footer','Item','AlternatingItem','SelectedItem','EditItem','Separator','Pager'.
*/
- public function __construct($itemIndex,$dataSetIndex,$itemType)
+ public function __construct($itemIndex,$dataSourceIndex,$itemType)
{
$this->_itemIndex=$itemIndex;
- $this->_dataSetIndex=$dataSetIndex;
+ $this->_dataSourceIndex=$dataSourceIndex;
$this->setItemType($itemType);
}
@@ -961,7 +1354,7 @@ class TDataGridItem extends TTableRow 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 datagrid
*/
public function getItemIndex()
{
@@ -971,9 +1364,9 @@ class TDataGridItem extends TTableRow implements INamingContainer
/**
* @return integer the index of the datagrid item from the bound data source
*/
- public function getDataSetIndex()
+ public function getDataSourceIndex()
{
- return $this->_dataSetIndex;
+ return $this->_dataSourceIndex;
}
/**
@@ -1080,7 +1473,7 @@ class TDataGridPagerStyle extends TTableItemStyle
public function setMode($value)
{
- $this->_mode=TPropertyValue::ensureEnum($value,'NextPrev','NumericPages');
+ $this->_mode=TPropertyValue::ensureEnum($value,'NextPrev','Numeric');
}
public function getNextPageText()
diff --git a/framework/Web/UI/WebControls/TDataGridColumn.php b/framework/Web/UI/WebControls/TDataGridColumn.php
index dc1d8521..5e43f735 100644
--- a/framework/Web/UI/WebControls/TDataGridColumn.php
+++ b/framework/Web/UI/WebControls/TDataGridColumn.php
@@ -206,12 +206,12 @@ abstract class TDataGridColumn extends TComponent
return $this->_viewState;
}
- protected function getOwner()
+ public function getOwner()
{
return $this->_owner;
}
- protected function setOwner(TDataGrid $value)
+ public function setOwner(TDataGrid $value)
{
$this->_owner=$value;
}
diff --git a/framework/Web/UI/WebControls/TDataList.php b/framework/Web/UI/WebControls/TDataList.php
index ebaf9568..6f61f8ef 100644
--- a/framework/Web/UI/WebControls/TDataList.php
+++ b/framework/Web/UI/WebControls/TDataList.php
@@ -415,6 +415,22 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
}
/**
+ * @return mixed the key value of the currently selected item
+ * @throws TInvalidOperationException if {@link getDataKeyField DataKeyField} is empty.
+ */
+ public function getSelectedDataKey()
+ {
+ if($this->getDataKeyField()==='')
+ throw new TInvalidOperationException('datalist_datakeyfield_required');
+ $index=$this->getSelectedIndex();
+ $dataKeys=$this->getDataKeys();
+ if($index>=0 && $index<$dataKeys->getCount())
+ return $dataKeys->itemAt($index);
+ else
+ return null;
+ }
+
+ /**
* @return integer the zero-based index of the edit item in {@link getItems Items}.
* A value -1 means no item is in edit mode.
*/
@@ -1091,17 +1107,7 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs
foreach($data as $dataItem)
{
if($keyField!=='')
- {
- if(is_array($dataItem) || ($dataItem instanceof TMap))
- $keys->add($dataItem[$keyField]);
- else if(($dataItem instanceof TComponent) && $dataItem->canGetProperty($keyField))
- {
- $getter='get'.$keyField;
- $keys->add($dataItem->$getter());
- }
- else
- throw new TInvalidDataValueException('datalist_keyfield_invalid',$keyField);
- }
+ $keys->add($this->getDataFieldValue($dataItem,$keyField));
if($itemIndex===0 && $this->_headerTemplate!=='')
$this->_header=$this->createItemInternal(-1,'Header',true,null);
if($hasSeparator && $itemIndex>0)
diff --git a/framework/Web/UI/WebControls/TTable.php b/framework/Web/UI/WebControls/TTable.php
index 13cbd0b1..3ca3d51d 100644
--- a/framework/Web/UI/WebControls/TTable.php
+++ b/framework/Web/UI/WebControls/TTable.php
@@ -124,7 +124,7 @@ class TTable extends TWebControl
public function getRows()
{
if(!$this->_rows)
- $this->_rows=new TTableRowCollection();
+ $this->_rows=new TTableRowCollection($this);
return $this->_rows;
}
@@ -352,7 +352,7 @@ class TTableRow extends TWebControl
public function getCells()
{
if(!$this->_cells)
- $this->_cells=new TTableCellCollection();
+ $this->_cells=new TTableCellCollection($this);
return $this->_cells;
}
@@ -698,6 +698,20 @@ class TTableHeaderCell extends TTableCell
class TTableRowCollection extends TList
{
/**
+ * @var mixed row collection owner
+ */
+ private $_owner=null;
+
+ /**
+ * Constructor.
+ * @param mixed row collection owner
+ */
+ public function __construct($owner=null)
+ {
+ $this->_owner=$owner;
+ }
+
+ /**
* Only string or instance of TControl can be added into collection.
* @param mixed the item to be added
*/
@@ -705,6 +719,26 @@ class TTableRowCollection extends TList
{
return ($item instanceof TTableRow);
}
+
+ /**
+ * Overrides the parent implementation with customized processing of the newly added item.
+ * @param mixed the newly added item
+ */
+ protected function addedItem($item)
+ {
+ if($this->_owner)
+ $this->_owner->getControls()->add($item);
+ }
+
+ /**
+ * Overrides the parent implementation with customized processing of the removed item.
+ * @param mixed the removed item
+ */
+ protected function removedItem($item)
+ {
+ if($this->_owner)
+ $this->_owner->getControls()->remove($item);
+ }
}
@@ -721,6 +755,20 @@ class TTableRowCollection extends TList
class TTableCellCollection extends TList
{
/**
+ * @var mixed cell collection owner
+ */
+ private $_owner=null;
+
+ /**
+ * Constructor.
+ * @param mixed cell collection owner
+ */
+ public function __construct($owner=null)
+ {
+ $this->_owner=$owner;
+ }
+
+ /**
* Only string or instance of TTableCell can be added into collection.
* @param mixed the item to be added
*/
@@ -728,5 +776,25 @@ class TTableCellCollection extends TList
{
return ($item instanceof TTableCell);
}
+
+ /**
+ * Overrides the parent implementation with customized processing of the newly added item.
+ * @param mixed the newly added item
+ */
+ protected function addedItem($item)
+ {
+ if($this->_owner)
+ $this->_owner->getControls()->add($item);
+ }
+
+ /**
+ * Overrides the parent implementation with customized processing of the removed item.
+ * @param mixed the removed item
+ */
+ protected function removedItem($item)
+ {
+ if($this->_owner)
+ $this->_owner->getControls()->remove($item);
+ }
}
?> \ No newline at end of file