summaryrefslogtreecommitdiff
path: root/framework/Web
diff options
context:
space:
mode:
authorwei <>2006-05-05 06:58:04 +0000
committerwei <>2006-05-05 06:58:04 +0000
commit47d05516b1d1c465217c59732bf8442ab0cfd497 (patch)
treec8c8fce4eb2c4ca9580b87a7c410fb7606ce1af4 /framework/Web
parentf21d3433721308f5d0693f44bbfed56f7b2ecc2d (diff)
Added prioritize callback and enabled viewstate update on callback return.
Diffstat (limited to 'framework/Web')
-rw-r--r--framework/Web/Javascripts/js/ajax.js44
-rw-r--r--framework/Web/Javascripts/prado/ajax3.js130
-rw-r--r--framework/Web/UI/ActiveControls/TActiveControlAdapter.php2
-rw-r--r--framework/Web/UI/ActiveControls/TActiveLabel.php8
-rw-r--r--framework/Web/UI/ActiveControls/TActivePageAdapter.php15
-rw-r--r--framework/Web/UI/ActiveControls/TCallback.php2
-rw-r--r--framework/Web/UI/ActiveControls/TCallbackClientScript.php2
-rw-r--r--framework/Web/UI/ActiveControls/TCallbackClientSideOptions.php114
-rw-r--r--framework/Web/UI/ActiveControls/TCallbackResponse.php15
-rw-r--r--framework/Web/UI/TClientScriptManager.php89
-rw-r--r--framework/Web/UI/TControl.php8
-rw-r--r--framework/Web/UI/TPage.php34
-rw-r--r--framework/Web/UI/TTemplateManager.php2
-rw-r--r--framework/Web/UI/WebControls/TBaseValidator.php73
-rw-r--r--framework/Web/UI/WebControls/TCheckBox.php2
-rw-r--r--framework/Web/UI/WebControls/TValidationSummary.php63
16 files changed, 323 insertions, 280 deletions
diff --git a/framework/Web/Javascripts/js/ajax.js b/framework/Web/Javascripts/js/ajax.js
index 6ab3d18d..5deebd1b 100644
--- a/framework/Web/Javascripts/js/ajax.js
+++ b/framework/Web/Javascripts/js/ajax.js
@@ -23,7 +23,7 @@ setTimeout(this.onComplete.bind(this),10);}}});Ajax.PeriodicalUpdater=Class.crea
this.timer=setTimeout(this.onTimerEvent.bind(this),this.decay*this.frequency*1000);},onTimerEvent:function(){this.updater=new Ajax.Updater(this.container,this.url,this.options);}});Object.extend(Ajax.Request.prototype,{respondToReadyState:function(readyState)
{var event=Ajax.Request.Events[readyState];var transport=this.transport,json=this.getHeaderData(Prado.CallbackRequest.DATA_HEADER);if(event=='Complete')
{try
-{Ajax.Responders.dispatch('on'+transport.status,this,transport,json);Prado.CallbackRequest.dispatchActions(transport,this.getHeaderData(Prado.CallbackRequest.ACTION_HEADER));(this.options['on'+this.transport.status]||this.options['on'+(this.responseIsSuccess()?'Success':'Failure')]||Prototype.emptyFunction)(transport,json);}catch(e){this.dispatchException(e);}
+{Prado.CallbackRequest.updatePageState(this,transport);Ajax.Responders.dispatch('on'+transport.status,this,transport,json);Prado.CallbackRequest.dispatchActions(transport,this.getHeaderData(Prado.CallbackRequest.ACTION_HEADER));(this.options['on'+this.transport.status]||this.options['on'+(this.responseIsSuccess()?'Success':'Failure')]||Prototype.emptyFunction)(transport,json);}catch(e){this.dispatchException(e);}
if((this.header('Content-type')||'').match(/^text\/javascript/i))
this.evalResponse();}
try{(this.options['on'+event]||Prototype.emptyFunction)(transport,json);Ajax.Responders.dispatch('on'+event,this,transport,json);}catch(e){this.dispatchException(e);}
@@ -34,7 +34,7 @@ this.transport.onreadystatechange=Prototype.emptyFunction;},getHeaderData:functi
catch(e)
{if(typeof(json)=="string")
{Logger.info("using json")
-return Prado.CallbackRequest.decode(json);}}}});Prado.CallbackRequest=Class.create();Object.extend(Prado.CallbackRequest,{FIELD_CALLBACK_TARGET:'PRADO_CALLBACK_TARGET',FIELD_CALLBACK_PARAMETER:'PRADO_CALLBACK_PARAMETER',FIELD_CALLBACK_PAGESTATE:'PRADO_PAGESTATE',PostDataLoaders:[],DATA_HEADER:'X-PRADO-DATA',ACTION_HEADER:'X-PRADO-ACTIONS',ERROR_HEADER:'X-PRADO-ERROR',Queque:[],InProgress:[],dispatchActions:function(transport,actions)
+return Prado.CallbackRequest.decode(json);}}}});Prado.CallbackRequest=Class.create();Object.extend(Prado.CallbackRequest,{FIELD_CALLBACK_TARGET:'PRADO_CALLBACK_TARGET',FIELD_CALLBACK_PARAMETER:'PRADO_CALLBACK_PARAMETER',FIELD_CALLBACK_PAGESTATE:'PRADO_PAGESTATE',PostDataLoaders:[],DATA_HEADER:'X-PRADO-DATA',ACTION_HEADER:'X-PRADO-ACTIONS',ERROR_HEADER:'X-PRADO-ERROR',PAGESTATE_HEADER:'X-PRADO-PAGESTATE',requestInProgress:null,dispatchActions:function(transport,actions)
{if(actions&&actions.length>0)
actions.each(this.__run.bind(this,transport));},__run:function(transport,command)
{for(var method in command)
@@ -54,27 +54,29 @@ msg+=e.version+" "+e.time+"\n";return msg;}},encode:function(data)
{return Prado.JSON.stringify(data);},decode:function(data)
{if(typeof(data)=="string"&&data.trim().length>0)
return Prado.JSON.parse(data);else
-return null;},dispatchQuequedRequest:function()
-{requests=Prado.CallbackRequest;if(requests.InProgress.length==0&&requests.Queque.length>0)
-{var item=requests.Queque.pop();item.callback=new Ajax.Request(item.url,item.options);item.callback.callbackID=item.id;item.timeout=setTimeout(function()
-{requests.removeInProgress(item.callback);},item.options.TimeOut);requests.InProgress.push(item);}},removeInProgress:function(request)
-{if(request&&request.callbackID)
-{var stillInProgress=[];requests=Prado.CallbackRequest;requests.InProgress.each(function(item)
-{if(item.callback.callbackID==request.callbackID)
-{item.callback.transport.abort();request.transport.abort();clearTimeout(item.timeout);}
-else
-{stillInProgress.push(item);}})
-requests.InProgress=stillInProgress;}
-requests.dispatchQuequedRequest();}})
-Ajax.Responders.register({onComplete:Prado.CallbackRequest.removeInProgress});Event.OnLoad(function()
+return null;},dispatchPriorityRequest:function(callback)
+{Logger.info("priority request "+callback.id)
+this.abortRequestInProgress();callback.request=new Ajax.Request(callback.url,callback.options);callback.timeout=setTimeout(function()
+{Logger.warn("priority timeout");Prado.CallbackRequest.abortRequestInProgress();},callback.options.RequestTimeOut);this.requestInProgress=callback;Logger.info("dispatched "+this.requestInProgress)},dispatchNormalRequest:function(callback)
+{Logger.info("dispatching normal request");new Ajax.Request(callback.url,callback.options);},abortRequestInProgress:function()
+{inProgress=Prado.CallbackRequest.requestInProgress;if(inProgress)
+{Logger.warn("aborted "+inProgress.id)
+inProgress.request.transport.abort();clearTimeout(inProgress.timeout);Prado.CallbackRequest.requestInProgress=null;}},updatePageState:function(request,transport)
+{pagestate=$(this.FIELD_CALLBACK_PAGESTATE);if(request.options.EnablePageStateUpdate&&request.options.HasPriority&&pagestate)
+{Logger.warn("updating page state");pagestate.value=request.header(this.PAGESTATE_HEADER);}}})
+Ajax.Responders.register({onComplete:function(request)
+{if(request.options.HasPriority)
+Prado.CallbackRequest.abortRequestInProgress();}});Event.OnLoad(function()
{if(typeof Logger!="undefined")
-Ajax.Responders.register(Prado.CallbackRequest.Exception);});Prado.CallbackRequest.prototype={url:window.location.href,options:{TimeOut:30000},id:null,callback:null,initialize:function(id,options)
-{Object.extend(this.options,options||{});this.id=id;var request={postBody:this._getPostData(),parameters:''}
-Object.extend(this.options,request);if(this.options.CausesValidation!=false&&typeof(Prado.Validation)!="undefined")
+Ajax.Responders.register(Prado.CallbackRequest.Exception);});Prado.CallbackRequest.prototype={url:window.location.href,options:{},id:null,request:null,initialize:function(id,options)
+{this.id=id;this.options={RequestTimeOut:30000,EnablePageStateUpdate:true,HasPriority:true,CausesValidation:true,ValidationGroup:null,PostInputs:true,postBody:this._getPostData(),parameters:''}
+Object.extend(this.options,options||{});if(this.options.CausesValidation&&typeof(Prado.Validation)!="undefined")
{var form=this.options.Form||Prado.Validation.getForm();if(Prado.Validation.validate(form,this.options.ValidationGroup,this)==false)
return;}
-Prado.CallbackRequest.Queque.push(this);Prado.CallbackRequest.dispatchQuequedRequest();},_getPostData:function()
-{var data={};var callback=Prado.CallbackRequest;if(this.options.PostState!=false)
+if(this.options.HasPriority)
+Prado.CallbackRequest.dispatchPriorityRequest(this);else
+Prado.CallbackRequest.dispatchNormalRequest(this);},_getPostData:function()
+{var data={};var callback=Prado.CallbackRequest;if(this.options.PostInputs!=false)
{callback.PostDataLoaders.each(function(name)
{$A(document.getElementsByName(name)).each(function(element)
{var value=$F(element);if(typeof(value)!="undefined")
@@ -83,7 +85,7 @@ if(typeof(this.options.params)!="undefined")
data[callback.FIELD_CALLBACK_PARAMETER]=callback.encode(this.options.params);var pageState=$F(callback.FIELD_CALLBACK_PAGESTATE);if(typeof(pageState)!="undefined")
data[callback.FIELD_CALLBACK_PAGESTATE]=pageState;data[callback.FIELD_CALLBACK_TARGET]=this.id;return $H(data).toQueryString();}}
Prado.Callback=function(UniqueID,parameter,onSuccess,options)
-{var callback={'params':parameter||'','onSuccess':onSuccess||Prototype.emptyFunction,'CausesValidation':true};Object.extend(callback,options||{});new Prado.CallbackRequest(UniqueID,callback);return false;}
+{var callback={'params':parameter||'','onSuccess':onSuccess||Prototype.emptyFunction};Object.extend(callback,options||{});new Prado.CallbackRequest(UniqueID,callback);return false;}
Array.prototype.______array='______array';Prado.JSON={org:'http://www.JSON.org',copyright:'(c)2005 JSON.org',license:'http://www.crockford.com/JSON/license.html',stringify:function(arg){var c,i,l,s='',v;switch(typeof arg){case'object':if(arg){if(arg.______array=='______array'){for(i=0;i<arg.length;++i){v=this.stringify(arg[i]);if(s){s+=',';}
s+=v;}
return'['+s+']';}else if(typeof arg.toString!='undefined'){for(i in arg){v=arg[i];if(typeof v!='undefined'&&typeof v!='function'){v=this.stringify(v);if(s){s+=',';}
diff --git a/framework/Web/Javascripts/prado/ajax3.js b/framework/Web/Javascripts/prado/ajax3.js
index 8ea76e10..2caaf553 100644
--- a/framework/Web/Javascripts/prado/ajax3.js
+++ b/framework/Web/Javascripts/prado/ajax3.js
@@ -16,6 +16,7 @@ Object.extend(Ajax.Request.prototype,
{
try
{
+ Prado.CallbackRequest.updatePageState(this,transport);
Ajax.Responders.dispatch('on' + transport.status, this, transport, json);
Prado.CallbackRequest.dispatchActions(transport,this.getHeaderData(Prado.CallbackRequest.ACTION_HEADER));
@@ -104,13 +105,13 @@ Object.extend(Prado.CallbackRequest,
*/
ERROR_HEADER : 'X-PRADO-ERROR',
/**
- * Callback request queque.
+ * Page state header name.
*/
- Queque : [],
+ PAGESTATE_HEADER : 'X-PRADO-PAGESTATE',
/**
- * Requests In progress.
+ * Current requests in progress.
*/
- InProgress : [],
+ requestInProgress : null,
/**
* Dispatch callback response actions.
@@ -223,53 +224,71 @@ Object.extend(Prado.CallbackRequest,
},
/**
- * Dispatch quequed requests, and set a timeout.
+ * Dispatch a priority request, it will call abortRequestInProgress first.
*/
- dispatchQuequedRequest : function()
+ dispatchPriorityRequest : function(callback)
{
- requests = Prado.CallbackRequest;
- if(requests.InProgress.length == 0 && requests.Queque.length > 0)
+ Logger.info("priority request "+callback.id)
+ this.abortRequestInProgress();
+
+ callback.request = new Ajax.Request(callback.url, callback.options);
+ callback.timeout = setTimeout(function()
{
- var item = requests.Queque.pop();
- item.callback = new Ajax.Request(item.url, item.options);
- item.callback.callbackID = item.id;
- item.timeout = setTimeout(function()
- {
- requests.removeInProgress(item.callback);
- }, item.options.TimeOut);
- requests.InProgress.push(item);
+ Logger.warn("priority timeout");
+ Prado.CallbackRequest.abortRequestInProgress();
+ },callback.options.RequestTimeOut);
+
+ this.requestInProgress = callback;
+ Logger.info("dispatched "+this.requestInProgress)
+ },
+
+ /**
+ * Dispatch a normal request, no timeouts or aborting of requests.
+ */
+ dispatchNormalRequest : function(callback)
+ {
+ Logger.info("dispatching normal request");
+ new Ajax.Request(callback.url, callback.options);
+ },
+
+ /**
+ * Abort the current priority request in progress.
+ */
+ abortRequestInProgress : function()
+ {
+ inProgress = Prado.CallbackRequest.requestInProgress;
+ if(inProgress)
+ {
+ Logger.warn("aborted "+inProgress.id)
+ inProgress.request.transport.abort();
+ clearTimeout(inProgress.timeout);
+ Prado.CallbackRequest.requestInProgress = null;
}
},
/**
- * Remove a request currently in progress and call dispatchQuequedRequest.
+ * Updates the page state. It will update only if EnablePageStateUpdate and
+ * HasPriority options are both true.
*/
- removeInProgress : function(request)
+ updatePageState : function(request, transport)
{
- if(request && request.callbackID)
+ pagestate = $(this.FIELD_CALLBACK_PAGESTATE);
+ if(request.options.EnablePageStateUpdate && request.options.HasPriority && pagestate)
{
- var stillInProgress = [];
- requests = Prado.CallbackRequest;
- requests.InProgress.each(function(item)
- {
- if(item.callback.callbackID == request.callbackID)
- {
- item.callback.transport.abort();
- request.transport.abort();
- clearTimeout(item.timeout);
- }
- else
- {
- stillInProgress.push(item);
- }
- })
- requests.InProgress = stillInProgress;
+ Logger.warn("updating page state");
+ pagestate.value = request.header(this.PAGESTATE_HEADER);
}
- requests.dispatchQuequedRequest();
}
})
-Ajax.Responders.register({onComplete : Prado.CallbackRequest.removeInProgress});
+/**
+ * Automatically aborts the current request when a priority request has returned.
+ */
+Ajax.Responders.register({onComplete : function(request)
+{
+ if(request.options.HasPriority)
+ Prado.CallbackRequest.abortRequestInProgress();
+}});
//Add HTTP exception respones when logger is enabled.
Event.OnLoad(function()
@@ -291,10 +310,7 @@ Prado.CallbackRequest.prototype =
/**
* Callback options, including onXXX events.
*/
- options :
- {
- TimeOut : 30000 // 30 second timeout.
- },
+ options : { },
/**
* Callback target ID. E.g. $control->getUniqueID();
@@ -304,34 +320,39 @@ Prado.CallbackRequest.prototype =
/**
* Current callback request.
*/
- callback : null,
+ request : null,
/**
* Prepare and inititate a callback request.
*/
initialize : function(id, options)
{
- Object.extend(this.options, options || {});
-
this.id = id;
-
- var request =
+
+ this.options =
{
+ RequestTimeOut : 30000, // 30 second timeout.
+ EnablePageStateUpdate : true,
+ HasPriority : true,
+ CausesValidation : true,
+ ValidationGroup : null,
+ PostInputs : true,
postBody : this._getPostData(),
parameters : ''
}
-
- Object.extend(this.options, request);
-
- if(this.options.CausesValidation != false && typeof(Prado.Validation) != "undefined")
+ Object.extend(this.options, options || {});
+
+ if(this.options.CausesValidation && typeof(Prado.Validation) != "undefined")
{
var form = this.options.Form || Prado.Validation.getForm();
if(Prado.Validation.validate(form,this.options.ValidationGroup,this) == false)
return;
}
- Prado.CallbackRequest.Queque.push(this);
- Prado.CallbackRequest.dispatchQuequedRequest();
+ if(this.options.HasPriority)
+ Prado.CallbackRequest.dispatchPriorityRequest(this);
+ else
+ Prado.CallbackRequest.dispatchNormalRequest(this);
},
/**
@@ -343,7 +364,7 @@ Prado.CallbackRequest.prototype =
{
var data = {};
var callback = Prado.CallbackRequest;
- if(this.options.PostState != false)
+ if(this.options.PostInputs != false)
{
callback.PostDataLoaders.each(function(name)
{
@@ -378,8 +399,7 @@ Prado.Callback = function(UniqueID, parameter, onSuccess, options)
var callback =
{
'params' : parameter || '',
- 'onSuccess' : onSuccess || Prototype.emptyFunction,
- 'CausesValidation' : true
+ 'onSuccess' : onSuccess || Prototype.emptyFunction
};
Object.extend(callback, options || {});
diff --git a/framework/Web/UI/ActiveControls/TActiveControlAdapter.php b/framework/Web/UI/ActiveControls/TActiveControlAdapter.php
index b95bdd37..77973b2c 100644
--- a/framework/Web/UI/ActiveControls/TActiveControlAdapter.php
+++ b/framework/Web/UI/ActiveControls/TActiveControlAdapter.php
@@ -22,4 +22,4 @@ class TActiveControlAdapter extends TControlAdapter
parent::render($writer);
}
}
-?>
+?> \ No newline at end of file
diff --git a/framework/Web/UI/ActiveControls/TActiveLabel.php b/framework/Web/UI/ActiveControls/TActiveLabel.php
index d71d8b7a..3216be43 100644
--- a/framework/Web/UI/ActiveControls/TActiveLabel.php
+++ b/framework/Web/UI/ActiveControls/TActiveLabel.php
@@ -29,7 +29,7 @@ class TActiveLabel extends TLabel
/**
* Creates a new callback control, sets the adapter to
* TActiveControlAdapter. If you override this class, be sure to set the
- * adapter appropriately by, for example, call this constructor.
+ * adapter appropriately by, for example, by calling this constructor.
*/
public function __construct()
{
@@ -44,7 +44,7 @@ class TActiveLabel extends TLabel
public function setText($value)
{
parent::setText($value);
- if($this->getPage()->getAllowCallbackUpdate())
+ if($this->getIsInitialized())
{
$this->getPage()->getCallbackClient()->update($this, $value);
}
@@ -59,7 +59,7 @@ class TActiveLabel extends TLabel
public function setForControl($value)
{
parent::setForControl($value);
- if($this->getPage()->getAllowCallbackUpdate())
+ if($this->getIsInitialized())
{
$id=$this->findControl($value)->getClientID();
$this->getPage()->getCallbackClient()->setAttribute($this, 'for', $id);
@@ -67,4 +67,4 @@ class TActiveLabel extends TLabel
}
}
-?>
+?> \ No newline at end of file
diff --git a/framework/Web/UI/ActiveControls/TActivePageAdapter.php b/framework/Web/UI/ActiveControls/TActivePageAdapter.php
index db783a12..67720afd 100644
--- a/framework/Web/UI/ActiveControls/TActivePageAdapter.php
+++ b/framework/Web/UI/ActiveControls/TActivePageAdapter.php
@@ -25,6 +25,7 @@ class TActivePageAdapter extends TControlAdapter
const CALLBACK_DATA_HEADER = 'X-PRADO-DATA';
const CALLBACK_ACTION_HEADER = 'X-PRADO-ACTIONS';
const CALLBACK_ERROR_HEADER = 'X-PRADO-ERROR';
+ const CALLBACK_PAGESTATE_HEADER = 'X-PRADO-PAGESTATE';
/**
* @var ICallbackEventHandler callback event handler.
@@ -80,7 +81,7 @@ class TActivePageAdapter extends TControlAdapter
/**
* Renders the callback response by adding additional callback data and
- * javascript actions in the header.
+ * javascript actions in the header and page state if required.
*/
protected function renderResponse($writer)
{
@@ -92,7 +93,15 @@ class TActivePageAdapter extends TControlAdapter
{
$data = TJavascript::jsonEncode($this->_result->getData());
$response->appendHeader(self::CALLBACK_DATA_HEADER.': '.$data);
- }
+ }
+ if(($handler = $this->getCallbackEventTarget()) !== null)
+ {
+ if($handler->getClientSide()->getEnablePageStateUpdate())
+ {
+ $pagestate = $this->getPage()->getClientState();
+ $response->appendHeader(self::CALLBACK_PAGESTATE_HEADER.': '.$pagestate);
+ }
+ }
}
/**
@@ -329,4 +338,4 @@ class TInvalidCallbackRequestException extends TException
{
}
-?>
+?> \ No newline at end of file
diff --git a/framework/Web/UI/ActiveControls/TCallback.php b/framework/Web/UI/ActiveControls/TCallback.php
index 9c3234fd..9d2301d8 100644
--- a/framework/Web/UI/ActiveControls/TCallback.php
+++ b/framework/Web/UI/ActiveControls/TCallback.php
@@ -147,4 +147,4 @@ class TCallback extends TControl implements ICallbackEventHandler
}
}
-?>
+?> \ No newline at end of file
diff --git a/framework/Web/UI/ActiveControls/TCallbackClientScript.php b/framework/Web/UI/ActiveControls/TCallbackClientScript.php
index 5f8851db..5d317c8a 100644
--- a/framework/Web/UI/ActiveControls/TCallbackClientScript.php
+++ b/framework/Web/UI/ActiveControls/TCallbackClientScript.php
@@ -531,4 +531,4 @@ class TCallbackClientScript extends TApplicationComponent
}
}
-?>
+?> \ No newline at end of file
diff --git a/framework/Web/UI/ActiveControls/TCallbackClientSideOptions.php b/framework/Web/UI/ActiveControls/TCallbackClientSideOptions.php
index 6a4731f7..c0a817f0 100644
--- a/framework/Web/UI/ActiveControls/TCallbackClientSideOptions.php
+++ b/framework/Web/UI/ActiveControls/TCallbackClientSideOptions.php
@@ -1,37 +1,4 @@
<?php
-/*
- * Created on 1/05/2006
- */
-
-class TClientSideOptions extends TComponent
-{
- private $_options;
-
- public function __construct()
- {
- $this->_options = Prado::createComponent('System.Collections.TMap');
- }
-
- protected function setFunction($name, $code)
- {
- $this->_options->add($name, $this->ensureFunction($code));
- }
-
- protected function getOption($name)
- {
- return $this->_options->itemAt($name);
- }
-
- public function getOptions()
- {
- return $this->_options;
- }
-
- protected function ensureFunction($javascript)
- {
- return $javascript;
- }
-}
/**
* TCallbackClientSideOptions class.
@@ -54,6 +21,15 @@ class TClientSideOptions extends TComponent
* - <b>onException</b> raised when callback request fails due to
* request/response errors.
*
+ * - <b>PostInputs</b> true to collect the form inputs and post them during
+ * callback, default is true.
+ * - <b>RequestTimeOut</b> The request timeout in milliseconds.
+ * - <b>HasPriority</b> true to ensure that the callback request will be sent
+ * immediately and will abort existing prioritized requests. It does not affect
+ * callbacks that are not prioritized.
+ * - <b>EnablePageStateUpdate</b> enable the callback response to enable the
+ * viewstate update. This will automatically set HasPrority to true when
+ * enabled.
*/
class TCallbackClientSideOptions extends TClientSideOptions
{
@@ -65,13 +41,7 @@ class TCallbackClientSideOptions extends TClientSideOptions
*/
protected function ensureFunction($javascript)
{
- if(TJavascript::isFunction($javascript))
- return $javascript;
- else
- {
- $code = "function(request, result){ {$javascript} }";
- return TJavascript::quoteFunction($code);
- }
+ return "function(request, result){ {$javascript} }";
}
/**
@@ -200,21 +170,21 @@ class TCallbackClientSideOptions extends TClientSideOptions
}
/**
- * @return boolean true to post the state on callback, default is post the
- * state on callback.
+ * @return boolean true to post the inputs of the form on callback, default
+ * is post the inputs on callback.
*/
public function getPostState()
{
- return $this->getOption('PostState');
+ return $this->getOption('PostInputs');
}
/**
- * @param boolean true to post the state of the form with callback requests.
- * Default is to post the state.
+ * @param boolean true to post the inputs of the form with callback
+ * requests. Default is to post the inputs.
*/
public function setPostState($value)
{
- $this->getOptions()->add('PostState', TPropertyValue::ensureBoolean($value));
+ $this->setOption('PostInputs', TPropertyValue::ensureBoolean($value));
}
/**
@@ -222,7 +192,7 @@ class TCallbackClientSideOptions extends TClientSideOptions
*/
public function getRequestTimeOut()
{
- return $this->getOption('TimeOut');
+ return $this->getOption('RequestTimeOut');
}
/**
@@ -230,8 +200,54 @@ class TCallbackClientSideOptions extends TClientSideOptions
*/
public function setRequestTimeOut($value)
{
- $this->getOptions()->add('TimeOut', TPropertyValue::ensureInteger($value));
+ $this->setOption('RequestTimeOut', TPropertyValue::ensureInteger($value));
+ }
+
+ /**
+ * @return boolean true if the callback request has priority and will abort
+ * existing prioritized request in order to send immediately. It does not
+ * affect callbacks that are not prioritized.
+ */
+ public function getHasPriority()
+ {
+ return $this->getOption('HasPriority');
+ }
+
+ /**
+ * @param boolean true to ensure that the callback request will be sent
+ * immediately and will abort existing prioritized requests. It does not
+ * affect callbacks that are not prioritized.
+ */
+ public function setHasPriority($value)
+ {
+ $hasPriority = TPropertyValue::ensureBoolean($value);
+ $this->setOption('HasPriority', $hasPriority);
+ if(!$hasPriority)
+ $this->setEnablePageStateUpdate(false);
+ }
+
+ /**
+ * Set to true to enable the callback response to enable the viewstate
+ * update. This will automatically set HasPrority to true.
+ * @param boolean true enables the callback response to update the
+ * viewstate.
+ */
+ public function setEnablePageStateUpdate($value)
+ {
+ $enabled = TPropertyValue::ensureBoolean($value);
+ $this->setOption('EnablePageStateUpdate', $enabled);
+ if($enabled)
+ $this->setHasPriority(true);
+ }
+
+ /**
+ * @return boolean client-side viewstate will be updated on callback
+ * response if true.
+ */
+ public function getEnablePageStateUpdate()
+ {
+ return $this->getOption('EnablePageStateUpdate');
}
}
-?>
+?> \ No newline at end of file
diff --git a/framework/Web/UI/ActiveControls/TCallbackResponse.php b/framework/Web/UI/ActiveControls/TCallbackResponse.php
index 4a893b9a..024ad6ef 100644
--- a/framework/Web/UI/ActiveControls/TCallbackResponse.php
+++ b/framework/Web/UI/ActiveControls/TCallbackResponse.php
@@ -1,14 +1,8 @@
<?php
-/*
- * Created on 29/04/2006
- */
-
-// See TActivePageAdapter::renderResponse()
-//TODO: How to render the response, it will contain 3 pieces of data
-// 1) The arbituary data returned to the client-side callback handler
-// 2) client-side function call statements
-// 3) Content body, which may need to be partitioned
+/**
+ *
+ */
class TCallbackResponse extends THttpResponse
{
private $_writers=array();
@@ -57,4 +51,5 @@ class TCallbackResponseWriter extends TTextWriter
return $content;
}
}
-?>
+
+?> \ No newline at end of file
diff --git a/framework/Web/UI/TClientScriptManager.php b/framework/Web/UI/TClientScriptManager.php
index 46203b0b..20612ce2 100644
--- a/framework/Web/UI/TClientScriptManager.php
+++ b/framework/Web/UI/TClientScriptManager.php
@@ -1,6 +1,6 @@
<?php
/**
- * TClientScriptManager class file
+ * TClientScriptManager and TClientSideOptions class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.pradosoft.com/
@@ -164,15 +164,12 @@ class TClientScriptManager extends TApplicationComponent
}
}
- public function getCallbackReference($callbackHandler, $options=null)
+ public function getCallbackReference(ICallbackEventHandler $callbackHandler, $options=null)
{
$options = !is_array($options) ? array() : $options;
$class = new TReflectionClass($callbackHandler);
- if($class->hasMethod('getClientSide'))
- {
- $clientSide = $callbackHandler->getClientSide();
- $options = array_merge($options, $clientSide->getOptions()->toArray());
- }
+ $clientSide = $callbackHandler->getClientSide();
+ $options = array_merge($options, $clientSide->getOptions()->toArray());
$optionString = TJavascript::encode($options);
$this->registerPradoScriptInternal('ajax');
$id = $callbackHandler->getUniqueID();
@@ -532,4 +529,82 @@ class TClientScriptManager extends TApplicationComponent
}
}
+/**
+ * TClientSideOptions abstract class.
+ *
+ * TClientSideOptions manages client-side options for components that have
+ * common client-side javascript behaviours and client-side events such as
+ * between ActiveControls and validators.
+ *
+ * @author <weizhuo[at]gmail[dot]com>
+ * @version $Revision: $ $Date: $
+ * @package System.Web.UI
+ * @since 3.0
+ */
+abstract class TClientSideOptions extends TComponent
+{
+ /**
+ * @var TMap list of client-side options.
+ */
+ private $_options;
+
+ /**
+ * Constructor, initialize the options list.
+ */
+ public function __construct()
+ {
+ $this->_options = Prado::createComponent('System.Collections.TMap');
+ }
+
+ /**
+ * Adds on client-side event handler by wrapping the code within a
+ * javascript function block. If the code begins with "javascript:", the
+ * code is assumed to be a javascript function block rather than arbiturary
+ * javascript statements.
+ * @param string option name
+ * @param string javascript statements.
+ */
+ protected function setFunction($name, $code)
+ {
+ if(!TJavascript::isFunction($code))
+ $code = TJavascript::quoteFunction($this->ensureFunction($code));
+ $this->setOption($name, $code);
+ }
+
+ /**
+ * @return string gets a particular option, null if not set.
+ */
+ protected function getOption($name)
+ {
+ return $this->_options->itemAt($name);
+ }
+
+ /**
+ * @param string option name
+ * @param mixed option value.
+ */
+ protected function setOption($name, $value)
+ {
+ $this->_options->add($name, $value);
+ }
+
+ /**
+ * @return TMap gets the list of options as TMap
+ */
+ public function getOptions()
+ {
+ return $this->_options;
+ }
+
+ /**
+ * Ensure that the javascript statements are wrapped in a javascript
+ * function block. Default has no wrapping. Override this method to
+ * customize the wrapping javascript function block.
+ */
+ protected function ensureFunction($javascript)
+ {
+ return $javascript;
+ }
+}
+
?> \ No newline at end of file
diff --git a/framework/Web/UI/TControl.php b/framework/Web/UI/TControl.php
index 860b6baf..3bb893e2 100644
--- a/framework/Web/UI/TControl.php
+++ b/framework/Web/UI/TControl.php
@@ -997,6 +997,14 @@ class TControl extends TApplicationComponent implements IRenderable, IBindable
{
return isset($this->_rf[self::RF_NAMED_OBJECTS][$name]);
}
+
+ /**
+ * @return boolean true if the control has been initialized.
+ */
+ public function getIsInitialized()
+ {
+ return $this->getControlStage() >= self::CS_CHILD_INITIALIZED;
+ }
/**
* Returns the named registered object.
diff --git a/framework/Web/UI/TPage.php b/framework/Web/UI/TPage.php
index 11ebc1dd..008b7c83 100644
--- a/framework/Web/UI/TPage.php
+++ b/framework/Web/UI/TPage.php
@@ -153,12 +153,7 @@ class TPage extends TTemplateControl
* @var array post data loader IDs.
*/
private $_postDataLoaders=array();
- /**
- * @var boolean true if callback request is allowed to update the client-
- * side contents during callback response.
- */
- private $_allowCallbackUpdate=false;
-
+
/**
* Constructor.
* Sets the page object to itself.
@@ -282,8 +277,6 @@ class TPage extends TTemplateControl
Prado::trace("Page initRecursive()",'System.Web.UI.TPage');
$this->initRecursive();
- $this->setAllowCallbackUpdate(true);
-
Prado::trace("Page onInitComplete()",'System.Web.UI.TPage');
$this->onInitComplete(null);
@@ -316,11 +309,12 @@ class TPage extends TTemplateControl
Prado::trace("Page onPreRenderComplete()",'System.Web.UI.TPage');
$this->onPreRenderComplete(null);
-/* Prado::trace("Page savePageState()",'System.Web.UI.TPage');
+ Prado::trace("Page savePageState()",'System.Web.UI.TPage');
$this->savePageState();
Prado::trace("Page onSaveStateComplete()",'System.Web.UI.TPage');
$this->onSaveStateComplete(null);
+/*
Prado::trace("Page renderControl()",'System.Web.UI.TPage');
$this->renderControl($writer);
*/
@@ -331,28 +325,6 @@ class TPage extends TTemplateControl
}
/**
- * Returns true if callback request is allowed to update the client- side
- * contents during callback response. Default is true if {@link
- * getIsCallback IsCallback} is true and onInit stage has been completed.
- * @return boolean true to allow client-side update.
- */
- public function getAllowCallbackUpdate()
- {
- return $this->_allowCallbackUpdate;
- }
-
- /**
- * Set to true to allow callback request to update client-side content
- * during callback response. Default is true if {@link getIsCallback
- * IsCallback} is true and onInit stage has been completed.
- * @param boolean true to allow callback to update client-side content.
- */
- public function setAllowCallbackUpdate($value)
- {
- $this->_allowCallbackUpdate = TPropertyValue::ensureBoolean($value);
- }
-
- /**
* Gets the callback client script handler that allows javascript functions
* to be executed during the callback response.
* @return TCallbackClientScript interface to client-side javascript code.
diff --git a/framework/Web/UI/TTemplateManager.php b/framework/Web/UI/TTemplateManager.php
index 36562b1b..27bd0ac6 100644
--- a/framework/Web/UI/TTemplateManager.php
+++ b/framework/Web/UI/TTemplateManager.php
@@ -883,4 +883,4 @@ class TTemplate extends TApplicationComponent implements ITemplate
}
}
-?>
+?> \ No newline at end of file
diff --git a/framework/Web/UI/WebControls/TBaseValidator.php b/framework/Web/UI/WebControls/TBaseValidator.php
index ea1a5836..c39db85a 100644
--- a/framework/Web/UI/WebControls/TBaseValidator.php
+++ b/framework/Web/UI/WebControls/TBaseValidator.php
@@ -80,9 +80,9 @@ abstract class TBaseValidator extends TLabel implements IValidator
*/
private $_registered=false;
/**
- * @var TValidatorClientScript validator client-script options.
+ * @var TClientSideValidatorOptions validator client-script options.
*/
- private $_clientScript;
+ private $_clientSide;
/**
* Constructor.
@@ -154,14 +154,14 @@ abstract class TBaseValidator extends TLabel implements IValidator
$options['ControlCssClass'] = $this->getControlCssClass();
$options['ControlType'] = get_class($control);
- if(!is_null($this->_clientScript))
- $options = array_merge($options,$this->_clientScript->getOptions());
+ if(!is_null($this->_clientSide))
+ $options = array_merge($options,$this->_clientSide->getOptions()->toArray());
return $options;
}
/**
- * Gets the TValidatorClientScript that allows modification of the client-
+ * Gets the TClientSideValidatorOptions that allows modification of the client-
* side validator events.
*
* The client-side validator supports the following events.
@@ -174,21 +174,21 @@ abstract class TBaseValidator extends TLabel implements IValidator
*
* You can attach custom javascript code to each of these events
*
- * @return TValidatorClientScript javascript validator event options.
+ * @return TClientSideValidatorOptions javascript validator event options.
*/
public function getClientSide()
{
- if(is_null($this->_clientScript))
- $this->_clientScript = $this->createClientScript();
- return $this->_clientScript;
+ if(is_null($this->_clientSide))
+ $this->_clientSide = $this->createClientSideOptions();
+ return $this->_clientSide;
}
/**
- * @return TValidatorClientScript javascript validator event options.
+ * @return TClientSideValidatorOptions javascript validator event options.
*/
- protected function createClientScript()
+ protected function createClientSideOptions()
{
- return new TValidatorClientScript;
+ return new TClientSideValidatorOptions;
}
/**
@@ -491,11 +491,11 @@ abstract class TBaseValidator extends TLabel implements IValidator
}
/**
- * TValidatorClientScript class.
+ * TClientSideValidatorOptions class.
*
* Client-side validator events can be modified through the {@link
* TBaseValidator::getClientSide ClientSide} property of a validator. The
- * subproperties of ClientSide are those of the TValidatorClientScript
+ * subproperties of ClientSide are those of the TClientSideValidatorOptions
* properties. The client-side validator supports the following events.
*
* The <tt>OnValidate</tt> event is raise before the validator validation
@@ -513,27 +513,14 @@ abstract class TBaseValidator extends TLabel implements IValidator
* @package System.Web.UI.WebControls
* @since 3.0
*/
-class TValidatorClientScript extends TComponent
+class TClientSideValidatorOptions extends TClientSideOptions
{
/**
- * @var TMap client-side validator event javascript code.
- */
- private $_options;
-
- /**
- * Constructor.
- */
- public function __construct()
- {
- $this->_options = new TMap;
- }
-
- /**
* @return string javascript code for client-side OnValidate event.
*/
public function getOnValidate()
{
- return $this->_options->itemAt['OnValidate'];
+ return $this->getOption('OnValidate');
}
/**
@@ -543,7 +530,7 @@ class TValidatorClientScript extends TComponent
*/
public function setOnValidate($javascript)
{
- $this->_options->add('OnValidate', $this->ensureFunction($javascript));
+ $this->setFunction('OnValidate', $javascript);
}
/**
@@ -553,7 +540,7 @@ class TValidatorClientScript extends TComponent
*/
public function setOnSuccess($javascript)
{
- $this->_options->add('OnSuccess', $this->ensureFunction($javascript));
+ $this->setFunction('OnSuccess', $javascript);
}
/**
@@ -561,7 +548,7 @@ class TValidatorClientScript extends TComponent
*/
public function getOnSuccess()
{
- return $this->_options->itemAt('OnSuccess');
+ return $this->getOption('OnSuccess');
}
/**
@@ -571,7 +558,7 @@ class TValidatorClientScript extends TComponent
*/
public function setOnError($javascript)
{
- $this->_options->add('OnError', $this->ensureFunction($javascript));
+ $this->setFunction('OnError', $javascript);
}
/**
@@ -579,15 +566,7 @@ class TValidatorClientScript extends TComponent
*/
public function getOnError()
{
- return $this->_options->itemAt('OnError');
- }
-
- /**
- * @return array list of client-side event code.
- */
- public function getOptions()
- {
- return $this->_options->toArray();
+ return $this->getOption('OnError');
}
/**
@@ -597,15 +576,9 @@ class TValidatorClientScript extends TComponent
* @param string javascript code.
* @return string javascript function code.
*/
- private function ensureFunction($javascript)
+ protected function ensureFunction($javascript)
{
- if(TJavascript::isFunction($javascript))
- return $javascript;
- else
- {
- $code = "function(validator, sender){ {$javascript} }";
- return TJavascript::quoteFunction($code);
- }
+ return "function(validator, sender){ {$javascript} }";
}
}
diff --git a/framework/Web/UI/WebControls/TCheckBox.php b/framework/Web/UI/WebControls/TCheckBox.php
index 681c8748..da389948 100644
--- a/framework/Web/UI/WebControls/TCheckBox.php
+++ b/framework/Web/UI/WebControls/TCheckBox.php
@@ -378,4 +378,4 @@ class TCheckBox extends TWebControl implements IPostBackDataHandler, IValidatabl
}
-?>
+?> \ No newline at end of file
diff --git a/framework/Web/UI/WebControls/TValidationSummary.php b/framework/Web/UI/WebControls/TValidationSummary.php
index 87821292..8148036b 100644
--- a/framework/Web/UI/WebControls/TValidationSummary.php
+++ b/framework/Web/UI/WebControls/TValidationSummary.php
@@ -37,9 +37,9 @@
class TValidationSummary extends TWebControl
{
/**
- * @var TValidatorClientScript validator client-script options.
+ * @var TClientSideValidationSummaryOptions validation client side options.
*/
- private $_clientScript;
+ private $_clientSide;
/**
* Constructor.
@@ -248,30 +248,30 @@ class TValidationSummary extends TWebControl
$options['ValidationGroup'] = $this->getValidationGroup();
$options['Display'] = $this->getDisplay();
- if(!is_null($this->_clientScript))
- $options = array_merge($options,$this->_clientScript->getOptions());
+ if(!is_null($this->_clientSide))
+ $options = array_merge($options,$this->_clientSide->getOptions()->toArray());
return $options;
}
/**
- * @return TValidationSummaryClientScript client-side validation summary
+ * @return TClientSideValidationSummaryOptions client-side validation summary
* event options.
*/
public function getClientSide()
{
- if(is_null($this->_clientScript))
- $this->_clientScript = $this->createClientScript();
- return $this->_clientScript;
+ if(is_null($this->_clientSide))
+ $this->_clientSide = $this->createClientScript();
+ return $this->_clientSide;
}
/**
- * @return TValidationSummaryClientScript javascript validation summary
+ * @return TClientSideValidationSummaryOptions javascript validation summary
* event options.
*/
protected function createClientScript()
{
- return new TValidationSummaryClientScript;
+ return new TClientSideValidationSummaryOptions;
}
/**
* Get the list of validation error messages.
@@ -372,7 +372,7 @@ class TValidationSummary extends TWebControl
}
/**
- * TValidationSummaryClientScript class.
+ * TClientSideValidationSummaryOptions class.
*
* Client-side validation summary events such as {@link setOnHideSummary
* OnHideSummary} and {@link setOnShowSummary OnShowSummary} can be modified
@@ -392,27 +392,14 @@ class TValidationSummary extends TWebControl
* @package System.Web.UI.WebControls
* @since 3.0
*/
-class TValidationSummaryClientScript extends TComponent
+class TClientSideValidationSummaryOptions extends TClientSideOptions
{
/**
- * @var TMap client-side validation summary event javascript code.
- */
- private $_options;
-
- /**
- * Constructor.
- */
- public function __construct()
- {
- $this->_options = new TMap;
- }
-
- /**
* @return string javascript code for client-side OnHideSummary event.
*/
public function getOnHideSummary()
{
- return $this->_options->itemAt['OnHideSummary'];
+ return $this->getOption('OnHideSummary');
}
/**
@@ -423,7 +410,7 @@ class TValidationSummaryClientScript extends TComponent
*/
public function setOnHideSummary($javascript)
{
- $this->_options->add('OnHideSummary', $this->ensureFunction($javascript));
+ $this->setFunction('OnHideSummary', $javascript);
}
/**
@@ -434,7 +421,7 @@ class TValidationSummaryClientScript extends TComponent
*/
public function setOnShowSummary($javascript)
{
- $this->_options->add('OnShowSummary', $this->ensureFunction($javascript));
+ $this->setFunction('OnShowSummary', $javascript);
}
/**
@@ -442,15 +429,7 @@ class TValidationSummaryClientScript extends TComponent
*/
public function getOnShowSummary()
{
- return $this->_options->itemAt('OnShowSummary');
- }
-
- /**
- * @return array list of client-side event code.
- */
- public function getOptions()
- {
- return $this->_options->toArray();
+ return $this->getOption('OnShowSummary');
}
/**
@@ -460,15 +439,9 @@ class TValidationSummaryClientScript extends TComponent
* @param string javascript code.
* @return string javascript function code.
*/
- private function ensureFunction($javascript)
+ protected function ensureFunction($javascript)
{
- if(TJavascript::isFunction($javascript))
- return $javascript;
- else
- {
- $code = "function(summary, validators){ {$javascript} }";
- return TJavascript::quoteFunction($code);
- }
+ return "function(summary, validators){ {$javascript} }";
}
}