summaryrefslogtreecommitdiff
path: root/framework/Web/UI/ActiveControls/TBaseActiveCallbackControl.php
blob: ffe00098a63db548f062d210d4fe67bc08517ab9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
<?php
/**
 * TBaseActiveControl and TBaseActiveCallbackControl class file.
 *
 * @author Wei Zhuo <weizhuo[at]gamil[dot]com>
 * @link http://www.pradosoft.com/
 * @copyright Copyright &copy; 2005-2014 PradoSoft
 * @license http://www.pradosoft.com/license/
 * @package Prado\Web\UI\ActiveControls
 */

namespace Prado\Web\UI\ActiveControls;
use Prado\Exceptions\TConfigurationException;
use Prado\TPropertyValue;
use Prado\Web\Javascripts\TJavaScript;

/**
 * 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 sets the validation group property of a TCallback component.
 * <code>
 * 	<com:TCallback ActiveControl.ValidationGroup="group1" ... />
 * </code>
 *
 * Additional client-side options and events can be set using the
 * {@link getClientSide ClientSide} property. The following example shows
 * an alert box when a TCallback component response returns successfully.
 * <code>
 * 	<com:TCallback ActiveControl.ClientSide.OnSuccess="alert('ok!')" ... />
 * </code>
 *
 * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
 * @package Prado\Web\UI\ActiveControls
 * @since 3.1
 */
class TBaseActiveCallbackControl extends TBaseActiveControl
{
	/**
	 * Callback client-side options can be set by setting the properties of
	 * the ClientSide property. E.g. <com:TCallback ActiveControl.ClientSide.OnSuccess="..." />
	 * See {@link TCallbackClientSide} for details on the properties of ClientSide.
	 * @return TCallbackClientSide client-side callback options.
	 */
	public function getClientSide()
	{
		if(($client = $this->getOption('ClientSide'))===null)
		{
			$client = $this->createClientSide();
			$this->setOption('ClientSide', $client);
		}
		return $client;
	}

	/**
	 * Sets the client side options. Can only be set when client side is null.
	 * @param TCallbackClientSide client side options.
	 */
	public function setClientSide($client)
	{
		if( $this->getOption('ClientSide')===null)
			$this->setOption('ClientSide', $client);
		else
			throw new TConfigurationException(
				'active_controls_client_side_exists', $this->getControl()->getID());
	}

	/**
	 * @return TCallbackClientSide callback client-side options.
	 */
	protected function createClientSide()
	{
		return new TCallbackClientSide;
	}

	/**
	 * Sets default callback options. Takes the ID of a TCallbackOptions
	 * component to duplicate the client-side
	 * options for this control. The {@link getClientSide ClientSide}
	 * subproperties takes precedence over the CallbackOptions property.
	 * @param string ID of a TCallbackOptions control from which ClientSide
	 * options are cloned.
	 */
	public function setCallbackOptions($value)
	{
		$this->setOption('CallbackOptions', $value, '');
	}

	/**
	 * @return string ID of a TCallbackOptions control from which ClientSide
	 * options are duplicated.
	 */
	public function getCallbackOptions()
	{
		return $this->getOption('CallbackOptions', '');
	}

	/**
	 * Returns an array of default callback client-side options. The default options
	 * are obtained from the client-side options of a TCallbackOptions control with
	 * ID specified by {@link setCallbackOptions CallbackOptions}.
	 * @return array list of default callback client-side options.
	 */
	protected function getDefaultClientSideOptions()
	{
		if(($id=$this->getCallbackOptions())!=='')
		{
			if(($pos=strrpos($id,'.'))!==false)
			{
				$control=$this->getControl()->getSubProperty(substr($id,0,$pos));
				$newid=substr($id,$pos+1);
				if ($control!==null)
					$control=$control->$newid;
			}
			else
			{
				// TCheckBoxList overrides findControl() with a fake implementation
				// but accepts a second parameter to use the standard one
				$control=$this->getControl()->findControl($id, true);
			}

			if($control instanceof TCallbackOptions)
				return $control->getClientSide()->getOptions()->toArray();
			else
				throw new TConfigurationException('callback_invalid_callback_options', $this->getControl()->getID(), $id);
		}

		return array();
	}

	/**
	 * @return boolean whether callback event trigger by this button will cause
	 * input validation, default is true
	 */
	public function getCausesValidation()
	{
		return $this->getOption('CausesValidation',true);
	}

	/**
	 * @param boolean whether callback event trigger by this button will cause
	 * input validation
	 */
	public function setCausesValidation($value)
	{
		$this->setOption('CausesValidation',TPropertyValue::ensureBoolean($value),true);
	}

	/**
	 * @return string the group of validators which the button causes validation
	 * upon callback
	 */
	public function getValidationGroup()
	{
		return $this->getOption('ValidationGroup','');
	}

	/**
	 * @param string the group of validators which the button causes validation
	 * upon callback
	 */
	public function setValidationGroup($value)
	{
		$this->setOption('ValidationGroup',$value,'');
	}

	/**
	 * @return boolean whether to perform validation if the callback is
	 * requested.
	 */
	public function canCauseValidation()
	{
		if($this->getCausesValidation())
		{
			$group=$this->getValidationGroup();
			return $this->getPage()->getValidators($group)->getCount()>0;
		}
		else
			return false;
	}

	/**
	 * @param mixed callback parameter value.
	 */
	public function setCallbackParameter($value)
	{
		$this->setOption('CallbackParameter', $value, '');
	}

	/**
	 * @return mixed callback parameter value.
	 */
	public function getCallbackParameter()
	{
		return $this->getOption('CallbackParameter', '');
	}


	/**
	 * @return array list of callback javascript options.
	 */
	protected function getClientSideOptions()
	{
		$default = $this->getDefaultClientSideOptions();
		$options = array_merge($default,$this->getClientSide()->getOptions()->toArray());
		$validate = $this->getCausesValidation();
		$options['CausesValidation']= $validate ? '' : false;
		$options['ValidationGroup']=$this->getValidationGroup();
		$options['CallbackParameter'] = $this->getCallbackParameter();
		// needed for TCallback
		if(!isset($options['EventTarget']))
			$options['EventTarget'] = $this->getControl()->getUniqueID();
		return $options;
	}

	/**
	 * 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();

		//remove true as default to save bytes
		if($options['CausesValidation']===true)
			$options['CausesValidation']='';
		$cs->registerCallbackControl($class, $options);
	}

	/**
	 * Returns the javascript callback request instance. To invoke a callback
	 * request for this control call the <tt>dispatch()</tt> method on the
	 * request instance. Example code in javascript
	 * <code>
	 *   var request = <%= $this->mycallback->ActiveControl->Javascript %>;
	 *   request.setParameter('hello');
	 *   request.dispatch(); //make the callback request.
	 * </code>
	 *
	 * Alternatively,
	 * <code>
	 * //dispatches immediately
	 * Prado.Callback("<%= $this->mycallback->UniqueID %>",
	 *    $this->mycallback->ActiveControl->JsCallbackOptions);
	 * </code>
	 * @return string javascript client-side callback request object (javascript
	 * code)
	 */
	public function getJavascript()
	{
		$client = $this->getPage()->getClientScript();
		return $client->getCallbackReference($this->getControl(),$this->getClientSideOptions());
	}

	/**
	 * @param string callback requestion options as javascript code.
	 */
	public function getJsCallbackOptions()
	{
		return TJavaScript::encode($this->getClientSideOptions());
	}
}