diff options
Diffstat (limited to 'framework/Web/UI')
| -rw-r--r-- | framework/Web/UI/TClientScriptManager.php | 155 | ||||
| -rw-r--r-- | framework/Web/UI/TControl.php | 2 | ||||
| -rw-r--r-- | framework/Web/UI/THiddenFieldPageStatePersister.php | 4 | ||||
| -rw-r--r-- | framework/Web/UI/TPage.php | 505 | ||||
| -rw-r--r-- | framework/Web/UI/TTemplateControl.php | 2 | ||||
| -rw-r--r-- | framework/Web/UI/WebControls/TCheckBox.php | 40 | ||||
| -rw-r--r-- | framework/Web/UI/WebControls/TImageButton.php | 2 | ||||
| -rw-r--r-- | framework/Web/UI/WebControls/TTextBox.php | 5 | 
8 files changed, 395 insertions, 320 deletions
| 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()
 -	{
 -		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()
 +	protected function isSystemPostField($field)
  	{
 -		// 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)
 +	public function registerRequiresPostBack(TControl $control)
  	{
 -		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()
 -	{
 -		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));
  	}
 -	private function raisePostBackEvent($postData)
 +	/**
 +	 * @internal
 +	 */
 +	public function beginFormRender($writer)
  	{
 -		if($this->_registeredControlThatRequireRaiseEvent)
 -		{
 -			$this->_registeredControlThatRequireRaiseEvent->raisePostBackEvent(null);
 -		}
 -		else
 +		if($this->_formRendered)
 +			throw new TInvalidConfigurationException('page_singleform_required');
 +		$this->_formRendered=true;
 +		$this->_inFormRender=true;
 +		$this->getClientScript()->renderBeginScripts($writer);
 +	}
 +
 +	/**
 +	 * @internal
 +	 */
 +	public function endFormRender($writer)
 +	{
 +		$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
 | 
