summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitattributes1
-rw-r--r--HISTORY1
-rw-r--r--demos/quickstart/protected/pages/Controls/DataGrid.page4
-rw-r--r--demos/quickstart/protected/pages/Controls/Samples/TDataGrid/Sample3.page28
-rw-r--r--demos/quickstart/protected/pages/Controls/Samples/TDataGrid/Sample3.php2
-rw-r--r--framework/Util/TSimpleDateFormatter.php3
-rw-r--r--framework/Web/UI/TClientScriptManager.php13
-rw-r--r--framework/Web/UI/WebControls/TDataBoundControl.php1
-rw-r--r--framework/Web/UI/WebControls/TDatePicker.php7
-rw-r--r--framework/Web/UI/WebControls/TDropDownListColumn.php286
-rw-r--r--framework/Web/UI/WebControls/TStyleSheet.php2
-rw-r--r--tests/FunctionalTests/quickstart/Controls/DataGrid3TestCase.php2
-rw-r--r--tests/FunctionalTests/tickets/protected/pages/Ticket351.page1
-rw-r--r--tests/FunctionalTests/tickets/tests/Ticket274TestCase.php4
14 files changed, 324 insertions, 31 deletions
diff --git a/.gitattributes b/.gitattributes
index b158779a..2606fb46 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1800,6 +1800,7 @@ framework/Web/UI/WebControls/TDataSourceView.php -text
framework/Web/UI/WebControls/TDataTypeValidator.php -text
framework/Web/UI/WebControls/TDatePicker.php -text
framework/Web/UI/WebControls/TDropDownList.php -text
+framework/Web/UI/WebControls/TDropDownListColumn.php -text
framework/Web/UI/WebControls/TEditCommandColumn.php -text
framework/Web/UI/WebControls/TEmailAddressValidator.php -text
framework/Web/UI/WebControls/TExpression.php -text
diff --git a/HISTORY b/HISTORY
index 97191f40..92ff82dc 100644
--- a/HISTORY
+++ b/HISTORY
@@ -28,6 +28,7 @@ CHG: Added more conditions in the requirement checker (Qiang)
CHG: TControl::findControlsByType() now only returns objects of the specified type (Qiang)
CHG: Moved createdOnTemplate() and addParsedObject() from TControl to TComponent (Qiang)
NEW: TDateTimeStamp class for supporting time stamps outside 1970-2038 using float (Wei)
+NEW: TDropDownListColumn (Qiang)
Version 3.0.3 August 6, 2006
============================
diff --git a/demos/quickstart/protected/pages/Controls/DataGrid.page b/demos/quickstart/protected/pages/Controls/DataGrid.page
index 392b78ab..2a51a3de 100644
--- a/demos/quickstart/protected/pages/Controls/DataGrid.page
+++ b/demos/quickstart/protected/pages/Controls/DataGrid.page
@@ -22,6 +22,7 @@ PRADO provides five types of columns:
<ul>
<li><tt>TBoundColumn</tt> associates cells with a specific field of data and displays the cells according to their modes.</li>
<li><tt>TCheckBoxColumn</tt> associates cells with a specific field of data and displays in each cell a checkbox whose check state is determined by the data field value.</li>
+ <li><tt>TDropDownListColumn</tt> associates cells with a specific field of data and displays the cells according to their modes. If in edit mode, a cell will be displayed with a <tt>TDropDownList</tt>.</li>
<li><tt>THyperLinkColumn</tt> displays in the cells a hyperlink whose caption and URL can be either statically specified or bound to some fields of data.</li>
<li><tt>TEditCommandColumn</tt> displays in the cells edit/update/cancel command buttons according to the state of the item that a cell resides in.</li>
<li><tt>TButtonColumn</tt> displays in the cells a command button.</li>
@@ -114,7 +115,8 @@ The following example uses manually specified columns to show a list of book inf
Besides the rich data presentation functionalities as demonstrated in previous section, TDataGrid is also highly user interactive. An import usage of TDataGrid is editing or deleting rows of data. The <tt>TBoundColumn</tt> can adjust the associated cell presentation according to the mode of datagrid items. When an item is in browsing mode, the cell is displayed with a static text; when the item is in editing mode, a textbox is displayed to collect user inputs. TDataGrid provides <tt>TEditCommandColumn</tt> for switching item modes. In addition, <tt>TButtonColumn</tt> offers developers the flexibility of creating arbitrary buttons for various user interactions.
</p>
<p>
-The following example shows how to make the previous book information table an interactive one. It allows users to edit and delete book items from the table. Two additional columns are used in the example to allow users interact with the datagrid: <tt>TEditCommandColumn</tt> and <tt>TButtonColumn</tt>.
+The following example shows how to make the previous book information table an interactive one. It allows users to edit and delete book items from the table. Two additional columns are used in the example to allow users interact with the datagrid: <tt>TEditCommandColumn</tt> and <tt>TButtonColumn</tt>. In addition,
+<tt>TDropDownListColumn</tt> replaces the previous <tt>TTemplateColumn</tt> to allow users to select a rating from a dropdown list. Note, it is also possible to use <tt>TTemplateColumn</tt> to achieve the same task.
</p>
<com:RunBar PagePath="Controls.Samples.TDataGrid.Sample3" />
diff --git a/demos/quickstart/protected/pages/Controls/Samples/TDataGrid/Sample3.page b/demos/quickstart/protected/pages/Controls/Samples/TDataGrid/Sample3.page
index 96affa4a..5fb19c6f 100644
--- a/demos/quickstart/protected/pages/Controls/Samples/TDataGrid/Sample3.page
+++ b/demos/quickstart/protected/pages/Controls/Samples/TDataGrid/Sample3.page
@@ -50,22 +50,18 @@
HeaderText="In-stock"
DataField="instock"
/>
- <com:TTemplateColumn ID="RatingColumn" HeaderText="Rating">
- <prop:ItemTemplate>
- <img src="images/star<%#$this->Parent->DataItem['rating']%>.gif" alt="" />
- </prop:ItemTemplate>
- <prop:EditItemTemplate>
- <com:TDropDownList
- SelectedValue=<%#$this->Parent->DataItem['rating'] %>
- ID="Rating">
- <com:TListItem Value="1" />
- <com:TListItem Value="2" />
- <com:TListItem Value="3" />
- <com:TListItem Value="4" />
- <com:TListItem Value="5" />
- </com:TDropDownList>
- </prop:EditItemTemplate>
- </com:TTemplateColumn>
+ <com:TDropDownListColumn
+ ID="RatingColumn"
+ HeaderText="Rating"
+ DataField="rating"
+ >
+ <prop:DataFormatString><img src="images/star%s.gif" alt="" /></prop:DataFormatString>
+ <com:TListItem Value="1" />
+ <com:TListItem Value="2" />
+ <com:TListItem Value="3" />
+ <com:TListItem Value="4" />
+ <com:TListItem Value="5" />
+ </com:TDropDownListColumn>
<com:TEditCommandColumn
HeaderText="Edit"
HeaderStyle.Width="100px"
diff --git a/demos/quickstart/protected/pages/Controls/Samples/TDataGrid/Sample3.php b/demos/quickstart/protected/pages/Controls/Samples/TDataGrid/Sample3.php
index 69a164c6..bb18f36b 100644
--- a/demos/quickstart/protected/pages/Controls/Samples/TDataGrid/Sample3.php
+++ b/demos/quickstart/protected/pages/Controls/Samples/TDataGrid/Sample3.php
@@ -164,7 +164,7 @@ class Sample3 extends TPage
$item->PublisherColumn->TextBox->Text, // publisher
$item->PriceColumn->TextBox->Text, // price
$item->InStockColumn->CheckBox->Checked, // instock
- $item->RatingColumn->Rating->SelectedValue // rating
+ $item->RatingColumn->DropDownList->SelectedValue // rating
);
$this->DataGrid->EditItemIndex=-1;
$this->DataGrid->DataSource=$this->Data;
diff --git a/framework/Util/TSimpleDateFormatter.php b/framework/Util/TSimpleDateFormatter.php
index 9c2975d5..046a3442 100644
--- a/framework/Util/TSimpleDateFormatter.php
+++ b/framework/Util/TSimpleDateFormatter.php
@@ -118,7 +118,8 @@ class TSimpleDateFormatter
$bits['dd'] = str_pad("{$date['mday']}", 2, '0', STR_PAD_LEFT);
$bits['d'] = $date['mday'];
- return str_replace(array_keys($bits), $bits, $this->pattern);
+ $pattern = preg_replace('/M{3,4}/', 'MM', $this->pattern);
+ return str_replace(array_keys($bits), $bits, $pattern);
}
public function getMonthPattern()
diff --git a/framework/Web/UI/TClientScriptManager.php b/framework/Web/UI/TClientScriptManager.php
index 3d0ced60..18d6089e 100644
--- a/framework/Web/UI/TClientScriptManager.php
+++ b/framework/Web/UI/TClientScriptManager.php
@@ -133,7 +133,7 @@ class TClientScriptManager extends TApplicationComponent
$this->_registeredPradoScripts[$name]=true;
else
throw new TInvalidOperationException('csmanager_pradoscript_invalid',$name);
- $basePath=$this->getPradoBaseScriptPath();
+ $basePath=$this->getPradoScriptBasePath();
foreach(self::$_pradoScripts[$name] as $script)
{
if(!isset($this->_publishedPradoFiles[$script]))
@@ -145,7 +145,10 @@ class TClientScriptManager extends TApplicationComponent
}
}
- protected function getPradoBaseScriptPath()
+ /**
+ * @return string the directory containing the PRADO js script files
+ */
+ protected function getPradoScriptBasePath()
{
$basePath = Prado::getFrameworkPath().'/'.self::SCRIPT_PATH;
if($this->getApplication()->getMode()===TApplication::STATE_DEBUG)
@@ -155,15 +158,15 @@ class TClientScriptManager extends TApplicationComponent
}
/**
- * Renders the <script> tag that will load the javascript library files.
- * @param THtmlWriter writer that renders the <script> tag.
+ * Renders the HTML tags for PRADO js files
+ * @param THtmlWriter writer
*/
protected function renderPradoScripts($writer)
{
$files=implode(',',array_keys($this->_publishedPradoFiles));
if($files!=='')
{
- $basePath=$this->getPradoBaseScriptPath();
+ $basePath=$this->getPradoScriptBasePath();
$scriptLoader=$basePath.'/'.self::SCRIPT_LOADER;
$url=$this->publishFilePath($scriptLoader).'?js='.trim($files,',');
if($this->getApplication()->getMode()===TApplication::STATE_DEBUG)
diff --git a/framework/Web/UI/WebControls/TDataBoundControl.php b/framework/Web/UI/WebControls/TDataBoundControl.php
index 798f9155..38ed42dd 100644
--- a/framework/Web/UI/WebControls/TDataBoundControl.php
+++ b/framework/Web/UI/WebControls/TDataBoundControl.php
@@ -462,6 +462,7 @@ abstract class TDataBoundControl extends TWebControl
/**
* Validates if the parameter is a valid data source.
* If it is a string or an array, it will be converted as a TList object.
+ * @param Traversable|array|string data source to be validated
* @return Traversable the data that is traversable
* @throws TInvalidDataTypeException if the data is neither null nor Traversable
*/
diff --git a/framework/Web/UI/WebControls/TDatePicker.php b/framework/Web/UI/WebControls/TDatePicker.php
index 02361e54..2a9340e5 100644
--- a/framework/Web/UI/WebControls/TDatePicker.php
+++ b/framework/Web/UI/WebControls/TDatePicker.php
@@ -263,14 +263,15 @@ class TDatePicker extends TTextBox
/**
* Sets the date for the date picker using timestamp.
- * @param integer time stamp for the date picker
+ * @param float time stamp for the date picker
*/
public function setTimeStamp($value)
{
- $date = TPropertyValue::ensureInteger($value);
+ $date = TPropertyValue::ensureFloat($value);
$formatter = Prado::createComponent('System.Util.TSimpleDateFormatter',
$this->getDateFormat());
- $this->setText($formatter->format($date));
+ $d =$formatter->format($date);
+ $this->setText($d);
}
/**
diff --git a/framework/Web/UI/WebControls/TDropDownListColumn.php b/framework/Web/UI/WebControls/TDropDownListColumn.php
new file mode 100644
index 00000000..bcbd87e4
--- /dev/null
+++ b/framework/Web/UI/WebControls/TDropDownListColumn.php
@@ -0,0 +1,286 @@
+<?php
+/**
+ * TDropDownListColumn class file
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ $Date: $
+ * @package System.Web.UI.WebControls
+ */
+
+Prado::using('System.Web.UI.WebControls.TDataGridColumn');
+Prado::using('System.Web.UI.WebControls.TDropDownList');
+
+/**
+ * TDropDownListColumn class
+ *
+ * TDropDownListColumn represents a column that is bound to a field in a data source.
+ * The cells in the column will be displayed using the data indexed by
+ * {@link setDataField DataField}. You can customize the display by
+ * setting {@link setDataFormatString DataFormatString}.
+ *
+ * If {@link setReadOnly ReadOnly} is false, TDropDownListColumn will display cells in edit mode
+ * with dropdown lists. Otherwise, a static text is displayed.
+ *
+ * There are two approaches to specify the list items available for selection.
+ * The first approach uses template syntax as follows,
+ * <code>
+ * <com:TDropDownListColumn ....>
+ * <com:TListItem Value="1" Text="first item" />
+ * <com:TListItem Value="2" Text="second item" />
+ * <com:TListItem Value="3" Text="third item" />
+ * </com:TDropDownListColumn>
+ * </code>
+ * The second approach specifies a data source to be bound to the dropdown lists
+ * by setting {@link setListDataSource ListDataSource}. Like generic list controls,
+ * you may also want to specify which data fields are used for item values and texts
+ * by setting {@link setListValueField ListValueField} and
+ * {@link setListTextField ListTextField}, respectively.
+ * Furthermore, the item texts may be formatted by using {@link setListTextFormatString ListTextFormatString}.
+ * Note, if you specify {@link setListDataSource ListDataSource}, do it before
+ * calling the datagrid's dataBind().
+ *
+ * The dropdown list control in the TDropDownListColumn can be accessed by one of
+ * the following two methods:
+ * <code>
+ * $datagridItem->DropDownListColumnID->DropDownList
+ * $datagridItem->DropDownListColumnID->Controls[0]
+ * </code>
+ * The second method is possible because the dropdown list control created within the
+ * datagrid cell is the first child.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Revision: $ $Date: $
+ * @package System.Web.UI.WebControls
+ * @since 3.0.4
+ */
+class TDropDownListColumn extends TDataGridColumn
+{
+ private $_stateLoaded=false;
+ private $_dataBound=false;
+ private $_listControl=null;
+
+ public function __construct()
+ {
+ $this->_listControl=new TDropDownList;
+ }
+
+ /**
+ * Loads items from viewstate.
+ * This method overrides the parent implementation by loading list items
+ * @param mixed state values
+ */
+ public function loadState($state)
+ {
+ parent::loadState($state);
+ $this->_stateLoaded=true;
+ if(!$this->_dataBound)
+ $this->_listControl->getItems()->loadState($this->getViewState('Items',null));
+ }
+
+ /**
+ * Saves items into viewstate.
+ * This method overrides the parent implementation by saving list items
+ */
+ public function saveState()
+ {
+ $this->setViewState('Items',$this->_listControl->getItems()->saveState(),null);
+ return parent::saveState();
+ }
+
+ /**
+ * Adds object parsed from template to the control.
+ * This method adds only {@link TListItem} objects into the {@link getItems Items} collection.
+ * All other objects are ignored.
+ * @param mixed object parsed from template
+ */
+ public function addParsedObject($object)
+ {
+ // Do not add items from template if items are loaded from viewstate
+ if(!$this->_stateLoaded && ($object instanceof TListItem))
+ {
+ $object->setSelected(false);
+ $index=$this->_listControl->getItems()->add($object);
+ }
+ }
+
+ /**
+ * @return string the field name from the data source to bind to the column
+ */
+ public function getDataField()
+ {
+ return $this->getViewState('DataField','');
+ }
+
+ /**
+ * @param string the field name from the data source to bind to the column
+ */
+ public function setDataField($value)
+ {
+ $this->setViewState('DataField',$value,'');
+ }
+
+ /**
+ * @return string the formatting string used to control how the bound data will be displayed.
+ */
+ public function getDataFormatString()
+ {
+ return $this->getViewState('DataFormatString','');
+ }
+
+ /**
+ * @param string the formatting string used to control how the bound data will be displayed.
+ */
+ public function setDataFormatString($value)
+ {
+ $this->setViewState('DataFormatString',$value,'');
+ }
+
+ /**
+ * @return boolean whether the items in the column can be edited. Defaults to false.
+ */
+ public function getReadOnly()
+ {
+ return $this->getViewState('ReadOnly',false);
+ }
+
+ /**
+ * @param boolean whether the items in the column can be edited
+ */
+ public function setReadOnly($value)
+ {
+ $this->setViewState('ReadOnly',TPropertyValue::ensureBoolean($value),false);
+ }
+
+ /**
+ * @return Traversable data source to be bound to the dropdown list boxes.
+ */
+ public function getListDataSource()
+ {
+ return $this->_listControl->getDataSource();
+ }
+
+ /**
+ * @param Traversable|array|string data source to be bound to the dropdown list boxes.
+ */
+ public function setListDataSource($value)
+ {
+ $this->_listControl->setDataSource($value);
+ }
+
+ /**
+ * @return string the data field used to populate the values of the dropdown list items. Defaults to empty.
+ */
+ public function getListValueField()
+ {
+ return $this->getViewState('ListValueField','');
+ }
+
+ /**
+ * @param string the data field used to populate the values of the dropdown list items
+ */
+ public function setListValueField($value)
+ {
+ $this->setViewState('ListValueField',$value,'');
+ }
+
+ /**
+ * @return string the data field used to populate the texts of the dropdown list items. Defaults to empty.
+ */
+ public function getListTextField()
+ {
+ return $this->getViewState('ListTextField','');
+ }
+
+ /**
+ * @param string the data field used to populate the texts of the dropdown list items
+ */
+ public function setListTextField($value)
+ {
+ $this->setViewState('ListTextField',$value,'');
+ }
+
+ /**
+ * @return string the formatting string used to control how the list item texts will be displayed.
+ */
+ public function getListTextFormatString()
+ {
+ return $this->getViewState('ListTextFormatString','');
+ }
+
+ /**
+ * @param string the formatting string used to control how the list item texts will be displayed.
+ */
+ public function setListTextFormatString($value)
+ {
+ $this->setViewState('ListTextFormatString',$value,'');
+ }
+
+ /**
+ * Initializes the specified cell to its initial values.
+ * This method overrides the parent implementation.
+ * It creates a textbox for item in edit mode and the column is not read-only.
+ * Otherwise it displays a static text.
+ * The caption of the button and the static text are retrieved
+ * from the datasource.
+ * @param TTableCell the cell to be initialized.
+ * @param integer the index to the Columns property that the cell resides in.
+ * @param string the type of cell (Header,Footer,Item,AlternatingItem,EditItem,SelectedItem)
+ */
+ public function initializeCell($cell,$columnIndex,$itemType)
+ {
+ parent::initializeCell($cell,$columnIndex,$itemType);
+ if(!$this->_dataBound && $this->_listControl->getDataSource()!==null)
+ {
+ $this->_listControl->setDataTextField($this->getListTextField());
+ $this->_listControl->setDataValueField($this->getListValueField());
+ $this->_listControl->setDataTextFormatString($this->getListTextFormatString());
+ $this->_listControl->dataBind();
+ $this->_dataBound=true;
+ }
+ switch($itemType)
+ {
+ case TDataGrid::IT_EDITITEM:
+ if(!$this->getReadOnly())
+ {
+ $listControl=clone $this->_listControl;
+ $cell->getControls()->add($listControl);
+ $cell->registerObject('DropDownList',$listControl);
+ $control=$listControl;
+ }
+ else
+ $control=$cell;
+ $control->attachEventHandler('OnDataBinding',array($this,'dataBindColumn'));
+ break;
+ case TDataGrid::IT_ITEM:
+ case TDataGrid::IT_ALTERNATINGITEM:
+ case TDataGrid::IT_SELECTEDITEM:
+ if($this->getDataField()!=='')
+ $cell->attachEventHandler('OnDataBinding',array($this,'dataBindColumn'));
+ break;
+ }
+ }
+
+ /**
+ * Databinds a cell in the column.
+ * This method is invoked when datagrid performs databinding.
+ * It populates the content of the cell with the relevant data from data source.
+ */
+ public function dataBindColumn($sender,$param)
+ {
+ $item=$sender->getNamingContainer();
+ $data=$item->getDataItem();
+ if(($field=$this->getDataField())!=='')
+ $data=$this->getDataFieldValue($data,$field);
+ $formatString=$this->getDataFormatString();
+ $value=$this->formatDataValue($formatString,$data);
+ if($sender instanceof TTableCell)
+ $sender->setText($value);
+ else if($sender instanceof TDropDownList)
+ $sender->setSelectedValue($data);
+ }
+}
+
+?> \ No newline at end of file
diff --git a/framework/Web/UI/WebControls/TStyleSheet.php b/framework/Web/UI/WebControls/TStyleSheet.php
index 3e172697..f8f4ab9f 100644
--- a/framework/Web/UI/WebControls/TStyleSheet.php
+++ b/framework/Web/UI/WebControls/TStyleSheet.php
@@ -24,7 +24,7 @@
*
* @author Wei Zhuo <weizhuo[at]gmail[dot]com>
* @version : $ Tue Jul 4 04:38:16 EST 2006 $
- * @package System.Web.UI.WebControl
+ * @package System.Web.UI.WebControls
* @since 3.0.2
*/
class TStyleSheet extends TControl
diff --git a/tests/FunctionalTests/quickstart/Controls/DataGrid3TestCase.php b/tests/FunctionalTests/quickstart/Controls/DataGrid3TestCase.php
index 39a5aba6..f44432dd 100644
--- a/tests/FunctionalTests/quickstart/Controls/DataGrid3TestCase.php
+++ b/tests/FunctionalTests/quickstart/Controls/DataGrid3TestCase.php
@@ -20,7 +20,7 @@ class DataGrid3TestCase extends SeleniumTestCase
$this->type("ctl0\$body\$DataGrid\$ctl2\$ctl2", "Addison Wesley Professional");
$this->type("ctl0\$body\$DataGrid\$ctl2\$ctl3", "\$57.04");
$this->click("//input[@name='ctl0\$body\$DataGrid\$ctl2\$ctl4']", "");
- $this->select("ctl0\$body\$DataGrid\$ctl2\$Rating", "label=1");
+ $this->select("ctl0\$body\$DataGrid\$ctl2\$ctl5", "label=1");
$this->clickAndWait("link=Save", "");
// verify the 2nd row is saved
diff --git a/tests/FunctionalTests/tickets/protected/pages/Ticket351.page b/tests/FunctionalTests/tickets/protected/pages/Ticket351.page
index 5fb65f20..78a7488d 100644
--- a/tests/FunctionalTests/tickets/protected/pages/Ticket351.page
+++ b/tests/FunctionalTests/tickets/protected/pages/Ticket351.page
@@ -1,6 +1,7 @@
<com:TContent ID="Content">
<com:TDatePicker ID="Birthdate"
DateFormat="MMM/d/yyyy"
+ TimeStamp="-2000000000"
FromYear="1900" UpToYear="1990" InputMode="DropDownList" />
<br />
diff --git a/tests/FunctionalTests/tickets/tests/Ticket274TestCase.php b/tests/FunctionalTests/tickets/tests/Ticket274TestCase.php
index 6a5ae0ff..8b74e565 100644
--- a/tests/FunctionalTests/tickets/tests/Ticket274TestCase.php
+++ b/tests/FunctionalTests/tickets/tests/Ticket274TestCase.php
@@ -16,8 +16,8 @@ class Ticket274TestCase extends SeleniumTestCase
$this->type($base.'MyDate', 'asd');
$this->clickAndWait($base.'button1');
- $this->assertVisible($base.'validator1');
- $this->assertNotVisible($base.'validator2');
+ $this->assertNotVisible($base.'validator1');
+ $this->assertVisible($base.'validator2');
}
}