summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxue <>2005-12-04 04:25:45 +0000
committerxue <>2005-12-04 04:25:45 +0000
commit0dda82c2a13ed09a2520dda9b420e8f90703c67b (patch)
tree27815328ce64437ff5e34cb163557d365b316abc
parent3ea63072225a473239227facfabde294bb58ed1d (diff)
-rw-r--r--demos/controls/protected/pages/HomePage.php1
-rw-r--r--demos/controls/protected/pages/HomePage.tpl2
-rw-r--r--framework/Web/UI/TClientScriptManager.php155
-rw-r--r--framework/Web/UI/TControl.php2
-rw-r--r--framework/Web/UI/THiddenFieldPageStatePersister.php4
-rw-r--r--framework/Web/UI/TPage.php505
-rw-r--r--framework/Web/UI/TTemplateControl.php2
-rw-r--r--framework/Web/UI/WebControls/TCheckBox.php40
-rw-r--r--framework/Web/UI/WebControls/TImageButton.php2
-rw-r--r--framework/Web/UI/WebControls/TTextBox.php5
10 files changed, 397 insertions, 321 deletions
diff --git a/demos/controls/protected/pages/HomePage.php b/demos/controls/protected/pages/HomePage.php
index 7339f364..334c826c 100644
--- a/demos/controls/protected/pages/HomePage.php
+++ b/demos/controls/protected/pages/HomePage.php
@@ -15,6 +15,7 @@ class HomePage extends TPage
$sender->BackColor='blue';
else
$sender->BackColor='';
+ $this->TextBox->focus();
}
}
diff --git a/demos/controls/protected/pages/HomePage.tpl b/demos/controls/protected/pages/HomePage.tpl
index eaa9179b..f3860d5b 100644
--- a/demos/controls/protected/pages/HomePage.tpl
+++ b/demos/controls/protected/pages/HomePage.tpl
@@ -4,7 +4,7 @@
<com:THiddenField Value="test" />
<h1>Welcome! <%=$this->User->Name %></h1>
<com:TLiteral Text="<literal>" Encode="true"/>
-<com:TTextBox Text="textbox" />
+<com:TTextBox ID="TextBox" Text="textbox" />
<com:TLabel Text="test" AssociatedControlID="checkbox"/><br/>
<com:System.Web.UI.WebControls.TButton text="Toggle Button" ForeColor="red" Font.size="18" Click="testClick" /> (requires membership)<br/>
<com:TCheckBox Text="Checkbox" ID="checkbox"/><br/>
diff --git a/framework/Web/UI/TClientScriptManager.php b/framework/Web/UI/TClientScriptManager.php
index d4aea650..0e3ad773 100644
--- a/framework/Web/UI/TClientScriptManager.php
+++ b/framework/Web/UI/TClientScriptManager.php
@@ -36,18 +36,18 @@ class TClientScriptManager extends TComponent
const SCRIPT_DIR='Web/Javascripts/js';
const POSTBACK_FUNC='Prado.PostBack.perform';
const POSTBACK_OPTIONS='Prado.PostBack.Options';
- const FIELD_POSTBACK_TARGET='PRADO_POSTBACK_TARGET';
- const FIELD_POSTBACK_PARAMETER='PRADO_POSTBACK_PARAMETER';
- const FIELD_LASTFOCUS='PRADO_LASTFOCUS';
- const FIELD_PAGE_STATE='PRADO_PAGE_STATE';
private $_owner;
private $_hiddenFields=array();
- private $_scriptBlocks=array();
- private $_startupScripts=array();
+ private $_beginScripts=array();
+ private $_endScripts=array();
private $_scriptIncludes=array();
private $_onSubmitStatements=array();
private $_arrayDeclares=array();
private $_expandoAttributes=array();
+ private $_postBackScriptRegistered=false;
+ private $_focusScriptRegistered=false;
+ private $_scrollScriptRegistered=false;
+ private $_publishedScriptFiles=array();
public function __construct(TPage $owner)
{
@@ -113,26 +113,47 @@ class TClientScriptManager extends TComponent
protected function registerPostBackScript()
{
- $this->registerHiddenField(self::FIELD_POSTBACK_TARGET,'');
- $this->registerHiddenField(self::FIELD_POSTBACK_PARAMETER,'');
- $am=$this->_owner->getService()->getAssetManager();
- $url=$am->publishFilePath(Prado::getFrameworkPath().'/'.self::SCRIPT_DIR.'/base.js');
- $this->registerScriptInclude('prado:base',$url);
+ if(!$this->_postBackScriptRegistered)
+ {
+ $this->_postBackScriptRegistered=true;
+ $this->registerHiddenField(TPage::FIELD_POSTBACK_TARGET,'');
+ $this->registerHiddenField(TPage::FIELD_POSTBACK_PARAMETER,'');
+ $this->registerScriptInclude('prado:base',$this->publishScriptFile('base.js'));
+ }
}
- public function registerFocusScript()
+ private function publishScriptFile($jsFile)
{
- // need Focus.js
+ if(!isset($this->_publishedScriptFiles[$jsFile]))
+ {
+ $am=$this->_owner->getService()->getAssetManager();
+ $this->_publishedScriptFiles[$jsFile]=$am->publishFilePath(Prado::getFrameworkPath().'/'.self::SCRIPT_DIR.'/'.$jsFile);
+ }
+ return $this->_publishedScriptFiles[$jsFile];
}
- public function registerScrollScript()
+ public function registerFocusScript($target)
{
- $this->registerHiddenField(self::FIELD_SCROLL_X,$this->_owner->getScrollPositionX());
- $this->registerHiddenField(self::FIELD_SCROLL_Y,$this->_owner->getScrollPositionY());
- /*
- this.ClientScript.RegisterStartupScript(typeof(Page), "PageScrollPositionScript", "\r\ntheForm.oldSubmit = theForm.submit;\r\ntheForm.submit = WebForm_SaveScrollPositionSubmit;\r\n\r\ntheForm.oldOnSubmit = theForm.onsubmit;\r\ntheForm.onsubmit = WebForm_SaveScrollPositionOnSubmit;\r\n" + (this.IsPostBack ? "\r\ntheForm.oldOnLoad = window.onload;\r\nwindow.onload = WebForm_RestoreScrollPosition;\r\n" : string.Empty), true);
- need base.js
- */
+ if(!$this->_focusScriptRegistered)
+ {
+ $this->_focusScriptRegistered=true;
+ $this->registerScriptInclude('prado:base',$this->publishScriptFile('base.js'));
+ $this->registerEndScript('prado:focus','Prado.Focus.setFocus("'.THttpUtility::quoteJavaScriptString($target).'");');
+ }
+ }
+
+ public function registerScrollScript($x,$y)
+ {
+ if(!$this->_scrollScriptRegistered)
+ {
+ $this->_scrollScriptRegistered=true;
+ $this->registerHiddenField(TPage::FIELD_SCROLL_X,$this->_owner->getScrollPositionX());
+ $this->registerHiddenField(TPage::FIELD_SCROLL_Y,$this->_owner->getScrollPositionY());
+ /*
+ this.ClientScript.RegisterStartupScript(typeof(Page), "PageScrollPositionScript", "\r\ntheForm.oldSubmit = theForm.submit;\r\ntheForm.submit = WebForm_SaveScrollPositionSubmit;\r\n\r\ntheForm.oldOnSubmit = theForm.onsubmit;\r\ntheForm.onsubmit = WebForm_SaveScrollPositionOnSubmit;\r\n" + (this.IsPostBack ? "\r\ntheForm.oldOnLoad = window.onload;\r\nwindow.onload = WebForm_RestoreScrollPosition;\r\n" : string.Empty), true);
+ need base.js
+ */
+ }
}
public function registerValidationScript()
@@ -154,9 +175,14 @@ class TClientScriptManager extends TComponent
return isset($this->_scriptIncludes[$key]);
}
- public function isStartupScriptRegistered($key)
+ public function isBeginScriptRegistered($key)
{
- return isset($this->_startupScripts[$key]);
+ return isset($this->_beginScripts[$key]);
+ }
+
+ public function isEndScriptRegistered($key)
+ {
+ return isset($this->_endScripts[$key]);
}
public function isOnSubmitStatementRegistered($key)
@@ -169,11 +195,6 @@ class TClientScriptManager extends TComponent
$this->_arrayDeclares[$name][]=$value;
}
- public function registerScriptBlock($key,$script)
- {
- $this->_scriptBlocks[$key]=$script;
- }
-
public function registerScriptInclude($key,$url)
{
$this->_scriptIncludes[$key]=$url;
@@ -189,9 +210,14 @@ class TClientScriptManager extends TComponent
$this->_onSubmitStatements[$key]=$script;
}
- public function registerStartupScript($key,$script)
+ public function registerBeginScript($key,$script)
{
- $this->_startupScripts[$key]=$script;
+ $this->_beginScripts[$key]=$script;
+ }
+
+ public function registerEndScript($key,$script)
+ {
+ $this->_endScripts[$key]=$script;
}
public function registerExpandoAttribute($controlID,$name,$value)
@@ -203,57 +229,35 @@ class TClientScriptManager extends TComponent
{
if(count($this->_arrayDeclares))
{
- $str="\n<script type=\"text/javascript\">\n<!--\n";
+ $str="<script type=\"text/javascript\"><!--\n";
foreach($this->_arrayDeclares as $name=>$array)
- {
- $str.="var $name=new Array(";
- $flag=true;
- foreach($array as $value)
- {
- if($flag)
- {
- $flag=false;
- $str.=$value;
- }
- else
- $str.=','.$value;
- }
- $str.=");\n";
- }
- $str.="// -->\n</script>\n";
+ $str.="var $name=new Array(".implode(',',$array).");\n";
+ $str.="\n// --></script>\n";
$writer->write($str);
}
}
- public function renderScriptBlocks($writer)
+ public function renderScriptIncludes($writer)
{
- $str='';
- foreach($this->_scriptBlocks as $script)
- $str.="\n".$script;
- if($this->_owner->getClientOnSubmitEvent()!=='' && $this->_owner->getClientSupportsJavaScript())
- {
- $str.="\nfunction WebForm_OnSubmit() {\n";
- foreach($this->_onSubmitStatements as $script)
- $str.=$script;
- $str.="\nreturn true;\n}";
- }
- if($str!=='')
- $writer->write("\n<script type=\"text/javascript\">\n<!--\n".$str."// -->\n</script>\n");
+ foreach($this->_scriptIncludes as $include)
+ $writer->write("<script type=\"text/javascript\" src=\"".THttpUtility::htmlEncode($include)."\"></script>\n");
}
- public function renderStartupScripts($writer)
+ public function renderOnSubmitStatements($writer)
{
- $str='';
- foreach($this->_scriptIncludes as $include)
- $str.="\n<script type=\"text/javascript\" src=\"".THttpUtility::htmlEncode($include)."\"></script>";
- if(count($this->_startupScripts))
- {
- $str.="\n<script type=\"text/javascript\">\n<!--\n";
- foreach($this->_startupScripts as $script)
- $str.=$script;
- $str.="// -->\n</script>\n";
- $writer->write($str);
- }
+ // ???
+ }
+
+ public function renderBeginScripts($writer)
+ {
+ if(count($this->_beginScripts))
+ $writer->write("<script type=\"text/javascript\"><!--\n".implode("\n",$this->_beginScripts)."\n// --></script>\n");
+ }
+
+ public function renderEndScripts($writer)
+ {
+ if(count($this->_endScripts))
+ $writer->write("<script type=\"text/javascript\"><!--\n".implode("\n",$this->_endScripts)."\n// --></script>\n");
}
public function renderHiddenFields($writer)
@@ -262,18 +266,17 @@ class TClientScriptManager extends TComponent
foreach($this->_hiddenFields as $name=>$value)
{
$value=THttpUtility::htmlEncode($value);
- $str.="\n<input type=\"hidden\" name=\"$name\" id=\"$name\" value=\"$value\" />";
+ $str.="<input type=\"hidden\" name=\"$name\" id=\"$name\" value=\"$value\" />\n";
}
if($str!=='')
$writer->write($str);
- $this->_hiddenFields=array();
}
- public function renderExpandoAttribute($writer)
+ public function renderExpandoAttributes($writer)
{
if(count($this->_expandoAttributes))
{
- $str="\n<script type=\"text/javascript\">\n<!--\n";
+ $str="<script type=\"text/javascript\"><!--\n";
foreach($this->_expandoAttributes as $controlID=>$attrs)
{
$str.="var $controlID = document.all ? document.all[\"$controlID\"] : document.getElementById(\"$controlID\");\n";
@@ -285,7 +288,7 @@ class TClientScriptManager extends TComponent
$str.="{$key}[\"$name\"]=\"$value\";\n";
}
}
- $str.="// -->\n</script>\n";
+ $str.="\n// --></script>\n";
$writer->write($str);
}
}
diff --git a/framework/Web/UI/TControl.php b/framework/Web/UI/TControl.php
index 0e601386..e568df65 100644
--- a/framework/Web/UI/TControl.php
+++ b/framework/Web/UI/TControl.php
@@ -960,7 +960,7 @@ class TControl extends TComponent
* Only framework developers should use this method.
* @param TControl the naming container control
*/
- protected function initRecursive($namingContainer)
+ protected function initRecursive($namingContainer=null)
{
$this->ensureChildControls();
if($this->getHasControls())
diff --git a/framework/Web/UI/THiddenFieldPageStatePersister.php b/framework/Web/UI/THiddenFieldPageStatePersister.php
index 5525b50a..d4041983 100644
--- a/framework/Web/UI/THiddenFieldPageStatePersister.php
+++ b/framework/Web/UI/THiddenFieldPageStatePersister.php
@@ -41,12 +41,12 @@ class THiddenFieldPageStatePersister extends TComponent implements IPageStatePer
$data=gzcompress($hmac.$data);
else
$data=$hmac.$data;
- $this->_application->getService()->getRequestedPage()->getClientScript()->registerHiddenField(TClientScriptManager::FIELD_PAGE_STATE,base64_encode($data));
+ $this->_application->getService()->getRequestedPage()->getClientScript()->registerHiddenField(TPage::FIELD_PAGESTATE,base64_encode($data));
}
public function load()
{
- $str=base64_decode($this->_application->getRequest()->getItems()->itemAt(TClientScriptManager::FIELD_PAGE_STATE));
+ $str=base64_decode($this->_application->getRequest()->getItems()->itemAt(TPage::FIELD_PAGESTATE));
if($str==='')
return null;
if(extension_loaded('zlib'))
diff --git a/framework/Web/UI/TPage.php b/framework/Web/UI/TPage.php
index 4c04f597..42f495cf 100644
--- a/framework/Web/UI/TPage.php
+++ b/framework/Web/UI/TPage.php
@@ -5,6 +5,24 @@ Prado::using('System.Web.UI.WebControls.*');
class TPage extends TTemplateControl
{
+ const FIELD_POSTBACK_TARGET='PRADO_POSTBACK_TARGET';
+ const FIELD_POSTBACK_PARAMETER='PRADO_POSTBACK_PARAMETER';
+ const FIELD_LASTFOCUS='PRADO_LASTFOCUS';
+ const FIELD_PAGESTATE='PRADO_PAGESTATE';
+ const FIELD_SCROLLX='PRADO_SCROLLX';
+ const FIELD_SCROLLY='PRADO_SCROLLY';
+ /**
+ * @var array system post fields
+ */
+ private static $_systemPostFields=array(
+ self::FIELD_POSTBACK_TARGET=>true,
+ self::FIELD_POSTBACK_PARAMETER=>true,
+ self::FIELD_LASTFOCUS=>true,
+ self::FIELD_PAGESTATE=>true,
+ self::FIELD_SCROLLX=>true,
+ self::FIELD_SCROLLY=>true,
+ '__PREVPAGE','__CALLBACKID','__CALLBACKPARAM'
+ );
/**
* @var TApplication application instance
*/
@@ -49,27 +67,47 @@ class TPage extends TTemplateControl
* @var TMap postback data that is not handled during first invocation of LoadPostData.
*/
private $_restPostData;
+ /**
+ * @var array list of controls whose data have been changed due to the postback
+ */
+ private $_controlsPostDataChanged=array();
+ /**
+ * @var array list of controls that need to load post data in the current request
+ */
+ private $_controlsRequiringPostBack=array();
+ /**
+ * @var array list of controls that need to load post data in the next postback
+ */
+ private $_controlsRegisteredForPostBack=array();
+ /**
+ * @var TControl control that needs to raise postback event
+ */
+ private $_postBackEventTarget=null;
+ /**
+ * @var mixed postback event parameter
+ */
+ private $_postBackEventParameter=null;
+ /**
+ * @var boolean whether form has rendered
+ */
+ private $_formRendered=false;
+ /**
+ * @var boolean whether the current rendering is within a form
+ */
+ private $_inFormRender=false;
+ /**
+ * @var TControl the control to be focused when the page is sent back to user
+ */
+ private $_focusedControl=null;
+ /**
+ * @var boolean whether or not to maintain page scroll position
+ */
+ private $_maintainScrollPosition=false;
private $_maxPageStateFieldLength=10;
private $_enableViewStateMac=true;
- private $_performPreRendering=true;
- private $_performRendering=true;
-
- private $_formRendered=false;
- private $_inFormRender=false;
- private $_requirePostBackScript=false;
- private $_postBackScriptRendered=false;
private $_isCrossPagePostBack=false;
private $_previousPagePath='';
- private $_preInitWorkComplete=false;
- private $_changedPostDataConsumers=array();
- private $_controlsRequiringPostBack=array();
- private $_registeredControlThatRequireRaiseEvent=null;
- private $_registeredControlsThatRequirePostBack=null;
- private $_autoPostBackControl=null;
- private $_webFormsScriptRendered=false;
- private $_requireWebFormsScript=false;
- private static $_systemPostFields=array('__EVENTTARGET','__EVENTPARAM','__STATE','__PREVPAGE','__CALLBACKID','__CALLBACKPARAM','__LASTFOCUS');
/**
* Constructor.
@@ -90,6 +128,48 @@ class TPage extends TTemplateControl
}
/**
+ * Runs through the page lifecycles.
+ * This method runs through the page lifecycles.
+ * @param THtmlTextWriter the HTML writer
+ */
+ public function run($writer)
+ {
+ $this->determinePostBackMode();
+
+ $this->onPreInit(null);
+ $this->initRecursive();
+ $this->onInitComplete(null);
+
+ if($this->getIsPostBack())
+ {
+ $this->_restPostData=new TMap;
+ $this->loadPageState();
+ $this->processPostData($this->_postData,true);
+ $this->onPreLoad(null);
+ $this->loadRecursive();
+ $this->processPostData($this->_restPostData,false);
+ $this->raiseChangedEvents();
+ $this->raisePostBackEvent();
+ $this->onLoadComplete(null);
+ }
+ else
+ {
+ $this->onPreLoad(null);
+ $this->loadRecursive();
+ $this->onLoadComplete(null);
+ }
+
+ $this->preRenderRecursive();
+ $this->onPreRenderComplete(null);
+
+ $this->savePageState();
+ $this->onSaveStateComplete(null);
+
+ $this->renderControl($writer);
+ $this->unloadRecursive();
+ }
+
+ /**
* Loads and parses the page template.
* This method overrides the parent implementation by allowing loading
* a page template from a specified template file.
@@ -378,7 +458,7 @@ class TPage extends TTemplateControl
private function determinePostBackMode()
{
$postData=$this->_application->getRequest()->getItems();
- if($postData->contains(TClientScriptManager::FIELD_PAGE_STATE) || $postData->contains(TClientScriptManager::FIELD_POSTBACK_TARGET))
+ if($postData->contains(self::FIELD_PAGESTATE) || $postData->contains(self::FIELD_POSTBACK_TARGET))
$this->_postData=$postData;
}
@@ -399,6 +479,30 @@ class TPage extends TTemplateControl
}
/**
+ * This method is invoked when control state is to be saved.
+ * You can override this method to do last step state saving.
+ * Parent implementation must be invoked.
+ * @param TEventParameter event parameter
+ */
+ protected function onSaveState($param)
+ {
+ parent::onSaveState($param);
+ $this->setViewState('ControlsRequiringPostBack',$this->_controlsRegisteredForPostBack,array());
+ }
+
+ /**
+ * This method is invoked right after the control has loaded its state.
+ * You can override this method to initialize data from the control state.
+ * Parent implementation must be invoked.
+ * @param TEventParameter
+ */
+ protected function onLoadState($param)
+ {
+ $this->_controlsRequiringPostBack=$this->getViewState('ControlsRequiringPostBack',array());
+ parent::onLoadState($param);
+ }
+
+ /**
* Loads page state from persistent storage.
*/
protected function loadPageState()
@@ -416,212 +520,100 @@ class TPage extends TTemplateControl
$this->getPageStatePersister()->save($state);
}
- public function RegisterEnabledControl($control)
- {
- $this->getEna.EnabledControls.Add(control);
- }
-
-
-
/**
- * @internal
+ * @param string the field name
+ * @return boolean whether the specified field is a system field in postback data
*/
- public function registerPostBackScript()
+ protected function isSystemPostField($field)
{
- if($this->getClientSupportsJavaScript() && !$this->_postBackScriptRendered)
- {
- if(!$this->_requirePostBackScript)
- {
- $this->getClientScript()->registerHiddenField('__EVENTTARGET','');
- $this->getClientScript()->registerHiddenField('__EVENTPARAM','');
- $this->_requirePostBackScript=true;
- }
- }
- }
-
- public function registerWebFormsScript()
- {
- if($this->getClientSupportsJavaScript() && !$this->_webFormsScriptRendered)
- {
- $this->registerPostBackScript();
- $this->_requireWebFormsScript=true;
- }
- }
-
-
- public function ensureRenderInForm($control)
- {
- if(!$this->_inFormRender)
- throw new THttpException('control_not_in_form',$control->getUniqueID());
- }
-
- private function renderPostBackScript($writer)
- {
- $id=$this->_form->getUniqueID();
- $str=<<<EOD
-\n<script type="text/javascript">
-<!--
-var theForm=document.forms['$id'];
-if(!theForm)
- theForm=document.$id;
-function __doPostBack(eventTarget,eventParam) {
- if(!theForm.onsubmit || (theForm.onsubmit()!=false)) {
- theForm.__EVENTTARGET.value = eventTarget;
- theForm.__EVENTPARAM.value = eventParam;
- theForm.submit();
- }
-}
-// -->
-</script>\n
-EOD;
- $writer->write($str);
- $this->_postBackScriptRendered=true;
- }
-
- private function renderWebFormsScript($writer)
- {
- $writer->write("\n<script src=\"js/WebForms.js\" type=\"text/javascript\"></script>\n");
- $this->_webFormsScriptRendered=true;
- }
-
- final public function getClientSupportsJavaScript()
- {
- // todo
- return true;
+ return isset(self::$_systemPostFields[$field]);
}
/**
- * @internal
+ * Registers a control for loading post data in the next postback.
+ * @param TControl control registered for loading post data
*/
- final public function beginFormRender($writer)
- {
- if($this->_formRendered)
- throw new THttpException('multiple_form_not_allowed');
- $this->_formRendered=true;
- $this->_inFormRender=true;
-
- $this->getClientScript()->renderHiddenFields($writer);
- if($this->getClientSupportsJavaScript())
- {
- /*
- if($this->getMaintainScrollPositionOnPostBack() && !$this->_requireScrollScript)
- {
- $cs=$this->getClientScript();
- $cs->registerHiddenField('_SCROLLPOSITIONX',$this->_scrollPositionX);
- $cs->registerHiddenField('_SCROLLPOSITIONY',$this->_scrollPositionY);
- $cs->registerStartupScript(get_class($this),"PageScrollPositionScript", "\r\nvar WebForm_ScrollPositionSubmit = theForm.submit;\r\ntheForm.submit = WebForm_SaveScrollPositionSubmit;\r\n\r\nvar WebForm_ScrollPositionOnSubmit = theForm.onsubmit;\r\ntheForm.onsubmit = WebForm_SaveScrollPositionOnSubmit;\r\n\r\nvar WebForm_ScrollPositionLoad = window.onload;\r\nwindow.onload = WebForm_RestoreScrollPosition;\r\n", true);
- $this->registerWebFormScript();
- $this->_requireScrollScript=true;
- }
- */
- if($this->_requirePostBackScript)
- $this->renderPostBackScript($writer,$this->_form->getUniqueID());
- if($this->_requireWebFormsScript)
- $this->renderWebFormsScript($writer);
- }
- $this->getClientScript()->renderScriptBlocks($writer);
- // todo: more ....
- }
-
- final public function getIsPostBackEventControlRegistered()
+ public function registerRequiresPostBack(TControl $control)
{
- return $this->_registeredControlThatRequireRaiseEvent!==null;
+ $this->_controlsRegisteredForPostBack[$control->getUniqueID()]=true;
}
/**
- * @internal
+ * @return TControl the control responsible for the current postback event, null if nonexistent
*/
- final public function endFormRender($writer)
+ public function getPostBackEventTarget()
{
- $cs=$this->getClientScript();
- if($this->getClientSupportsJavaScript())
- $cs->renderArrayDeclarations($writer);
- $cs->renderHiddenFields($writer);
- if($this->getClientSupportsJavaScript())
+ if($this->_postBackEventTarget===null)
{
- if($this->_requirePostBackScript && !$this->_postBackScriptRendered)
- $this->renderPostBackScript($writer);
- if($this->_requireWebFormsScript && !$this->_webFormsScriptRendered)
- $this->renderWebFormsScript($writer);
+ $eventTarget=$this->_postData->itemAt(self::FIELD_POSTBACK_TARGET);
+ if(!empty($eventTarget))
+ $this->_postBackEventTarget=$this->findControl($eventTarget);
}
- $cs->renderStartupScripts($writer);
- $this->_inFormRender=false;
- }
-
- final public function getClientOnSubmitEvent()
- {
- // todo
- if($this->getClientScript()->getHasSubmitStatements())
- return 'javascript:return WebForm_OnSubmit();';
- else
- return '';
- }
-
- protected function initializeCulture()
- {
+ return $this->_postBackEventTarget;
}
/**
- * @internal
+ * Registers a control to raise postback event in the current request.
+ * @param TControl control registered to raise postback event.
*/
- public function loadScrollPosition()
+ public function setPostBackEventTarget(TControl $control)
{
- if($this->_previousPagePath==='' && $this->_requestValueCollection)
- {
- if(isset($_REQUEST['__SCROLLPOSITIONX']))
- $this->_scrollPositionX=(integer)$_REQUEST['__SCROLLPOSITIONX'];
- if(isset($_REQUEST['__SCROLLPOSITIONY']))
- $this->_scrollPositionX=(integer)$_REQUEST['__SCROLLPOSITIONY'];
- }
+ $this->_postBackEventTarget=$control;
}
-
- final public function registerAsyncTask()
+ /**
+ * @return mixed postback event parameter
+ */
+ public function getPostBackEventParameter()
{
+ if($this->_postBackEventParameter===null)
+ $this->_postBackEventParameter=$this->_postData->itemAt(self::FIELD_POSTBACK_PARAMETER);
+ return $this->_postBackEventParameter;
}
- final public function registerRequiresPostBack($control)
+ /**
+ * @param mixed postback event parameter
+ */
+ public function setPostBackEventParameter($value)
{
- if(!$this->_registeredControlsThatRequirePostBack)
- $this->_registeredControlsThatRequirePostBack=new TList;
- $this->_registeredControlsThatRequirePostBack->add($control->getUniqueID());
+ $this->_postBackEventParameter=$value;
}
- final public function registerRequiresRaiseEvent($control)
+ /**
+ * Registers a control as the
+ */
+ public function registerAutoPostBackControl(TControl $control)
{
- $this->_registeredControlThatRequireRaiseEvent=$control;
+ $this->_autoPostBackControl=$control;
}
+ /**
+ * Processes post data.
+ * @param TMap post data to be processed
+ * @param boolean whether this method is invoked before {@link onLoad Load}.
+ */
protected function processPostData($postData,$beforeLoad)
{
- $eventTarget=$postData->itemAt('__EVENTTARGET');
+ if($beforeLoad)
+ $this->_restPostData=new TMap;
foreach($postData as $key=>$value)
{
- if(in_array($key,self::$_systemPostFields))
+ if($this->isSystemPostField($key))
continue;
else if($control=$this->findControl($key))
{
if($control instanceof IPostBackDataHandler)
{
- if($control->loadPostData($key,$this->_postData))
- $this->_changedPostDataConsumers[]=$control;
- unset($this->_controlsRequiringPostBack[$key]);
- }
- else
- {
- if(empty($eventTarget))
- {
- if($control instanceof IPostBackEventHandler)
- $this->registerRequiresRaiseEvent($control);
- }
- else
- unset($this->_controlsRequiringPostBack[$key]);
+ if($control->loadPostData($key,$postData))
+ $this->_controlsPostDataChanged[]=$control;
}
+ else if($control instanceof IPostBackEventHandler)
+ $this->setPostBackEventTarget($control);
+ unset($this->_controlsRequiringPostBack[$key]);
}
else if($beforeLoad)
$this->_restPostData->add($key,$value);
}
- $list=new TMap;
foreach($this->_controlsRequiringPostBack as $key=>$value)
{
if($control=$this->findControl($key))
@@ -629,93 +621,140 @@ EOD;
if($control instanceof IPostBackDataHandler)
{
if($control->loadPostData($key,$this->_postData))
- $this->_changedPostDataConsumers->add($control);
+ $this->_controlsPostDataChanged[]=$control;
}
else
- throw new THttpException('postback_control_not_found',$key);
+ throw new TInvalidDataValueException('page_postbackcontrol_invalid',$key);
+ unset($this->_controlsRequiringPostBack[$key]);
}
- else if($beforeLoad)
- $list->add($key,null);
}
- $this->_controlsRequiringPostBack=$list;
}
- final public function getAutoPostBackControl()
+ /**
+ * Raises PostDataChangedEvent for controls whose data have been changed due to the postback.
+ */
+ private function raiseChangedEvents()
{
- return $this->_autoPostBackControl;
+ foreach($this->_controlsPostDataChanged as $control)
+ $control->raisePostDataChangedEvent();
}
- final public function setAutoPostBackControl($control)
+ /**
+ * Raises PostBack event.
+ */
+ private function raisePostBackEvent()
{
- $this->_autoPostBackControl=$control;
+ if(($postBackHandler=$this->getPostBackEventTarget())===null)
+ $this->validate();
+ else if($postBackHandler instanceof IPostBackEventHandler)
+ $postBackHandler->raisePostBackEvent($this->getPostBackEventParameter());
}
- private function raiseChangedEvents()
+ /**
+ * Ensures the control is rendered within a form.
+ * @param TControl the control to be rendered
+ * @throws TInvalidConfigurationException if the control is outside of the form
+ */
+ public function ensureRenderInForm($control)
{
- foreach($this->_changedPostDataConsumers as $control)
- $control->raisePostDataChangedEvent();
+ if(!$this->_inFormRender)
+ throw new TInvalidConfigurationException('page_control_outofform',get_class($control),$control->getID(false));
+ }
+
+ /**
+ * @internal
+ */
+ public function beginFormRender($writer)
+ {
+ if($this->_formRendered)
+ throw new TInvalidConfigurationException('page_singleform_required');
+ $this->_formRendered=true;
+ $this->_inFormRender=true;
+ $this->getClientScript()->renderBeginScripts($writer);
}
- private function raisePostBackEvent($postData)
+ /**
+ * @internal
+ */
+ public function endFormRender($writer)
{
- if($this->_registeredControlThatRequireRaiseEvent)
- {
- $this->_registeredControlThatRequireRaiseEvent->raisePostBackEvent(null);
- }
- else
+ $cs=$this->getClientScript();
+ if($this->getClientSupportsJavaScript())
{
- $eventTarget=$postData->itemAt('__EVENTTARGET');
- if(!empty($eventTarget) || $this->getAutoPostBackControl())
+ if($this->_focusedControl && $this->_focusedControl->getVisible(true))
+ $cs->registerFocusScript($this->_focusedControl->getClientID());
+ else if($this->_postData && ($lastFocus=$this->_postData->itemAt(self::FIELD_LASTFOCUS))!==null)
+ $cs->registerFocusScript($lastFocus);
+ if($this->_maintainScrollPosition && $this->_postData)
{
- if(!empty($eventTarget))
- $control=$this->findControl($eventTarget);
- else
- $control=null;
- if($control instanceof IPostBackEventHandler)
- $control->raisePostBackEvent($postData->itemAt('__EVENTPARAM'));
+ $x=TPropertyValue::ensureInteger($this->_postData->itemAt(self::PRADO_SCROLLX));
+ $y=TPropertyValue::ensureInteger($this->_postData->itemAt(self::PRADO_SCROLLY));
+ $cs->registerScrollScript($x,$y);
}
- else
- $this->validate();
+ $cs->renderHiddenFields($writer);
+ $cs->renderArrayDeclarations($writer);
+ $cs->renderExpandoAttributes($writer);
+ $cs->renderScriptIncludes($writer);
+ $cs->renderEndScripts($writer);
}
+ else
+ $cs->renderHiddenFields($writer);
+ $this->_inFormRender=false;
}
- public function run($writer)
+ public function setFocus(TControl $value)
{
- $this->determinePostBackMode();
- $this->_restPostData=new TMap;
+ $this->_focusedControl=$value;
+ }
- $this->onPreInit(null);
- $this->_preInitWorkComplete=true;
+ public function getMaintainScrollPosition()
+ {
+ return $this->_maintainScrollPosition;
+ }
- $this->initRecursive(null);
- $this->onInitComplete(null);
+ public function setMaintainScrollPosition($value)
+ {
+ $this->_maintainScrollPosition=TPropertyValue::ensureBoolean($value);
+ }
- if($this->getIsPostBack())
- {
- $this->loadPageState();
- $this->processPostData($this->_postData,true);
- }
+ public function getClientSupportsJavaScript()
+ {
+ // todo
+ return true;
+ }
- $this->onPreLoad(null);
- $this->loadRecursive(null);
- if($this->getIsPostBack())
- {
- $this->processPostData($this->_restPostData,false);
- $this->raiseChangedEvents();
- $this->raisePostBackEvent($this->_postData);
- }
- $this->onLoadComplete(null);
- $this->preRenderRecursive();
- $this->onPreRenderComplete(null);
+ public function getClientOnSubmitEvent()
+ {
+ // todo
+ if($this->getClientScript()->getHasSubmitStatements())
+ return 'javascript:return WebForm_OnSubmit();';
+ else
+ return '';
+ }
- $this->savePageState();
- $this->onSaveStateComplete(null);
+ protected function initializeCulture()
+ {
+ }
- $this->renderControl($writer);
- $this->unloadRecursive();
+ /**
+ * @internal
+ */
+ public function loadScrollPosition()
+ {
+ if($this->_previousPagePath==='' && $this->_requestValueCollection)
+ {
+ if(isset($_REQUEST['__SCROLLPOSITIONX']))
+ $this->_scrollPositionX=(integer)$_REQUEST['__SCROLLPOSITIONX'];
+ if(isset($_REQUEST['__SCROLLPOSITIONY']))
+ $this->_scrollPositionX=(integer)$_REQUEST['__SCROLLPOSITIONY'];
+ }
}
+
+ final public function registerAsyncTask()
+ {
+ }
}
?> \ No newline at end of file
diff --git a/framework/Web/UI/TTemplateControl.php b/framework/Web/UI/TTemplateControl.php
index 13a3295f..e1a2d248 100644
--- a/framework/Web/UI/TTemplateControl.php
+++ b/framework/Web/UI/TTemplateControl.php
@@ -185,7 +185,7 @@ class TTemplateControl extends TControl implements INamingContainer
* Only framework developers should use this method.
* @param TControl the naming container control
*/
- protected function initRecursive($namingContainer)
+ protected function initRecursive($namingContainer=null)
{
$this->ensureChildControls();
if($this->_masterClass!=='')
diff --git a/framework/Web/UI/WebControls/TCheckBox.php b/framework/Web/UI/WebControls/TCheckBox.php
index 7b9d4702..ad83556e 100644
--- a/framework/Web/UI/WebControls/TCheckBox.php
+++ b/framework/Web/UI/WebControls/TCheckBox.php
@@ -103,9 +103,9 @@ class TCheckBox extends TWebControl implements IPostBackDataHandler, IValidatabl
public function raisePostDataChangedEvent()
{
$page=$this->getPage();
- if($this->getAutoPostBack() && !$page->getIsPostBackEventControlRegistered())
+ if($this->getAutoPostBack() && !$page->getPostBackEventTarget())
{
- $page->setAutoPostBackControl($this);
+ $page->setPostBackEventTarget($this);
if($this->getCausesValidation())
$page->validate($this->getValidationGroup());
}
@@ -393,7 +393,41 @@ class TCheckBox extends TWebControl implements IPostBackDataHandler, IValidatabl
$writer->renderBeginTag('input');
$writer->renderEndTag();
}
- // todo: onprerender???
+
+ protected function onPreRender($param)
+ {
+ parent::onPreRender($param);
+ $this->getPage()->registerRequiresPostBack($this);
+ }
+
+ /*
+protected internal override void OnPreRender(EventArgs e)
+{
+ base.OnPreRender(e);
+ bool flag1 = this.AutoPostBack;
+ if ((this.Page != null) && base.IsEnabled)
+ {
+ this.Page.RegisterRequiresPostBack(this);
+ if (flag1)
+ {
+ this.Page.RegisterPostBackScript();
+ this.Page.RegisterFocusScript();
+ if (this.CausesValidation && (this.Page.GetValidators(this.ValidationGroup).Count > 0))
+ {
+ this.Page.RegisterWebFormsScript();
+ }
+ }
+ }
+ if (!this.SaveCheckedViewState(flag1))
+ {
+ this.ViewState.SetItemDirty("Checked", false);
+ if ((this.Page != null) && base.IsEnabled)
+ {
+ this.Page.RegisterEnabledControl(this);
+ }
+ }
+}
+*/
}
?> \ No newline at end of file
diff --git a/framework/Web/UI/WebControls/TImageButton.php b/framework/Web/UI/WebControls/TImageButton.php
index b0fb5a8b..7043fa86 100644
--- a/framework/Web/UI/WebControls/TImageButton.php
+++ b/framework/Web/UI/WebControls/TImageButton.php
@@ -117,7 +117,7 @@ class TImageButton extends TImage implements IPostBackDataHandler, IPostBackEven
{
$this->_x=intval($values["{$uid}_x"]);
$this->_y=intval($values["{$uid}_y"]);
- $page=$this->getPage()->registerRequiresRaiseEvent($this);
+ $page=$this->getPage()->setPostBackEventTarget($this);
}
return false;
}
diff --git a/framework/Web/UI/WebControls/TTextBox.php b/framework/Web/UI/WebControls/TTextBox.php
index 5e57e240..bfd7c029 100644
--- a/framework/Web/UI/WebControls/TTextBox.php
+++ b/framework/Web/UI/WebControls/TTextBox.php
@@ -224,15 +224,14 @@ class TTextBox extends TWebControl implements IPostBackDataHandler, IValidatable
public function raisePostDataChangedEvent()
{
$page=$this->getPage();
- if($this->getAutoPostBack() && !$page->getIsPostBackEventControlRegistered())
+ if($this->getAutoPostBack() && !$page->getPostBackEventTarget())
{
- $page->setAutoPostBackControl($this);
+ $page->setPostBackEventTarget($this);
if($this->getCausesValidation())
$page->validate($this->getValidationGroup());
}
$this->onTextChanged(new TEventParameter);
}
-
/**
* Renders the body content of the textbox when it is in MultiLine text mode.
* @param THtmlWriter the writer for rendering