From 54900d0145dfda07bde40dc6e1f0b31935b55444 Mon Sep 17 00:00:00 2001 From: xue <> Date: Tue, 17 Jan 2006 23:58:54 +0000 Subject: --- .gitattributes | 3 + demos/quickstart/protected/controls/TopicList.tpl | 2 +- .../protected/pages/Controls/DataGrid.page | 9 + .../pages/Controls/Samples/TDataGrid/Sample1.page | 14 + .../pages/Controls/Samples/TDataGrid/Sample1.php | 25 ++ framework/Collections/TList.php | 4 +- framework/Collections/TMap.php | 4 +- framework/Collections/TPagedDataSource.php | 4 +- framework/Web/UI/TControl.php | 2 +- framework/Web/UI/WebControls/TBaseDataList.php | 40 +- framework/Web/UI/WebControls/TBoundColumn.php | 8 +- framework/Web/UI/WebControls/TDataGrid.php | 443 +++++++++++++++++++-- framework/Web/UI/WebControls/TDataGridColumn.php | 4 +- framework/Web/UI/WebControls/TDataList.php | 28 +- framework/Web/UI/WebControls/TTable.php | 72 +++- 15 files changed, 605 insertions(+), 57 deletions(-) create mode 100644 demos/quickstart/protected/pages/Controls/DataGrid.page create mode 100644 demos/quickstart/protected/pages/Controls/Samples/TDataGrid/Sample1.page create mode 100644 demos/quickstart/protected/pages/Controls/Samples/TDataGrid/Sample1.php 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 @@ Validation Controls
TRepeater
TDataList
-TDataGrid
+TDataGrid
Active Controls
Authoring New Controls
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 @@ + + +

TDataGrid

+

+TBC +

+ + +
\ 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 @@ + + +

TDataGrid Sample 1

+ + + + +
\ 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 @@ +'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 @@ -42,11 +42,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. @@ -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 PageCount is calculated based the item number and the * PageSize property. The datagrid will manage which section of the data source to be displayed * based on the CurrentPageIndex property. - * The second approach calculates the page number based on the VirtualItemCount property and + * The second approach calculates the page number based on the VirtualCount property and * the PageSize property. The datagrid will always display from the beginning of the datasource * upto the number of 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(' '); + 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(' '); + } + + 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(' '); + } + + if($pageCount>$endPageIndex) + { + $controls->add(' '); + $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 * @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 @@ -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 @@ -414,6 +414,22 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs return null; } + /** + * @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; } @@ -697,6 +697,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); + } } @@ -720,6 +754,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 -- cgit v1.2.3