summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxue <>2006-05-04 20:00:46 +0000
committerxue <>2006-05-04 20:00:46 +0000
commit42df6f47862c2f1495ded49f758dbc46f9d9e930 (patch)
treeee849b9758bcbd5c1b1aac40761ce68417eba2bb
parentc00193d23726bcb05b1fe53c4dfb3fc38b0a22e5 (diff)
Merge from 3.0 branch till 1023.
-rw-r--r--.gitattributes3
-rw-r--r--HISTORY9
-rw-r--r--UPGRADE7
-rw-r--r--demos/quickstart/protected/pages/Advanced/State.page4
-rw-r--r--demos/quickstart/protected/pages/Controls/NewControl.page6
-rw-r--r--demos/quickstart/protected/pages/Controls/Samples/LabeledTextBox2/LabeledTextBox.php2
-rw-r--r--framework/Exceptions/messages.txt2
-rw-r--r--framework/Web/Services/TPageService.php2
-rw-r--r--framework/Web/THttpRequest.php46
-rw-r--r--framework/Web/UI/TCompositeControl.php39
-rw-r--r--framework/Web/UI/TPage.php1
-rw-r--r--framework/Web/UI/TTemplateControl.php7
-rw-r--r--framework/Web/UI/WebControls/TDataGrid.php93
-rw-r--r--framework/Web/UI/WebControls/TRepeatInfo.php8
-rw-r--r--framework/Web/UI/WebControls/TTable.php56
-rw-r--r--framework/Web/UI/WebControls/TTableFooterRow.php48
-rw-r--r--framework/Web/UI/WebControls/TTableHeaderRow.php48
-rw-r--r--framework/Web/UI/WebControls/TTableRow.php20
18 files changed, 360 insertions, 41 deletions
diff --git a/.gitattributes b/.gitattributes
index b9a4e3b3..88be958c 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -934,6 +934,7 @@ framework/Web/UI/ActiveControls/TCallbackClientScript.php -text
framework/Web/UI/ActiveControls/TCallbackClientSideOptions.php -text
framework/Web/UI/ActiveControls/TCallbackResponse.php -text
framework/Web/UI/TClientScriptManager.php -text
+framework/Web/UI/TCompositeControl.php -text
framework/Web/UI/TControl.php -text
framework/Web/UI/TControlAdapter.php -text
framework/Web/UI/TForm.php -text
@@ -1006,7 +1007,9 @@ framework/Web/UI/WebControls/TStatements.php -text
framework/Web/UI/WebControls/TStyle.php -text
framework/Web/UI/WebControls/TTable.php -text
framework/Web/UI/WebControls/TTableCell.php -text
+framework/Web/UI/WebControls/TTableFooterRow.php -text
framework/Web/UI/WebControls/TTableHeaderCell.php -text
+framework/Web/UI/WebControls/TTableHeaderRow.php -text
framework/Web/UI/WebControls/TTableRow.php -text
framework/Web/UI/WebControls/TTemplateColumn.php -text
framework/Web/UI/WebControls/TTextBox.php -text
diff --git a/HISTORY b/HISTORY
index b0fdd00f..c80b8f18 100644
--- a/HISTORY
+++ b/HISTORY
@@ -7,11 +7,14 @@ NEW: SQLMap (Wei)
Version 3.0.1 June 1, 2006
==========================
-CHG: Ticket#153 - TAssetManager now ignores .svn directories (Qiang)
-CHG: Ticket#154 - HTML comments are now parsed as regular template strings (Qiang)
-ENH: Ticket#151 - added sanity check GET parameters in constructUrl() (Qiang)
+ENH: Ticket#150 - TDataGrid and TDataList now render table section tags (Qiang)
ENH: Ticket#152 - constituent parts of TWizard are exposed (Qiang)
ENH: added sanity check to calling event handlers (Qiang)
+CHG: Ticket#153 - TAssetManager now ignores .svn directories (Qiang)
+CHG: Ticket#154 - HTML comments are now parsed as regular template strings (Qiang)
+CHG: Ticket#151 - URL format is modified to handle empty GET values (Qiang)
+NEW: TTableHeaderRow, TTableFooterRow and table section support (Qiang)
+NEW: TCompositeControl (Qiang)
Version 3.0.0 May 1, 2006
=========================
diff --git a/UPGRADE b/UPGRADE
index 5fa4fab5..2cbf3355 100644
--- a/UPGRADE
+++ b/UPGRADE
@@ -16,6 +16,13 @@ for both A and B.
Upgrading from v3.0.0
---------------------
+- URL format is modified when THttpRequest.UrlFormat=='Path'.
+ This modification affects both the URLs generated by calling constructUrl()
+ and the URLs understood by PRADO. In particular, PRADO now understands
+ the following URL format:
+ /index.php/ServiceID,ServiceParam/Name1,Value1/Name2,Value2/...
+ In v3.0.0, the above URL is written as:
+ /index.php/ServiceID/ServiceParam/Name1/Value1/Name2/Value2/...
Upgrading from v3.0.0 RC2
-------------------------
diff --git a/demos/quickstart/protected/pages/Advanced/State.page b/demos/quickstart/protected/pages/Advanced/State.page
index 30d5b2fc..8d69d6a4 100644
--- a/demos/quickstart/protected/pages/Advanced/State.page
+++ b/demos/quickstart/protected/pages/Advanced/State.page
@@ -27,7 +27,7 @@ $caption = $this->getViewState('Caption');
Control state is like view state in every aspect except that control state cannot be disabled. Control state is intended to be used for storing crucial state information without which a page or control may not work properly.
</p>
<p>
-To store and retrieve a variable in control state, use the followign commands,
+To store and retrieve a variable in control state, use the following commands,
</p>
<com:TTextHighlighter CssClass="source">
$this->setControlState('Caption',$caption);
@@ -39,7 +39,7 @@ $caption = $this->getControlState('Caption');
Application state refers to data that is persistent across user sessions and page requests. A typical example of application state is the user visit counter. The counter value is persistent even if the current user session terminates. Note, view state and control state are lost if the user requests for a different page, while session state is lost if the user session terminates.
</p>
<p>
-To store and retrieve a variable in application state, use the followign commands,
+To store and retrieve a variable in application state, use the following commands,
</p>
<com:TTextHighlighter CssClass="source">
$application->setGlobalState('Caption',$caption);
diff --git a/demos/quickstart/protected/pages/Controls/NewControl.page b/demos/quickstart/protected/pages/Controls/NewControl.page
index 61209b6b..51d0cc02 100644
--- a/demos/quickstart/protected/pages/Controls/NewControl.page
+++ b/demos/quickstart/protected/pages/Controls/NewControl.page
@@ -13,7 +13,7 @@ In general, there are two ways of writing new controls: composition of existing
Composition is the easiest way of creating new controls. It mainly involves instantiating existing controls, configuring them and making them the constituent components. The properties of the constituent components are exposed through <a href="?page=Fundamentals.Components">subproperties</a>.
</p>
<p>
-One can compose a new control in two ways. One is to override the <tt>TControl::createChildControls()</tt> method. The other is to extend <tt>TTemplateControl</tt> (or its child classes) and write a control template. The latter is easier to use and can organize the layout constituent compoents more intuitively, while the former is more efficient because it does not require parsing of the template.
+One can compose a new control in two ways. One is to extend <tt>TCompositeControl</tt> and override the <tt>TControl::createChildControls()</tt> method. The other is to extend <tt>TTemplateControl</tt> (or its child classes) and write a control template. The latter is easier to use and can organize the layout constituent compoents more intuitively, while the former is more efficient because it does not require parsing of the template.
</p>
<p>
As an example, we show how to create a labeled textbox called <tt>LabeledTextBox</tt> using the above two approaches. A labeled textbox displays a label besides a textbox. We want reuse the PRADO provided <tt>TLabel</tt> and <tt>TTextBox</tt> to accomplish this task.
@@ -48,13 +48,13 @@ In the above, the method call to <tt>ensureChildControls()</tt> ensures that bot
<h3>Composition by Overriding <tt>createChildControls()</tt></h3>
<p>
-For a composite control as simple as <tt>LabeledTextBox</tt>, it is better to create it by extending <tt>TControl</tt> and overriding the <tt>createChildControls()</tt> method, because it does not use templates and thus saves template parsing time. Note, the new control class must implement the <tt>INamingContainer</tt> interface to ensure the global uniqueness of the ID of its constituent controls.
+For a composite control as simple as <tt>LabeledTextBox</tt>, it is better to create it by extending <tt>TCompositeControl</tt> and overriding the <tt>createChildControls()</tt> method, because it does not use templates and thus saves template parsing time.
</p>
<p>
Complete code for <tt>LabeledTextBox</tt> is shown as follows,
</p>
<com:TTextHighlighter CssClass="source">
-class LabeledTextBox extends TControl implements INamingContainer {
+class LabeledTextBox extends TCompositeControl {
private $_label;
private $_textbox;
protected function createChildControls() {
diff --git a/demos/quickstart/protected/pages/Controls/Samples/LabeledTextBox2/LabeledTextBox.php b/demos/quickstart/protected/pages/Controls/Samples/LabeledTextBox2/LabeledTextBox.php
index 4b8ac2c2..5bbf4ce2 100644
--- a/demos/quickstart/protected/pages/Controls/Samples/LabeledTextBox2/LabeledTextBox.php
+++ b/demos/quickstart/protected/pages/Controls/Samples/LabeledTextBox2/LabeledTextBox.php
@@ -1,6 +1,6 @@
<?php
-class LabeledTextBox extends TControl implements INamingContainer
+class LabeledTextBox extends TCompositeControl
{
private $_label;
private $_textbox;
diff --git a/framework/Exceptions/messages.txt b/framework/Exceptions/messages.txt
index 20bafba2..3df84dde 100644
--- a/framework/Exceptions/messages.txt
+++ b/framework/Exceptions/messages.txt
@@ -270,6 +270,8 @@ view_visible_readonly = TView.Visible is read-only. Use TView.Active to togg
wizard_step_invalid = The step to be activated cannot be found in wizard step collection.
wizard_command_invalid = Invalid wizard navigation command '{0}'.
+table_tablesection_outoforder = TTable table sections must be in the order of: Header, Body and Footer.
+
completewizardstep_steptype_readonly = TCompleteWizardStep.StepType is read-only.
wizardstepcollection_wizardstep_required = TWizardStepCollection can only accept objects of TWizardStep or its derived classes.
diff --git a/framework/Web/Services/TPageService.php b/framework/Web/Services/TPageService.php
index 2448c0c3..54112fb1 100644
--- a/framework/Web/Services/TPageService.php
+++ b/framework/Web/Services/TPageService.php
@@ -460,7 +460,7 @@ class TPageService extends TService
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Revision: $ $Date: $
- * @package System.Services
+ * @package System.Web.Services
* @since 3.0
*/
class TPageConfiguration extends TComponent
diff --git a/framework/Web/THttpRequest.php b/framework/Web/THttpRequest.php
index 9b06076e..4e04ecca 100644
--- a/framework/Web/THttpRequest.php
+++ b/framework/Web/THttpRequest.php
@@ -60,6 +60,11 @@
class THttpRequest extends TApplicationComponent implements IteratorAggregate,ArrayAccess,IModule
{
/**
+ * Separator used to separate GET variable name and value when URL format is Path.
+ */
+ const URL_PARAM_SEPARATOR=',';
+
+ /**
* @var boolean whether the module is initialized
*/
private $_initialized=false;
@@ -159,15 +164,22 @@ class THttpRequest extends TApplicationComponent implements IteratorAggregate,Ar
if($this->getUrlFormat()==='Path' && ($pathInfo=trim($this->_pathInfo,'/'))!=='')
{
$paths=explode('/',$pathInfo);
- $n=count($paths);
- $getVariables=array();
- for($i=0;$i<$n-1;++$i)
+ foreach($paths as $path)
{
- $name=$paths[$i];
- if(($pos=strpos($name,'[]'))!==false)
- $getVariables[substr($name,0,$pos)][]=$paths[++$i];
- else
- $getVariables[$name]=$paths[++$i];
+ if(($path=trim($path))!=='')
+ {
+ if(($pos=strpos($path,','))!==false)
+ {
+ $name=substr($path,0,$pos);
+ $value=substr($path,$pos+1);
+ if(($pos=strpos($name,'[]'))!==false)
+ $getVariables[substr($name,0,$pos)][]=$value;
+ else
+ $getVariables[$name]=$value;
+ }
+ else
+ $getVariables[$path]='';
+ }
}
$this->_items=array_merge($getVariables,array_merge($_GET,$_POST));
}
@@ -224,7 +236,7 @@ class THttpRequest extends TApplicationComponent implements IteratorAggregate,Ar
/**
* Sets the format of URLs constructed and interpretted by the request module.
* A 'Get' URL format is like index.php?name1=value1&name2=value2
- * while a 'Path' URL format is like index.php/name1/value1/name2/value.
+ * while a 'Path' URL format is like index.php/name1,value1/name2,value.
* Changing the UrlFormat will affect {@link constructUrl} and how GET variables
* are parsed.
* @param string the format of URLs. Valid values include 'Path' and 'Get'.
@@ -460,12 +472,9 @@ class THttpRequest extends TApplicationComponent implements IteratorAggregate,Ar
{
$name=urlencode($name.'[]');
foreach($value as $v)
- {
- if(($v=trim($v))!=='')
- $url.=$amp.$name.'='.$v;
- }
+ $url.=$amp.$name.'='.$v;
}
- else if(($value=trim($value))!=='')
+ else
$url.=$amp.urlencode($name).'='.urlencode($value);
}
}
@@ -476,19 +485,16 @@ class THttpRequest extends TApplicationComponent implements IteratorAggregate,Ar
if(is_array($value))
{
foreach($value as $v)
- {
- if(($v=trim($v))!=='')
- $url.=$amp.$name.'[]='.$v;
- }
+ $url.=$amp.$name.'[]='.$v;
}
- else if(($value=trim($value))!=='')
+ else
$url.=$amp.$name.'='.$value;
}
}
}
if($this->getUrlFormat()==='Path')
{
- $url=strtr($url,array($amp=>'/','?'=>'/','='=>'/'));
+ $url=strtr($url,array($amp=>'/','?'=>'/','='=>self::URL_PARAM_SEPARATOR));
if(defined('SID') && SID != '' && !((int)ini_get('session.use_cookies')===1 && ((int)ini_get('session.use_only_cookies')===1)))
$url.='?'.SID;
return $this->getApplicationUrl().'/'.$url;
diff --git a/framework/Web/UI/TCompositeControl.php b/framework/Web/UI/TCompositeControl.php
new file mode 100644
index 00000000..4e33bb83
--- /dev/null
+++ b/framework/Web/UI/TCompositeControl.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * TCompositeControl 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
+ */
+
+/**
+ * TCompositeControl class.
+ * TCompositeControl is the base class for controls that are composed
+ * by other controls.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Revision: $ $Date: $
+ * @package System.Web.UI
+ * @since 3.0
+ */
+class TCompositeControl extends TControl implements INamingContainer
+{
+ /**
+ * Performs the OnInit step for the control and all its child controls.
+ * This method overrides the parent implementation
+ * by ensuring child controls are created first.
+ * Only framework developers should use this method.
+ * @param TControl the naming container control
+ */
+ protected function initRecursive($namingContainer=null)
+ {
+ $this->ensureChildControls();
+ parent::initRecursive($namingContainer);
+ }
+}
+
+?> \ No newline at end of file
diff --git a/framework/Web/UI/TPage.php b/framework/Web/UI/TPage.php
index 598fb9dc..94f1f475 100644
--- a/framework/Web/UI/TPage.php
+++ b/framework/Web/UI/TPage.php
@@ -13,6 +13,7 @@
Prado::using('System.Web.UI.WebControls.*');
Prado::using('System.Web.UI.TControl');
Prado::using('System.Web.UI.WebControls.TWebControl');
+Prado::using('System.Web.UI.TCompositeControl');
Prado::using('System.Web.UI.TTemplateControl');
Prado::using('System.Web.UI.TForm');
Prado::using('System.Web.UI.TClientScriptManager');
diff --git a/framework/Web/UI/TTemplateControl.php b/framework/Web/UI/TTemplateControl.php
index f18678f1..0595a9e5 100644
--- a/framework/Web/UI/TTemplateControl.php
+++ b/framework/Web/UI/TTemplateControl.php
@@ -11,6 +11,11 @@
*/
/**
+ * Includes TCompositeControl class
+ */
+Prado::using('System.Web.UI.TCompositeControl');
+
+/**
* TTemplateControl class.
* TTemplateControl is the base class for all controls that use templates.
* By default, a control template is assumed to be in a file under the same
@@ -22,7 +27,7 @@
* @package System.Web.UI
* @since 3.0
*/
-class TTemplateControl extends TControl implements INamingContainer
+class TTemplateControl extends TCompositeControl
{
/**
* template file extension.
diff --git a/framework/Web/UI/WebControls/TDataGrid.php b/framework/Web/UI/WebControls/TDataGrid.php
index 55b12ebc..6ff6faba 100644
--- a/framework/Web/UI/WebControls/TDataGrid.php
+++ b/framework/Web/UI/WebControls/TDataGrid.php
@@ -357,6 +357,39 @@ class TDataGrid extends TBaseDataList implements INamingContainer
}
/**
+ * @return string caption for the datagrid
+ */
+ public function getCaption()
+ {
+ return $this->getViewState('Caption','');
+ }
+
+ /**
+ * @param string caption for the datagrid
+ */
+ public function setCaption($value)
+ {
+ $this->setViewState('Caption',$value,'');
+ }
+
+ /**
+ * @return string datagrid caption alignment. Defaults to 'NotSet'.
+ */
+ public function getCaptionAlign()
+ {
+ return $this->getViewState('CaptionAlign','NotSet');
+ }
+
+ /**
+ * @param string datagrid caption alignment. Valid values include
+ * 'NotSet','Top','Bottom','Left','Right'.
+ */
+ public function setCaptionAlign($value)
+ {
+ $this->setViewState('CaptionAlign',TPropertyValue::ensureEnum($value,'NotSet','Top','Bottom','Left','Right'),'NotSet');
+ }
+
+ /**
* @return TDataGridItem the header item
*/
public function getHeader()
@@ -1444,6 +1477,23 @@ class TDataGrid extends TBaseDataList implements INamingContainer
}
/**
+ * Renders the openning tag for the datagrid control which will render table caption if present.
+ * @param THtmlWriter the writer used for the rendering purpose
+ */
+ public function renderBeginTag($writer)
+ {
+ parent::renderBeginTag($writer);
+ if(($caption=$this->getCaption())!=='')
+ {
+ if(($align=$this->getCaptionAlign())!=='NotSet')
+ $writer->addAttribute('align',strtolower($align));
+ $writer->renderBeginTag('caption');
+ $writer->write($caption);
+ $writer->renderEndTag();
+ }
+ }
+
+ /**
* Renders the datagrid.
* @param THtmlWriter writer for the rendering purpose
*/
@@ -1457,12 +1507,7 @@ class TDataGrid extends TBaseDataList implements INamingContainer
$this->_topPager->renderControl($writer);
$writer->writeLine();
}
- $this->renderBeginTag($writer);
- $this->_header->renderControl($writer);
- foreach($this->getItems() as $item)
- $item->renderControl($writer);
- $this->_footer->renderControl($writer);
- $this->renderEndTag($writer);
+ $this->renderTable($writer);
if($this->_bottomPager)
{
$writer->writeLine();
@@ -1470,6 +1515,38 @@ class TDataGrid extends TBaseDataList implements INamingContainer
}
}
}
+
+ /**
+ * Renders the tabular data.
+ * @param THtmlWriter writer
+ */
+ protected function renderTable($writer)
+ {
+ $this->renderBeginTag($writer);
+ if($this->_header->getVisible())
+ {
+ $writer->writeLine();
+ $writer->renderBeginTag('thead');
+ $this->_header->render($writer);
+ $writer->renderEndTag();
+ }
+ $writer->writeLine();
+ $writer->renderBeginTag('tbody');
+ foreach($this->getItems() as $item)
+ $item->renderControl($writer);
+ $writer->renderEndTag();
+
+ if($this->_footer->getVisible())
+ {
+ $writer->writeLine();
+ $writer->renderBeginTag('tfoot');
+ $this->_footer->render($writer);
+ $writer->renderEndTag();
+ }
+
+ $writer->writeLine();
+ $this->renderEndTag($writer);
+ }
}
/**
@@ -1758,6 +1835,10 @@ class TDataGridItem extends TTableRow implements INamingContainer
$this->_itemIndex=$itemIndex;
$this->_dataSourceIndex=$dataSourceIndex;
$this->setItemType($itemType);
+ if($itemType===TDataGrid::IT_HEADER)
+ $this->setTableSection('Header');
+ else if($itemType===TDataGrid::IT_FOOTER)
+ $this->setTableSection('Footer');
}
/**
diff --git a/framework/Web/UI/WebControls/TRepeatInfo.php b/framework/Web/UI/WebControls/TRepeatInfo.php
index 10c49691..81b82c33 100644
--- a/framework/Web/UI/WebControls/TRepeatInfo.php
+++ b/framework/Web/UI/WebControls/TRepeatInfo.php
@@ -261,6 +261,7 @@ class TRepeatInfo extends TComponent
// render items
if($tableLayout)
{
+ $writer->renderBeginTag('tbody');
$column=0;
for($i=0;$i<$itemCount;++$i)
{
@@ -297,6 +298,7 @@ class TRepeatInfo extends TComponent
$column=0;
}
}
+ $writer->renderEndTag();
}
else
{
@@ -353,6 +355,7 @@ class TRepeatInfo extends TComponent
if($tableLayout)
{
+ $writer->renderBeginTag('tbody');
$renderedItems=0;
for($row=0;$row<$rows;++$row)
{
@@ -407,6 +410,7 @@ class TRepeatInfo extends TComponent
$writer->renderEndTag();
$writer->writeLine();
}
+ $writer->renderEndTag();
}
else
{
@@ -461,6 +465,7 @@ class TRepeatInfo extends TComponent
{
if($tableLayout)
{
+ $writer->renderBeginTag('thead');
$writer->renderBeginTag('tr');
if($columns>1)
$writer->addAttribute('colspan',"$columns");
@@ -471,6 +476,7 @@ class TRepeatInfo extends TComponent
$user->renderItem($writer,$this,'Header',-1);
$writer->renderEndTag();
$writer->renderEndTag();
+ $writer->renderEndTag();
}
else
{
@@ -492,6 +498,7 @@ class TRepeatInfo extends TComponent
{
if($tableLayout)
{
+ $writer->renderBeginTag('tfoot');
$writer->renderBeginTag('tr');
if($columns>1)
$writer->addAttribute('colspan',"$columns");
@@ -501,6 +508,7 @@ class TRepeatInfo extends TComponent
$user->renderItem($writer,$this,'Footer',-1);
$writer->renderEndTag();
$writer->renderEndTag();
+ $writer->renderEndTag();
}
else
$user->renderItem($writer,$this,'Footer',-1);
diff --git a/framework/Web/UI/WebControls/TTable.php b/framework/Web/UI/WebControls/TTable.php
index e7baca02..aaed37df 100644
--- a/framework/Web/UI/WebControls/TTable.php
+++ b/framework/Web/UI/WebControls/TTable.php
@@ -298,11 +298,63 @@ class TTable extends TWebControl
{
if($this->getHasControls())
{
- $writer->writeLine();
+ $renderTableSection=false;
foreach($this->getControls() as $row)
{
- $row->renderControl($writer);
+ if($row->getTableSection()!=='Body')
+ {
+ $renderTableSection=true;
+ break;
+ }
+ }
+ if($renderTableSection)
+ {
+ $currentSection='Header';
+ $writer->writeLine();
+ foreach($this->getControls() as $index=>$row)
+ {
+ if(($section=$row->getTableSection())===$currentSection)
+ {
+ if($index===0 && $currentSection==='Header')
+ $writer->renderBeginTag('thead');
+ }
+ else
+ {
+ if($currentSection==='Header')
+ {
+ if($index>0)
+ $writer->renderEndTag();
+ if($section==='Body')
+ $writer->renderBeginTag('tbody');
+ else
+ $writer->renderBeginTag('tfoot');
+ $currentSection=$section;
+ }
+ else if($currentSection==='Body')
+ {
+ $writer->renderEndTag();
+ if($section==='Footer')
+ $writer->renderBeginTag('tfoot');
+ else
+ throw new TConfigurationException('table_tablesection_outoforder');
+ $currentSection=$section;
+ }
+ else // Footer
+ throw new TConfigurationException('table_tablesection_outoforder');
+ }
+ $row->renderControl($writer);
+ $writer->writeLine();
+ }
+ $writer->renderEndTag();
+ }
+ else
+ {
$writer->writeLine();
+ foreach($this->getControls() as $row)
+ {
+ $row->renderControl($writer);
+ $writer->writeLine();
+ }
}
}
}
diff --git a/framework/Web/UI/WebControls/TTableFooterRow.php b/framework/Web/UI/WebControls/TTableFooterRow.php
new file mode 100644
index 00000000..3b178d52
--- /dev/null
+++ b/framework/Web/UI/WebControls/TTableFooterRow.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * TTableFooterRow 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 TTableRow class.
+ */
+Prado::using('System.Web.UI.WebControls.TTableRow');
+
+/**
+ * TTableFooterRow class.
+ *
+ * TTableFooterRow displays a table footer row.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Revision: $ $Date: $
+ * @package System.Web.UI.WebControls
+ * @since 3.0.1
+ */
+class TTableFooterRow extends TTableRow
+{
+ /**
+ * @return string location of a row in a table. Always returns 'Footer'.
+ */
+ public function getTableSection()
+ {
+ return 'Footer';
+ }
+
+ /**
+ * @param string location of a row in a table.
+ * @throws TInvalidOperationException if this method is invoked
+ */
+ public function setTableSection($value)
+ {
+ throw new TInvalidOperationException('tablefooterrow_tablesection_readonly');
+ }
+}
+
+?> \ No newline at end of file
diff --git a/framework/Web/UI/WebControls/TTableHeaderRow.php b/framework/Web/UI/WebControls/TTableHeaderRow.php
new file mode 100644
index 00000000..87e01abd
--- /dev/null
+++ b/framework/Web/UI/WebControls/TTableHeaderRow.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * TTableHeaderRow 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 TTableRow class.
+ */
+Prado::using('System.Web.UI.WebControls.TTableRow');
+
+/**
+ * TTableHeaderRow class.
+ *
+ * TTableHeaderRow displays a table header row.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Revision: $ $Date: $
+ * @package System.Web.UI.WebControls
+ * @since 3.0.1
+ */
+class TTableHeaderRow extends TTableRow
+{
+ /**
+ * @return string location of a row in a table. Always returns 'Header'.
+ */
+ public function getTableSection()
+ {
+ return 'Header';
+ }
+
+ /**
+ * @param string location of a row in a table.
+ * @throws TInvalidOperationException if this method is invoked
+ */
+ public function setTableSection($value)
+ {
+ throw new TInvalidOperationException('tableheaderrow_tablesection_readonly');
+ }
+}
+
+?> \ No newline at end of file
diff --git a/framework/Web/UI/WebControls/TTableRow.php b/framework/Web/UI/WebControls/TTableRow.php
index daf921ce..b0e0bfbe 100644
--- a/framework/Web/UI/WebControls/TTableRow.php
+++ b/framework/Web/UI/WebControls/TTableRow.php
@@ -11,10 +11,9 @@
*/
/**
- * Includes TTableCell and TTableHeaderCell classes
+ * Includes TTableCell class
*/
Prado::using('System.Web.UI.WebControls.TTableCell');
-Prado::using('System.Web.UI.WebControls.TTableHeaderCell');
/**
* TTableRow class.
@@ -122,6 +121,23 @@ class TTableRow extends TWebControl
}
/**
+ * @return string location of a row in a table. Defaults to 'Body'.
+ */
+ public function getTableSection()
+ {
+ return $this->getViewState('TableSection','Body');
+ }
+
+ /**
+ * @param string location of a row in a table. Valid values include 'Header', 'Footer' and 'Body'.
+ */
+ public function setTableSection($value)
+ {
+ $value=TPropertyValue::ensureEnum($value,'Header','Body','Footer');
+ $this->setViewState('TableSection',$value,'Body');
+ }
+
+ /**
* Renders body contents of the table row
* @param THtmlWriter writer for the rendering purpose
*/