From 67e09d150afe55d7a956beb299dc0534f7da68eb Mon Sep 17 00:00:00 2001 From: wei <> Date: Thu, 15 Jun 2006 00:56:57 +0000 Subject: Update active controls. Add comments. Add THttpResponseAdapter --- framework/Web/UI/ActiveControls/TActiveButton.php | 61 ++++++++-- .../UI/ActiveControls/TActiveControlAdapter.php | 2 +- framework/Web/UI/ActiveControls/TActiveLabel.php | 16 ++- .../Web/UI/ActiveControls/TActivePageAdapter.php | 70 +++++------ framework/Web/UI/ActiveControls/TActivePanel.php | 2 +- framework/Web/UI/ActiveControls/TActiveTextBox.php | 2 +- framework/Web/UI/ActiveControls/TAutoComplete.php | 29 ++++- .../Web/UI/ActiveControls/TBaseActiveControl.php | 128 ++++++++++++++++++--- framework/Web/UI/ActiveControls/TCallback.php | 23 +++- .../Web/UI/ActiveControls/TCallbackOptions.php | 2 +- .../UI/ActiveControls/TCallbackResponseAdapter.php | 65 +++++++++++ 11 files changed, 305 insertions(+), 95 deletions(-) create mode 100755 framework/Web/UI/ActiveControls/TCallbackResponseAdapter.php (limited to 'framework/Web/UI/ActiveControls') diff --git a/framework/Web/UI/ActiveControls/TActiveButton.php b/framework/Web/UI/ActiveControls/TActiveButton.php index 84db60fc..f4bfc678 100644 --- a/framework/Web/UI/ActiveControls/TActiveButton.php +++ b/framework/Web/UI/ActiveControls/TActiveButton.php @@ -1,8 +1,33 @@ + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2006 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Revision: $ $Date: $ + * @package System.Web.UI.WebControls */ +/** + * TActiveButton is the active control counter part to TButton. + * + * When a TActiveButton is clicked, rather than a normal post back request a + * callback request is initiated. + * + * The {@link onCallback OnCallback} event is raised during a callback request + * and it is raise before the {@link onClick OnClick} event. + * + * When the {@link TBaseActiveCallbackControl::setEnableUpdate ActiveControl.EnableUpdate} + * property is true, changing the {@link setText Text} property during callback request + * will update the button's caption upon callback response completion. + * + * @author Wei Zhuo + * @version $Revision: $ $Date: $ + * @package System.Web.UI.ActiveControls + * @since 3.0 + */ class TActiveButton extends TButton implements ICallbackEventHandler { /** @@ -17,11 +42,11 @@ class TActiveButton extends TButton implements ICallbackEventHandler } /** - * @return TBaseActiveCallbackControl base callback options. + * @return TBaseActiveCallbackControl standard callback control options. */ public function getActiveControl() { - return $this->getAdapter()->getActiveControl(); + return $this->getAdapter()->getBaseActiveControl(); } /** @@ -29,14 +54,14 @@ class TActiveButton extends TButton implements ICallbackEventHandler * ICallbackEventHandler} interface. If {@link getCausesValidation * CausesValidation} is true, it will invoke the page's {@link TPage:: * validate validate} method first. It will raise {@link onCallback - * OnCallback} event and then the {@link onClick OnClick} event. This method - * is mainly used by framework and control developers. + * OnCallback} event first and then the {@link onClick OnClick} event. + * This method is mainly used by framework and control developers. * @param TCallbackEventParameter the event parameter */ public function raiseCallbackEvent($param) { - $this->raisePostBackEvent($param); $this->onCallback($param); + $this->raisePostBackEvent($param); } /** @@ -51,7 +76,9 @@ class TActiveButton extends TButton implements ICallbackEventHandler $this->raiseEvent('OnCallback', $this, $param); } - /** + /** + * Updates the button text on the client-side if the + * {@link setEnableUpdate EnableUpdate} property is set to true. * @param string caption of the button */ public function setText($value) @@ -62,17 +89,31 @@ class TActiveButton extends TButton implements ICallbackEventHandler } /** - * Renders the callback control javascript statement. + * Override parent implementation, no javascript is rendered here instead + * the javascript required for active control is registered in {@link addAttributesToRender}. */ protected function renderClientControlScript($writer) { } + /** + * Ensure that the ID attribute is rendered and registers the javascript code + * for initializing the active control. + */ protected function addAttributesToRender($writer) { parent::addAttributesToRender($writer); $writer->addAttribute('id',$this->getClientID()); - $this->getActiveControl()->registerCallbackClientScript($this->getPostBackOptions()); + $this->getActiveControl()->registerCallbackClientScript( + $this->getClientClassName(), $this->getPostBackOptions()); + } + + /** + * @return string corresponding javascript class name for this TActiveButton. + */ + protected function getClientClassName() + { + return 'Prado.WebUI.TActiveButton'; } /** diff --git a/framework/Web/UI/ActiveControls/TActiveControlAdapter.php b/framework/Web/UI/ActiveControls/TActiveControlAdapter.php index af4131ea..ab842976 100644 --- a/framework/Web/UI/ActiveControls/TActiveControlAdapter.php +++ b/framework/Web/UI/ActiveControls/TActiveControlAdapter.php @@ -59,7 +59,7 @@ class TActiveControlAdapter extends TControlAdapter } } - public function getActiveControl() + public function getBaseActiveControl() { if(is_null($this->_baseActiveControl)) { diff --git a/framework/Web/UI/ActiveControls/TActiveLabel.php b/framework/Web/UI/ActiveControls/TActiveLabel.php index fd2d49b8..c1cb1fba 100644 --- a/framework/Web/UI/ActiveControls/TActiveLabel.php +++ b/framework/Web/UI/ActiveControls/TActiveLabel.php @@ -13,11 +13,12 @@ /** * TActiveLabel class * - * The active control counterpart of TLabel component. During a callback - * request, setting {@link setText Text} property will also set the text of the - * label on the client upon callback completion. Similarly, setting {@link - * setForControl ForControl} will set the client-side for attribute on the - * label. + * The active control counterpart of TLabel component. When + * {@link TBaseActiveControl::setEnableUpdate ActiveControl.EnableUpdate} + * property is true the during a callback request, setting {@link setText Text} + * property will also set the text of the label on the client upon callback + * completion. Similarly, setting {@link setForControl ForControl} will also set + * the client-side "for" attribute on the label. * * @author Wei Zhuo * @version $Revision: $ $Date: $ @@ -37,9 +38,12 @@ class TActiveLabel extends TLabel $this->setAdapter(new TActiveControlAdapter($this)); } + /** + * @return TBaseActiveControl basic active control options. + */ public function getActiveControl() { - return $this->getAdapter()->getActiveControl(); + return $this->getAdapter()->getBaseActiveControl(); } /** diff --git a/framework/Web/UI/ActiveControls/TActivePageAdapter.php b/framework/Web/UI/ActiveControls/TActivePageAdapter.php index 9148a27f..77d8a7fe 100644 --- a/framework/Web/UI/ActiveControls/TActivePageAdapter.php +++ b/framework/Web/UI/ActiveControls/TActivePageAdapter.php @@ -1,6 +1,6 @@ * @link http://www.pradosoft.com/ @@ -39,11 +39,7 @@ class TActivePageAdapter extends TControlAdapter * @var TCallbackClientScript callback client script handler */ private $_callbackClient; - /** - * @var TCallbackEventParameter callback result. - */ - private $_result; - + /** * Constructor, trap errors and exception to let the callback response * handle them. @@ -51,7 +47,11 @@ class TActivePageAdapter extends TControlAdapter public function __construct(TPage $control) { parent::__construct($control); - $this->getApplication()->setResponse($this->createCallbackResponseHandler()); + + //TODO: can this be done later? + $response = $this->getApplication()->getResponse(); + $response->setAdapter(new TCallbackResponseAdapter($response)); + $this->trapCallbackErrorsExceptions(); } @@ -88,11 +88,19 @@ class TActivePageAdapter extends TControlAdapter $executeJavascript = $this->getCallbackClientHandler()->getClientFunctionsToExecute()->toArray(); $actions = TJavascript::jsonEncode($executeJavascript); $response->appendHeader(self::CALLBACK_ACTION_HEADER.': '.$actions); - if($this->_result) + + //send response data in header + if($response->getHasAdapter()) { - $data = TJavascript::jsonEncode($this->_result->getData()); - $response->appendHeader(self::CALLBACK_DATA_HEADER.': '.$data); + $responseData = $response->getAdapter()->getResponseData(); + if(!is_null($responseData)) + { + $data = TJavascript::jsonEncode($responseData); + $response->appendHeader(self::CALLBACK_DATA_HEADER.': '.$data); + } } + + //sends page state in header if(($handler = $this->getCallbackEventTarget()) !== null) { if($handler->getActiveControl()->getClientSide()->getEnablePageStateUpdate()) @@ -102,7 +110,7 @@ class TActivePageAdapter extends TControlAdapter } } } - + /** * Trys to find the callback event handler and raise its callback event. * @throws TInvalidCallbackRequestException if call back target is not found. @@ -116,8 +124,8 @@ class TActivePageAdapter extends TControlAdapter if($callbackHandler instanceof ICallbackEventHandler) { $param = $this->getCallbackEventParameter(); - $this->_result = new TCallbackEventParameter($this->getResponse(), $param); - $callbackHandler->raiseCallbackEvent($this->_result); + $result = new TCallbackEventParameter($this->getResponse(), $param); + $callbackHandler->raiseCallbackEvent($result); } else { @@ -131,14 +139,6 @@ class TActivePageAdapter extends TControlAdapter } } - /** - * @return mixed callback event result. - */ - public function getCallbackEventResult() - { - return $this->_callbackEventResult->getResult(); - } - /** * @return TControl the control responsible for the current callback event, * null if nonexistent @@ -196,21 +196,7 @@ class TActivePageAdapter extends TControlAdapter if(is_null($this->_callbackClient)) $this->_callbackClient = new TCallbackClientScript; return $this->_callbackClient; - } - - /** - * @param TCallbackClientScript new callback client handler. - */ - public function setCallbackClientHandler($handler) - { - $this->_callbackClient = $handler; - } - - protected function createCallbackResponseHandler() - { - return new TCallbackResponse(); - } - + } } /** @@ -231,17 +217,13 @@ class TActivePageAdapter extends TControlAdapter class TCallbackEventParameter extends TEventParameter { /** - * @var TCallbackResponse output content. + * @var THttpResponse output content. */ private $_response; /** * @var mixed callback request parameter. */ private $_parameter; - /** - * @var mixed callback response data. - */ - private $_data; /** * Creates a new TCallbackEventParameter. @@ -257,7 +239,7 @@ class TCallbackEventParameter extends TEventParameter */ public function getOutput() { - return $this->_response->createHtmlWriter(null,$this); + return $this->_response->createHtmlWriter(null); } /** @@ -273,7 +255,7 @@ class TCallbackEventParameter extends TEventParameter */ public function setData($value) { - $this->_data = $value; + $this->_response->getAdapter()->setResponseData($value); } /** @@ -281,7 +263,7 @@ class TCallbackEventParameter extends TEventParameter */ public function getData() { - return $this->_data; + return $this->_response->getAdapter()->getResponseData(); } } diff --git a/framework/Web/UI/ActiveControls/TActivePanel.php b/framework/Web/UI/ActiveControls/TActivePanel.php index bd7b2200..db1d8a7d 100644 --- a/framework/Web/UI/ActiveControls/TActivePanel.php +++ b/framework/Web/UI/ActiveControls/TActivePanel.php @@ -18,7 +18,7 @@ class TActivePanel extends TPanel public function getActiveControl() { - return $this->getAdapter()->getActiveControl(); + return $this->getAdapter()->getBaseActiveControl(); } } diff --git a/framework/Web/UI/ActiveControls/TActiveTextBox.php b/framework/Web/UI/ActiveControls/TActiveTextBox.php index 91adf8c7..ece08e11 100644 --- a/framework/Web/UI/ActiveControls/TActiveTextBox.php +++ b/framework/Web/UI/ActiveControls/TActiveTextBox.php @@ -18,7 +18,7 @@ class TActiveTextBox extends TTextBox public function getActiveControl() { - return $this->getAdapter()->getActiveControl(); + return $this->getAdapter()->getBaseActiveControl(); } /** diff --git a/framework/Web/UI/ActiveControls/TAutoComplete.php b/framework/Web/UI/ActiveControls/TAutoComplete.php index 5a76847d..63b1d089 100644 --- a/framework/Web/UI/ActiveControls/TAutoComplete.php +++ b/framework/Web/UI/ActiveControls/TAutoComplete.php @@ -139,7 +139,7 @@ class TAutoComplete extends TActiveTextBox implements ICallbackEventHandler, INa { $this->getSuggestions()->render($writer); $boundary = $writer->getWriter()->getBoundary(); - $writer->getWriter()->getResponse()->setData($boundary); + $this->getResponse()->getAdapter()->setResponseData($boundary); } } @@ -162,17 +162,34 @@ class TAutoComplete extends TActiveTextBox implements ICallbackEventHandler, INa return $options; } + /** + * Override parent implementation, no javascript is rendered here instead + * the javascript required for active control is registered in {@link addAttributesToRender}. + */ + protected function renderClientControlScript($writer) + { + } + + /** + * Ensure that the ID attribute is rendered and registers the javascript code + * for initializing the active control. + */ + public function addAttributesToRender($writer) { parent::addAttributesToRender($writer); $writer->addAttribute('id',$this->getClientID()); - $this->getActiveControl()->registerCallbackClientScript($this->getAutoCompleteOptions()); + $this->getActiveControl()->registerCallbackClientScript( + $this->getClientClassName(), $this->getAutoCompleteOptions()); } - - protected function renderClientControlScript($writer) + + /** + * @return string corresponding javascript class name for this TActiveButton. + */ + protected function getClientClassName() { - - } + return 'Prado.WebUI.TAutoComplete'; + } } /** diff --git a/framework/Web/UI/ActiveControls/TBaseActiveControl.php b/framework/Web/UI/ActiveControls/TBaseActiveControl.php index d2f1ef57..13d953c8 100644 --- a/framework/Web/UI/ActiveControls/TBaseActiveControl.php +++ b/framework/Web/UI/ActiveControls/TBaseActiveControl.php @@ -1,18 +1,59 @@ + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Revision: $ $Date: $ + * @package System.Web.UI.ActiveControls + */ + +/** + * TBaseActiveControl class provided additional basic property for every + * active control. An instance of TBaseActiveControl or its decendent + * TBaseActiveCallbackControl is created by {@link TActiveControlAdapter::getBaseActiveControl()} + * method. + * + * The {@link setEnableUpdate EnableUpdate} property determines wether the active + * control is allowed to update the contents of the client-side when the callback + * response returns. + * + * @author Wei Zhuo + * @version $Revision: $ $Date: $ + * @package System.Web.UI.ActiveControls + * @since 3.0 */ class TBaseActiveControl extends TComponent { + /** + * @TMap map of active control options. + */ private $_options; + /** + * @TControl attached control. + */ private $_control; + /** + * Constructor. Attach a base active control to an active control instance. + * @param TControl active control + */ public function __construct($control) { $this->_control = $control; $this->_options = new TMap; } + /** + * Sets a named options with a value. Options are used to store and retrive + * named values for the base active controls. + * @param string option name. + * @param mixed new value. + * @param mixed default value. + * @return mixed options value. + */ protected function setOption($name,$value,$default=null) { $value = is_null($value) ? $default : $value; @@ -20,17 +61,30 @@ class TBaseActiveControl extends TComponent $this->_options->add($name,$value); } + /** + * Gets an option named value. Options are used to store and retrive + * named values for the base active controls. + * @param string option name. + * @param mixed default value. + * @return mixed options value. + */ protected function getOption($name,$default=null) { $item = $this->_options->itemAt($name); return is_null($item) ? $default : $item; } + /** + * @return TPage the page containing the attached control. + */ protected function getPage() { return $this->_control->getPage(); } + /** + * @return TControl the attached control. + */ protected function getControl() { return $this->_control; @@ -44,14 +98,21 @@ class TBaseActiveControl extends TComponent $this->setOption('EnableUpdate', TPropertyValue::ensureBoolean($value), true); } - /** - * @return true to allow fine grain callback updates. + /** + * @return boolean true to allow fine grain callback updates. */ public function getEnableUpdate() { return $this->getOption('EnableUpdate', true); } + /** + * Returns true if callback response is allowed to update the browser contents. + * Is is true if the control is initilized, and is a callback request and + * the {@link setEnableUpdate EnabledUpdate} property is true. + * @return boolean true if the callback response is allowed update + * client-side contents. + */ public function canUpdateClientSide() { return $this->getControl()->getIsInitialized() @@ -60,21 +121,44 @@ class TBaseActiveControl extends TComponent } } - +/** + * TBaseActiveCallbackControl is a common set of options and functionality for + * active controls that can perform callback requests. + * + * The properties of TBaseActiveCallbackControl can be accessed and changed from + * each individual active controls' {@link getActiveControl ActiveControl} + * property. + * + * The following example to set the validation group property of a TCallback component. + * + * + * + * + * Additional client-side options and events can be set using the + * {@link getClientSide ClientSide} property. The following example to show + * an alert box when a TCallback component response returns successfully. + * + * + * + * + * @author Wei Zhuo + * @version $Revision: $ Fri Jun 16 08:40:43 EST 2006 $ + * @package System.Web.UI.ActiveControls + * @since 3.0 + */ class TBaseActiveCallbackControl extends TBaseActiveControl { /** * Callback client-side options can be set by setting the properties of - * the ClientSide property. E.g. - * See {@link TCallbackClientSideOptions} for details on the properties of - * ClientSide. + * the ClientSide property. E.g. + * See {@link TCallbackClientSideOptions} for details on the properties of ClientSide. * @return TCallbackClientSideOptions client-side callback options. */ public function getClientSide() { if(is_null($client = $this->getOption('ClientSide'))) { - $client = $this->createClientSide(); + $client = $this->createClientSideOptions(); $this->setOption('ClientSide', $client); } return $client; @@ -83,9 +167,9 @@ class TBaseActiveCallbackControl extends TBaseActiveControl /** * @return TCallbackClientSideOptions callback client-side options. */ - protected function createClientSide() + protected function createClientSideOptions() { - if(($id=$this->getCallbackOptions())!=='' + if(($id=$this->getCallbackOptionID())!=='' && ($control=$this->getControl()->findControl($id))!==null) { if($control instanceof TCallbackOptions) @@ -101,7 +185,7 @@ class TBaseActiveCallbackControl extends TBaseActiveControl * @param string ID of a TCallbackOptions control from which ClientSide * options are cloned. */ - public function setCallbackOptions($value) + public function setCallbackOptionID($value) { $this->setOption('CallbackOptions', $value, ''); } @@ -110,7 +194,7 @@ class TBaseActiveCallbackControl extends TBaseActiveControl * @return string ID of a TCallbackOptions control from which ClientSide * options are cloned. */ - public function getCallbackOptions() + public function getCallbackOptionID() { return $this->getOption('CallbackOptions', ''); } @@ -178,17 +262,23 @@ class TBaseActiveCallbackControl extends TBaseActiveControl return $options; } - public function registerCallbackClientScript($options=null) + /** + * Registers the callback control javascript code. Client-side options are + * merged and passed to the javascript code. This method should be called by + * Active component developers wanting to register the javascript to initialize + * the active component with additional options offered by the + * {@link getClientSide ClientSide} property. + * @param string client side javascript class name. + * @param array additional callback options. + */ + public function registerCallbackClientScript($class,$options=null) { $cs = $this->getPage()->getClientScript(); if(is_array($options)) $options = array_merge($this->getClientSideOptions(),$options); else - $options = $this->getClientSideOptions(); - // TODO (xue): - // We need explicitly specify what js class is to be used - // to avoid problem that may occur in extended child class - $cs->registerCallbackControl('Prado.WebUI.'.get_class($this->getControl()), $options); + $options = $this->getClientSideOptions(); + $cs->registerCallbackControl($class, $options); } /** diff --git a/framework/Web/UI/ActiveControls/TCallback.php b/framework/Web/UI/ActiveControls/TCallback.php index 681093ee..c42b2cd7 100644 --- a/framework/Web/UI/ActiveControls/TCallback.php +++ b/framework/Web/UI/ActiveControls/TCallback.php @@ -15,9 +15,20 @@ * * The TCallback provides a basic callback handler that can be invoke from the * client side by running the javascript code obtained from the - * {@link getCallbackReference CallbackReference} property. The event {@link - * onCallback OnCallback} is raise when a callback is requested by the TCallback - * component. + * {@link TBaseActiveCallbackControl::getJavascript ActiveControl.Javascript} property. + * The event {@link onCallback OnCallback} is raise when a callback is requested made. + * + * Example usage: + * + * + * + *
Click Me!
+ *
* * @author Wei Zhuo * @version $Revision: $ $Date: $ @@ -38,17 +49,17 @@ class TCallback extends TControl implements ICallbackEventHandler } /** - * @return TBaseActiveCallbackControl base callback options. + * @return TBaseActiveCallbackControl standard callback options. */ public function getActiveControl() { - return $this->getAdapter()->getActiveControl(); + return $this->getAdapter()->getBaseActiveControl(); } /** * Raises the callback event. This method is required by {@link * ICallbackEventHandler} interface. If {@link getCausesValidation - * CausesValidation} is true, it will invoke the page's {@link TPage:: + * ActiveControl.CausesValidation} is true, it will invoke the page's {@link TPage:: * validate validate} method first. It will raise {@link onCallback * OnCallback} event. This method is mainly used by framework and control * developers. diff --git a/framework/Web/UI/ActiveControls/TCallbackOptions.php b/framework/Web/UI/ActiveControls/TCallbackOptions.php index e9c48c43..fc0becb5 100644 --- a/framework/Web/UI/ActiveControls/TCallbackOptions.php +++ b/framework/Web/UI/ActiveControls/TCallbackOptions.php @@ -9,7 +9,7 @@ class TCallbackOptions extends TControl /** * Callback client-side options can be set by setting the properties of - * the ClientSide property. E.g. + * the ClientSide property. E.g. * See {@link TCallbackClientSideOptions} for details on the properties of * ClientSide. * @return TCallbackClientSideOptions client-side callback options. diff --git a/framework/Web/UI/ActiveControls/TCallbackResponseAdapter.php b/framework/Web/UI/ActiveControls/TCallbackResponseAdapter.php new file mode 100755 index 00000000..d1ec67ad --- /dev/null +++ b/framework/Web/UI/ActiveControls/TCallbackResponseAdapter.php @@ -0,0 +1,65 @@ +_writers[] = $writer; + return parent::createNewHtmlWriter($type,$writer); + } + + public function flushContent() + { + foreach($this->_writers as $writer) + echo $writer->flush(); + parent::flushContent(); + } + + public function setResponseData($data) + { + $this->_data = $data; + } + + public function getResponseData() + { + return $this->_data; + } +} + +class TCallbackResponseWriter extends TTextWriter +{ + private $_boundary; + + public function __construct() + { + $this->_boundary = sprintf('%x',crc32((string)$this)); + } + + public function getBoundary() + { + return $this->_boundary; + } + + public function setBoundary($value) + { + $this->_boundary = $value; + } + + public function flush() + { + $content = ''; + $content .= parent::flush(); + $content .= ''; + return $content; + } +} + +?> \ No newline at end of file -- cgit v1.2.3