From 9af7e1312620de671c4312fbfd723b59ee4685df Mon Sep 17 00:00:00 2001 From: xue <> Date: Wed, 21 Jun 2006 13:42:04 +0000 Subject: Merge from 3.0 branch till 1191. --- framework/Web/UI/WebControls/TBaseDataList.php | 9 --- framework/Web/UI/WebControls/TButton.php | 84 +++++++++++++++--------- framework/Web/UI/WebControls/TDataGrid.php | 88 +++++++++++++++++++++++--- framework/Web/UI/WebControls/TDataList.php | 40 ++++++++++-- framework/Web/UI/WebControls/THyperLink.php | 2 +- framework/Web/UI/WebControls/TRepeater.php | 34 +++++----- 6 files changed, 184 insertions(+), 73 deletions(-) (limited to 'framework/Web') diff --git a/framework/Web/UI/WebControls/TBaseDataList.php b/framework/Web/UI/WebControls/TBaseDataList.php index 479fb2ef..a8ab8faf 100644 --- a/framework/Web/UI/WebControls/TBaseDataList.php +++ b/framework/Web/UI/WebControls/TBaseDataList.php @@ -43,15 +43,6 @@ Prado::using('System.Util.TDataFieldAccessor'); */ abstract class TBaseDataList extends TDataBoundControl { - /** - * 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 - */ - public function addParsedObject($object) - { - } - /** * Creates a style object for the control. * This method creates a {@link TTableStyle} to be used by the data list control. diff --git a/framework/Web/UI/WebControls/TButton.php b/framework/Web/UI/WebControls/TButton.php index b77ca111..f1132625 100644 --- a/framework/Web/UI/WebControls/TButton.php +++ b/framework/Web/UI/WebControls/TButton.php @@ -13,37 +13,35 @@ /** * TButton class * - * TButton creates a click button on the page. It is used to submit data to a page. - * You can create either a submit button or a command button. + * TButton creates a click button on the page. It is mainly used to submit data to a page. * - * A command button has a command name (specified by - * the {@link setCommandName CommandName} property) and and a command parameter - * (specified by {@link setCommandParameter CommandParameter} property) - * associated with the button. This allows you to create multiple TButton + * TButton raises two server-side events, {@link onClick OnClick} and {@link onCommand OnCommand}, + * when it is clicked on the client-side. The difference between these two events + * is that the event {@link onCommand OnCommand} is bubbled up to the button's ancestor controls. + * And within the event parameter for {@link onCommand OnCommand} contains the reference + * to the {@link setCommandName CommandName} and {@link setCommandParameter CommandParameter} + * property values that are set for the button object. This allows you to create multiple TButton * components on a Web page and programmatically determine which one is clicked - * with what parameter. You can provide an event handler for - * {@link onCommand OnCommand} event to programmatically control the actions performed - * when the command button is clicked. In the event handler, you can determine - * the {@link setCommandName CommandName} property value and - * the {@link setCommandParameter CommandParameter} property value - * through the {@link TCommandParameter::getName Name} and - * {@link TCommandParameter::getParameter Parameter} properties of the event - * parameter which is of type {@link TCommandEventParameter}. + * with what parameter. * - * A submit button does not have a command name associated with the button - * and clicking on it simply posts the Web page back to the server. - * By default, a TButton component is a submit button. - * You can provide an event handler for the {@link onClick OnClick} event - * to programmatically control the actions performed when the submit button is clicked. - * - * Clicking on button can trigger form validation, if + * Clicking on button can also trigger form validation, if * {@link setCausesValidation CausesValidation} is true. - * And the validation may be restricted within a certain group of validator + * The validation may be restricted within a certain group of validator * controls by setting {@link setValidationGroup ValidationGroup} property. * If validation is successful, the data will be post back to the same page. * * TButton displays the {@link setText Text} property as the button caption. * + * TButton can be one of three {@link setButtonType ButtonType}: Submit, Button and Reset. + * By default, it is a Submit button and the form submission uses the browser's + * default submission capability. If it is Button or Reset, postback may occur + * if one of the following conditions is met: + * - an event handler is attached to {@link onClick OnClick} event; + * - an event handler is attached to {@link onCommand OnCommand} event; + * - the button is in a non-empty validation group. + * In addition, clicking on a Reset button will clear up all input fields + * if the button does not cause a postback. + * * @author Qiang Xue * @version $Revision: $ $Date: $ * @package System.Web.UI.WebControls @@ -68,12 +66,15 @@ class TButton extends TWebControl implements IPostBackEventHandler, IButtonContr { $page=$this->getPage(); $page->ensureRenderInForm($this); - $writer->addAttribute('type','submit'); + $writer->addAttribute('type',strtolower($this->getButtonType())); if(($uniqueID=$this->getUniqueID())!=='') $writer->addAttribute('name',$uniqueID); $writer->addAttribute('value',$this->getText()); - if($this->getEnabled(true) ) - $this->renderClientControlScript($writer); + if($this->getEnabled(true)) + { + if($this->needPostBackScript()) + $this->renderClientControlScript($writer); + } else if($this->getEnabled()) // in this case, parent will not render 'disabled' $writer->addAttribute('disabled','disabled'); @@ -85,12 +86,8 @@ class TButton extends TWebControl implements IPostBackEventHandler, IButtonContr */ protected function renderClientControlScript($writer) { - if($this->canCauseValidation()) - { - $writer->addAttribute('id',$this->getClientID()); - $cs = $this->getPage()->getClientScript(); - $cs->registerPostBackControl($this->getClientClassName(),$this->getPostBackOptions()); - } + $writer->addAttribute('id',$this->getClientID()); + $this->getPage()->getClientScript()->registerPostBackControl($this->getClientClassName(),$this->getPostBackOptions()); } /** @@ -117,6 +114,15 @@ class TButton extends TWebControl implements IPostBackEventHandler, IButtonContr return false; } + /** + * @return boolean whether the button needs javascript to do postback + */ + protected function needPostBackScript() + { + return $this->canCauseValidation() || ($this->getButtonType()!=='Submit' && + ($this->hasEventHandler('OnClick') || $this->hasEventHandler('OnCommand'))); + } + /** * Returns postback specifications for the button. * This method is used by framework and control developers. @@ -262,6 +268,22 @@ class TButton extends TWebControl implements IPostBackEventHandler, IButtonContr { $this->setViewState('ValidationGroup',$value,''); } + + /** + * @return string the type of the button. Defaults to 'Submit'. + */ + public function getButtonType() + { + return $this->getViewState('ButtonType','Submit'); + } + + /** + * @param string the type of the button. Valid values include 'Submit', 'Reset', 'Button'. + */ + public function setButtonType($value) + { + $this->setViewState('ButtonType',TPropertyValue::ensureEnum($value,'Submit','Reset','Button'),'Submit'); + } } ?> diff --git a/framework/Web/UI/WebControls/TDataGrid.php b/framework/Web/UI/WebControls/TDataGrid.php index 69798c1a..dae2d2cd 100644 --- a/framework/Web/UI/WebControls/TDataGrid.php +++ b/framework/Web/UI/WebControls/TDataGrid.php @@ -186,6 +186,14 @@ class TDataGrid extends TBaseDataList implements INamingContainer private $_pagedDataSource=null; private $_topPager=null; private $_bottomPager=null; + /** + * @var ITemplate template used when empty data is bounded + */ + private $_emptyTemplate=null; + /** + * @var boolean whether empty template is effective + */ + private $_useEmptyTemplate=false; /** * @return string tag name (table) of the datagrid @@ -197,13 +205,15 @@ class TDataGrid extends TBaseDataList implements INamingContainer /** * Adds objects parsed in template to datagrid. - * Only datagrid columns are added into {@link getColumns Columns} collection. + * Datagrid columns are added into {@link getColumns Columns} collection. * @param mixed object parsed in template */ public function addParsedObject($object) { if($object instanceof TDataGridColumn) $this->getColumns()->add($object); + else + parent::addParsedObject($object); } /** @@ -682,6 +692,26 @@ class TDataGrid extends TBaseDataList implements INamingContainer $this->setViewState('ShowFooter',TPropertyValue::ensureBoolean($value),false); } + /** + * @return ITemplate the template applied when no data is bound to the datagrid + */ + public function getEmptyTemplate() + { + return $this->_emptyTemplate; + } + + /** + * @param ITemplate the template applied when no data is bound to the datagrid + * @throws TInvalidDataTypeException if the input is not an {@link ITemplate} or not null. + */ + public function setEmptyTemplate($value) + { + if($value instanceof ITemplate || $value===null) + $this->_emptyTemplate=$value; + else + throw new TInvalidDataTypeException('datagrid_template_required','EmptyTemplate'); + } + /** * This method overrides parent's implementation to handle * {@link onItemCommand OnItemCommand} event which is bubbled from @@ -953,6 +983,7 @@ class TDataGrid extends TBaseDataList implements INamingContainer $this->_footer=null; $this->_topPager=null; $this->_bottomPager=null; + $this->_useEmptyTemplate=false; } /** @@ -968,6 +999,17 @@ class TDataGrid extends TBaseDataList implements INamingContainer $ds->setDataSource(new TDummyDataSource($itemCount)); else $ds->setDataSource(new TDummyDataSource($this->getViewState('DataSourceCount',0))); + + if($ds->getCount()===0 && $ds->getCurrentPageIndex()===0 && $this->_emptyTemplate!==null) + { + $this->_emptyTemplate->instantiateIn($this); + $this->_useEmptyTemplate=true; + $this->clearViewState('ItemCount'); + $this->clearViewState('PageCount'); + $this->clearViewState('DataSourceCount'); + return; + } + $columns=new TList($this->getColumns()); $columns->mergeWith($this->_autoColumns); @@ -1020,9 +1062,21 @@ class TDataGrid extends TBaseDataList implements INamingContainer $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'); + + if($ds->getCount()===0 && $ds->getCurrentPageIndex()===0 && $this->_emptyTemplate!==null) + { + $this->_emptyTemplate->instantiateIn($this); + $this->_useEmptyTemplate=true; + $this->clearViewState('ItemCount'); + $this->clearViewState('PageCount'); + $this->clearViewState('DataSourceCount'); + return; + } + // get all columns if($this->getAutoGenerateColumns()) { @@ -1046,7 +1100,7 @@ class TDataGrid extends TBaseDataList implements INamingContainer $selectedIndex=$this->getSelectedItemIndex(); $editIndex=$this->getEditItemIndex(); $index=0; - $dsIndex=$ds->getAllowPaging()?$ds->getFirstIndexInPage():0; + $dsIndex=$allowPaging?$ds->getFirstIndexInPage():0; foreach($ds as $key=>$data) { if($keyField!=='') @@ -1502,17 +1556,31 @@ class TDataGrid extends TBaseDataList implements INamingContainer { if($this->getHasControls()) { - $this->applyItemStyles(); - if($this->_topPager) + if($this->_useEmptyTemplate) { - $this->_topPager->renderControl($writer); - $writer->writeLine(); + $control=new TWebControl; + $control->setID($this->getClientID()); + $control->copyBaseAttributes($this); + if($this->getHasStyle()) + $control->getStyle()->copyFrom($this->getStyle()); + $control->renderBeginTag($writer); + $this->renderContents($writer); + $control->renderEndTag($writer); } - $this->renderTable($writer); - if($this->_bottomPager) + else { - $writer->writeLine(); - $this->_bottomPager->renderControl($writer); + $this->applyItemStyles(); + if($this->_topPager) + { + $this->_topPager->renderControl($writer); + $writer->writeLine(); + } + $this->renderTable($writer); + if($this->_bottomPager) + { + $writer->writeLine(); + $this->_bottomPager->renderControl($writer); + } } } } diff --git a/framework/Web/UI/WebControls/TDataList.php b/framework/Web/UI/WebControls/TDataList.php index b2bd9229..0dac2be2 100644 --- a/framework/Web/UI/WebControls/TDataList.php +++ b/framework/Web/UI/WebControls/TDataList.php @@ -115,6 +115,7 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs * @var Itemplate various item templates */ private $_itemTemplate=null; + private $_emptyTemplate=null; private $_alternatingItemTemplate=null; private $_selectedItemTemplate=null; private $_editItemTemplate=null; @@ -362,6 +363,26 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs return $this->_footer; } + /** + * @return ITemplate the template applied when no data is bound to the datalist + */ + public function getEmptyTemplate() + { + return $this->_emptyTemplate; + } + + /** + * @param ITemplate the template applied when no data is bound to the datalist + * @throws TInvalidDataTypeException if the input is not an {@link ITemplate} or not null. + */ + public function setEmptyTemplate($value) + { + if($value instanceof ITemplate || $value===null) + $this->_emptyTemplate=$value; + else + throw new TInvalidDataTypeException('datalist_template_required','EmptyTemplate'); + } + /** * @return ITemplate the separator template */ @@ -1109,6 +1130,8 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs if($this->_footerTemplate!==null) $this->_footer=$this->createItemInternal(-1,'Footer',false,null); } + else if($this->_emptyTemplate!==null) + $this->_emptyTemplate->instantiateIn($this); $this->clearChildState(); } @@ -1150,6 +1173,8 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs } if($itemIndex>0 && $this->_footerTemplate!==null) $this->_footer=$this->createItemInternal(-1,'Footer',true,null); + if($itemIndex===0 && $this->_emptyTemplate!==null) + $this->_emptyTemplate->instantiateIn($this); $this->setViewState('ItemCount',$itemIndex,0); } @@ -1162,9 +1187,14 @@ class TDataList extends TBaseDataList implements INamingContainer, IRepeatInfoUs { if($this->getHasControls()) { - $this->applyItemStyles(); - $repeatInfo=$this->getRepeatInfo(); - $repeatInfo->renderRepeater($writer,$this); + if($this->getItemCount()>0) + { + $this->applyItemStyles(); + $repeatInfo=$this->getRepeatInfo(); + $repeatInfo->renderRepeater($writer,$this); + } + else if($this->_emptyTemplate!==null) + parent::render($writer); } } } @@ -1317,7 +1347,7 @@ class TDataListItem extends TWebControl implements INamingContainer } /** - * @return string item type, can be 'Header','Footer','Item','AlternatingItem','SelectedItem','EditItem','Separator','Pager' + * @return string item type */ public function getItemType() { @@ -1325,7 +1355,7 @@ class TDataListItem extends TWebControl implements INamingContainer } /** - * @param mixed data to be associated with the item + * @param string item type. Valid values include 'Header','Footer','Item','AlternatingItem','SelectedItem','EditItem','Separator','Pager'. */ public function setItemType($value) { diff --git a/framework/Web/UI/WebControls/THyperLink.php b/framework/Web/UI/WebControls/THyperLink.php index 5489727c..011ce4db 100644 --- a/framework/Web/UI/WebControls/THyperLink.php +++ b/framework/Web/UI/WebControls/THyperLink.php @@ -73,7 +73,7 @@ class THyperLink extends TWebControl if(($toolTip=$this->getToolTip())!=='') $image->setToolTip($toolTip); if(($text=$this->getText())!=='') - $image->setAlternateText(THttpUtility::htmlEncode($text)); + $image->setAlternateText($text); $image->renderControl($writer); } } diff --git a/framework/Web/UI/WebControls/TRepeater.php b/framework/Web/UI/WebControls/TRepeater.php index 9c1cc4ac..a2fc01d7 100644 --- a/framework/Web/UI/WebControls/TRepeater.php +++ b/framework/Web/UI/WebControls/TRepeater.php @@ -62,7 +62,6 @@ class TRepeater extends TDataBoundControl implements INamingContainer */ const IT_HEADER='Header'; const IT_FOOTER='Footer'; - const IT_EMPTY='Empty'; const IT_ITEM='Item'; const IT_SEPARATOR='Separator'; const IT_ALTERNATINGITEM='AlternatingItem'; @@ -104,15 +103,6 @@ class TRepeater extends TDataBoundControl implements INamingContainer */ private $_footer=null; - /** - * No body content should be added to repeater. - * This method is invoked when body content is parsed and added to this control. - * @param mixed body content to be added - */ - public function addParsedObject($object) - { - } - /** * @return ITemplate the template for repeater items */ @@ -343,7 +333,6 @@ class TRepeater extends TDataBoundControl implements INamingContainer { case self::IT_HEADER: $template=$this->_headerTemplate; break; case self::IT_FOOTER: $template=$this->_footerTemplate; break; - case self::IT_EMPTY : $template=$this->_emptyTemplate; break; case self::IT_ITEM : $template=$this->_itemTemplate; break; case self::IT_SEPARATOR : $template=$this->_separatorTemplate; break; case self::IT_ALTERNATINGITEM : $template=$this->_alternatingItemTemplate===null ? $this->_itemTemplate : $this->_alternatingItemTemplate; break; @@ -360,7 +349,10 @@ class TRepeater extends TDataBoundControl implements INamingContainer */ public function render($writer) { - $this->renderContents($writer); + if($this->_items && $this->_items->getCount()) + $this->renderContents($writer); + else if($this->_emptyTemplate!==null) + parent::render($writer); } /** @@ -422,7 +414,7 @@ class TRepeater extends TDataBoundControl implements INamingContainer $this->_footer=$this->createItemInternal(-1,self::IT_FOOTER,false,null); } else if($this->_emptyTemplate!==null) - $this->createItemInternal(-1,self::IT_EMPTY,false,null); + $this->_emptyTemplate->instantiateIn($this); $this->clearChildState(); } @@ -460,7 +452,7 @@ class TRepeater extends TDataBoundControl implements INamingContainer if($itemIndex>0 && $this->_footerTemplate!==null) $this->_footer=$this->createItemInternal(-1,self::IT_FOOTER,true,null); if($itemIndex===0 && $this->_emptyTemplate!==null) - $this->createItemInternal(-1,self::IT_EMPTY,true,null); + $this->_emptyTemplate->instantiateIn($this); $this->setViewState('ItemCount',$itemIndex,0); } @@ -677,22 +669,30 @@ class TRepeaterItem extends TControl implements INamingContainer /** * Constructor. * @param integer zero-based index of the item in the item collection of repeater - * @param string item type, can be 'Header','Footer','Empty','Item','AlternatingItem','SelectedItem','EditItem','Separator','Pager'. + * @param string item type, can be 'Header','Footer','Item','AlternatingItem','SelectedItem','EditItem','Separator','Pager'. */ public function __construct($itemIndex,$itemType) { $this->_itemIndex=$itemIndex; - $this->_itemType=$itemType; + $this->setItemType($itemType); } /** - * @return string item type, can be 'Header','Footer','Empty','Item','AlternatingItem','SelectedItem','EditItem','Separator','Pager' + * @return string item type */ public function getItemType() { return $this->_itemType; } + /** + * @param string item type. Valid values include 'Header','Footer','Item','AlternatingItem','SelectedItem','EditItem','Separator','Pager'. + */ + public function setItemType($value) + { + $this->_itemType=TPropertyValue::ensureEnum($value,'Header','Footer','Item','AlternatingItem','SelectedItem','EditItem','Separator','Pager'); + } + /** * @return integer zero-based index of the item in the item collection of repeater */ -- cgit v1.2.3