Subversion-Projekte lars-tiefland.prado

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * TSlider class file.
4
 *
5
 * @author Christophe Boulain <Christophe.Boulain@gmail.com>
6
 * @link http://www.pradosoft.com/
7
 * @copyright Copyright &copy; 2005-2008 PradoSoft
8
 * @license http://www.pradosoft.com/license/
9
 * @version $Id: TSlider.php 2564 2008-11-11 21:56:02Z carlgmathisen $
10
 * @package System.Web.UI.WebControls
11
 * @since 3.1.1
12
 */
13
 
14
/**
15
 * TSlider class
16
 *
17
 * TSlider displays a slider for numeric input purpose. A slider consists of a 'track',
18
 * which define the range of possible value, and a 'handle' which can slide on the track, to select
19
 * a value in the range. The track can be either Horizontal or Vertical, depending of the {@link SetDirection Direction}
20
 * property. By default, it's horizontal.
21
 *
22
 * The range boundaries are defined by {@link SetMinValue MinValue} and {@link SetMaxValue MaxValue} properties.
23
 * The default range is from 0 to 100.
24
 * The {@link SetStepSize StepSize} property can be used to define the <b>step</b> between 2 values inside the range.
25
 * Notice that this step will be recomputed if there is more than 200 values between the range boundaries.
26
 * You can also provide the allowed values by setting the {@link SetValues Values} array.
27
 *
28
 * A 'Progress Indicator' can be displayed within the track with the {@link SetProgressIndicator ProgressIndicator} property.
29
 *
30
 * The TSlider control can be easily customized using CssClasses. You can provide your own css file, using the
31
 * {@link SetCssUrl CssUrl} property.
32
 * The css class for TSlider can be set by the {@link setCssClass CssClass} property. Default value is "Slider HorizontalSlider"
33
 * for an horizontal slider, and "Slider VerticalSlider" for a vertical one.
34
 *
35
 * If {@link SetAutoPostBack AutoPostBack} property is true, postback is sent as soon as the value changed.
36
 *
37
 * TSlider raises the {@link onValueChanged} event when the value of the slider has changed during postback.
38
 *
39
 * You can also attach ClientSide javascript events handler to the slider :
40
 * - ClientSide.onSlide is called when the handle is slided on the track. You can get the current value in the <b>value</b>
41
 * javascript variable. You can use this event to update on client side a label with the current value
42
 * - ClientSide.onChange is called when the slider value has changed (at the end of a move).
43
 *
44
 * @author Christophe Boulain <Christophe.Boulain@gmail.com>
45
 * @version $Id: TSlider.php 2564 2008-11-11 21:56:02Z carlgmathisen $
46
 * @package System.Web.UI.WebControls
47
 * @since 3.1.1
48
 */
49
class TSlider extends TWebControl implements IPostBackDataHandler, IDataRenderer
50
{
51
	const MAX_STEPS=200;
52
	/**
53
	 * @var TSliderHandle handle component
54
	 */
55
	private $_handle;
56
	/*
57
	 * @var boolean Wether the data has changed during postback
58
	 */
59
	private $_dataChanged=false;
60
	/**
61
	 * @var TSliderClientScript Clients side javascripts
62
	 */
63
	private $_clientScript=null;
64
 
65
	/**
66
	 * @return TSliderDirection Direction of slider (Horizontal or Vertical). Defaults to Horizontal.
67
	 */
68
	public function getDirection()
69
	{
70
		return $this->getViewState('Direction', TSliderDirection::Horizontal);
71
	}
72
 
73
	/**
74
	 * @param TSliderDirection Direction of slider (Horizontal or Vertical)
75
	 */
76
	public function setDirection($value)
77
	{
78
		$this->setViewState('Direction', TPropertyValue::ensureEnum($value,'TSliderDirection'),TSliderDirection::Horizontal);
79
	}
80
 
81
	/**
82
	 * @return string URL for the CSS file including all relevant CSS class definitions. Defaults to '' (a default CSS file will be applied in this case.)
83
	 */
84
	public function getCssUrl()
85
	{
86
		return $this->getViewState('CssUrl','');
87
	}
88
 
89
	/**
90
	 * @param string URL for the CSS file including all relevant CSS class definitions.
91
	 */
92
	public function setCssUrl($value)
93
	{
94
		$this->setViewState('CssUrl',TPropertyValue::ensureString($value),'');
95
	}
96
 
97
	/**
98
	 * @return float Maximum value for the slider. Defaults to 100.0.
99
	 */
100
	public function getMaxValue()
101
	{
102
		return $this->getViewState('MaxValue',100.0);
103
	}
104
 
105
	/**
106
	 * @param float Maximum value for slider
107
	 */
108
	public function setMaxValue($value)
109
	{
110
		$this->setViewState('MaxValue', TPropertyValue::ensureFloat($value),100.0);
111
	}
112
 
113
	/**
114
	 * @return float Minimum value for slider. Defaults to 0.0.
115
	 */
116
	public function getMinValue()
117
	{
118
		return $this->getViewState('MinValue',0.0);
119
	}
120
 
121
	/**
122
	 * @param float Minimum value for slider
123
	 */
124
	public function setMinValue($value)
125
	{
126
		$this->setViewState('MinValue', TPropertyValue::ensureFloat($value),0.0);
127
	}
128
 
129
	/**
130
	 * @return float Step size. Defaults to 1.0.
131
	 */
132
	public function getStepSize()
133
	{
134
		return $this->getViewState('StepSize', 1.0);
135
	}
136
 
137
	/**
138
	 * Sets the step size used to determine the places where the slider handle can stop at.
139
	 * An evenly distributed stop marks will be generated according to
140
	 * {@link getMinValue MinValue}, {@link getMaxValue MaxValue} and StepSize.
141
	 * To use uneven stop marks, set {@link setValues Values}.
142
	 * @param float Step size.
143
	 */
144
	public function setStepSize($value)
145
	{
146
		$this->setViewState('StepSize', $value, 1.0);
147
	}
148
 
149
	/**
150
	 * @return boolean wether to display a progress indicator or not. Defaults to true.
151
	 */
152
	public function getProgressIndicator ()
153
	{
154
		return $this->getViewState('ProgressIndicator', true);
155
	}
156
 
157
	/**
158
	 * @param boolean wether to display a progress indicator or not. Defaults to true.
159
	 */
160
	public function setProgressIndicator ($value)
161
	{
162
		$this->setViewState('ProgressIndicator', TPropertyValue::ensureBoolean($value), true);
163
	}
164
	/**
165
	 * @return float current value of slider
166
	 */
167
	public function getValue()
168
	{
169
		return $this->getViewState('Value',0.0);
170
	}
171
 
172
	/**
173
	 * @param float current value of slider
174
	 */
175
	public function setValue($value)
176
	{
177
		$this->setViewState('Value', TPropertyValue::ensureFloat($value),0.0);
178
	}
179
 
180
	/**
181
	 * Returns the value of the TSlider control.
182
	 * This method is required by {@link IDataRenderer}.
183
	 * It is the same as {@link getValue()}.
184
	 * @return string the value of the TSlider control.
185
	 * @see getValue
186
	 */
187
	public function getData()
188
	{
189
		return $this->getValue();
190
	}
191
 
192
	/**
193
	 * Sets the value of the TSlider control.
194
	 * This method is required by {@link IDataRenderer}.
195
	 * It is the same as {@link setValue()}.
196
	 * @param string the value of the TSlider control.
197
	 * @see setValue
198
	 */
199
	public function setData($value)
200
	{
201
		$this->setValue($value);
202
	}
203
 
204
	/**
205
	 * @return array list of allowed values the slider can take. Defaults to an empty array.
206
	 */
207
	public function getValues()
208
	{
209
		return $this->getViewState('Values', array());
210
	}
211
 
212
	/**
213
	 * Sets the possible values that the slider can take.
214
	 * If this is set, {@link setStepSize StepSize} will be ignored. The latter
215
	 * generates a set of evenly distributed candidate values.
216
	 * @param array list of allowed values the slider can take
217
	 */
218
	public function setValues($value)
219
	{
220
		$this->setViewState('Values', TPropertyValue::ensureArray($value), array());
221
	}
222
 
223
	/**
224
	 * @return boolean a value indicating whether an automatic postback to the server
225
	 * will occur whenever the user modifies the slider value. Defaults to false.
226
	 */
227
	public function getAutoPostBack()
228
	{
229
		return $this->getViewState('AutoPostBack',false);
230
	}
231
 
232
	/**
233
	 * Sets the value indicating if postback automatically.
234
	 * An automatic postback to the server will occur whenever the user
235
	 * modifies the slider value.
236
	 * @param boolean the value indicating if postback automatically
237
	 */
238
	public function setAutoPostBack($value)
239
	{
240
		$this->setViewState('AutoPostBack',TPropertyValue::ensureBoolean($value),false);
241
	}
242
 
243
	/**
244
	 * Gets the name of the javascript class responsible for performing postback for this control.
245
	 * This method overrides the parent implementation.
246
	 * @return string the javascript class name
247
	 */
248
	protected function getClientClassName()
249
	{
250
		return 'Prado.WebUI.TSlider';
251
	}
252
 
253
	/**
254
	 * Returns a value indicating whether postback has caused the control data change.
255
	 * This method is required by the IPostBackDataHandler interface.
256
	 * @return boolean whether postback has caused the control data change. False if the page is not in postback mode.
257
	 */
258
	public function getDataChanged()
259
	{
260
		return $this->_dataChanged;
261
	}
262
 
263
	/**
264
	 * Raises postdata changed event.
265
	 * This method is required by {@link IPostBackDataHandler} interface.
266
	 * It is invoked by the framework when {@link getValue Value} property
267
	 * is changed on postback.
268
	 * This method is primarly used by framework developers.
269
	 */
270
	public function raisePostDataChangedEvent()
271
	{
272
		$this->onValueChanged(null);
273
	}
274
 
275
	/**
276
	 * Raises <b>OnValueChanged</b> event.
277
	 * This method is invoked when the {@link getValue Value}
278
	 * property changes on postback.
279
	 * If you override this method, be sure to call the parent implementation to ensure
280
	 * the invocation of the attached event handlers.
281
	 * @param TEventParameter event parameter to be passed to the event handlers
282
	 */
283
	public function onValueChanged($param)
284
	{
285
		$this->raiseEvent('OnValueChanged',$this,$param);
286
	}
287
 
288
	/**
289
	 * Loads user input data.
290
	 * This method is primarly used by framework developers.
291
	 * @param string the key that can be used to retrieve data from the input data collection
292
	 * @param array the input data collection
293
	 * @return boolean whether the data of the component has been changed
294
	 */
295
	public function loadPostData($key,$values)
296
	{
297
		$value=(float)$values[$this->getClientID().'_1'];
298
		if($this->getValue()!==$value)
299
		{
300
			$this->setValue($value);
301
			return $this->_dataChanged=true;
302
		}
303
		else
304
			return false;
305
	}
306
 
307
	/**
308
	 * Gets the TSliderClientScript to set the TSlider event handlers.
309
	 *
310
	 * The slider on the client-side supports the following events.
311
	 * # <tt>OnSliderMove</tt> -- raised when the slider is moved.
312
	 * # <tt>OnSliderChanged</tt> -- raised when the slider value is changed
313
	 *
314
	 * You can attach custom javascript code to each of these events
315
	 *
316
	 * @return TSliderClientScript javascript validator event options.
317
	 */
318
	public function getClientSide()
319
	{
320
		if($this->_clientScript===null)
321
			$this->_clientScript = $this->createClientScript();
322
		return $this->_clientScript;
323
	}
324
 
325
	/**
326
	 * @return TSliderClientScript javascript event options.
327
	 */
328
	protected function createClientScript()
329
	{
330
		return new TSliderClientScript;
331
	}
332
 
333
	/**
334
	 * @return string the HTML tag name for slider. Defaults to div.
335
	 */
336
	public function getTagName ()
337
	{
338
		return "div";
339
	}
340
 
341
	/**
342
	 * Add the specified css classes to the track
343
	 * @param THtmlWriter writer
344
	 */
345
	protected function addAttributesToRender($writer)
346
	{
347
		parent::addAttributesToRender($writer);
348
		$writer->addAttribute('id',$this->getClientID());
349
		if ($this->getCssClass()==='')
350
		{
351
			$class=($this->getDirection()==TSliderDirection::Horizontal)?'HorizontalSlider':'VerticalSlider';
352
			$writer->addAttribute('class', 'Slider '.$class);
353
		}
354
 
355
	}
356
 
357
	/**
358
	 * Render the body content
359
	 */
360
	public function renderContents($writer)
361
	{
362
		// Render the 'Track'
363
		$writer->addAttribute('class', 'Track');
364
		$writer->addAttribute('id', $this->getClientID().'_track');
365
		$writer->renderBeginTag('div');
366
		// Render the 'Progress Indicator'
367
		if ($this->getProgressIndicator())
368
		{
369
			$writer->addAttribute('class', 'Progress');
370
			$writer->addAttribute('id', $this->getClientID().'_progress');
371
			$writer->renderBeginTag('div');
372
			$writer->renderEndTag();
373
		}
374
		// Render the 'Ruler'
375
		/*
376
		 * Removing for now
377
		$writer->addAttribute('class', 'RuleContainer');
378
		$writer->addAttribute('id', $this->getClientID()."_rule");
379
		$writer->renderBeginTag('div');
380
		for ($i=0;$i<=100;$i+=10)
381
		{
382
			$writer->addAttribute('class', 'RuleMark');
383
			$attr=($this->getDirection()===TSliderDirection::Horizontal)?"left":"top";
384
			$writer->addStyleAttribute($attr, $i.'%');
385
			$writer->renderBeginTag('div');
386
			$writer->renderEndTag();
387
		}
388
		$writer->renderEndTag();
389
		*/
390
 
391
		$writer->renderEndTag();
392
 
393
		// Render the 'Handle'
394
		$writer->addAttribute('class', 'Handle');
395
		$writer->addAttribute('id', $this->getClientID().'_handle');
396
		$writer->renderBeginTag('div');
397
		$writer->renderEndTag();
398
	}
399
	/**
400
	 * Registers CSS and JS.
401
	 * This method is invoked right before the control rendering, if the control is visible.
402
	 * @param mixed event parameter
403
	 */
404
	public function onPreRender ($param)
405
	{
406
		parent::onPreRender($param);
407
		$this->registerStyleSheet();
408
		$this->registerSliderClientScript();
409
 
410
	}
411
 
412
	/**
413
	 * Registers the CSS relevant to the TSlider.
414
	 * It will register the CSS file specified by {@link getCssUrl CssUrl}.
415
	 * If that is not set, it will use the default CSS.
416
	 */
417
	protected function registerStyleSheet()
418
	{
419
		if(($url=$this->getCssUrl())==='')
420
		{
421
			$manager=$this->getApplication()->getAssetManager();
422
			// publish the assets
423
			$url=$manager->publishFilePath(dirname(__FILE__).DIRECTORY_SEPARATOR.'assets'.DIRECTORY_SEPARATOR.'TSlider');
424
			$url.='/TSlider.css';
425
		}
426
		$this->getPage()->getClientScript()->registerStyleSheetFile($url,$url);
427
	}
428
 
429
	/**
430
	 * Registers the javascript code to initialize the slider.
431
	 */
432
	protected function registerSliderClientScript()
433
	{
434
		$page=$this->getPage();
435
		$cs = $page->getClientScript();
436
		$cs->registerPradoScript("slider");
437
		$id=$this->getClientID();
438
		$cs->registerHiddenField($id.'_1',$this->getValue());
439
		$page->registerRequiresPostData($this);
440
		$cs->registerPostBackControl($this->getClientClassName(),$this->getSliderOptions());
441
	}
442
 
443
	/**
444
	 * Get javascript sliderr options.
445
	 * @return array slider client-side options
446
	 */
447
	protected function getSliderOptions()
448
	{
449
		// PostBack Options :
450
		$options['ID'] = $this->getClientID();
451
		$options['EventTarget'] = $this->getUniqueID();
452
		$options['AutoPostBack'] = $this->getAutoPostBack();
453
 
454
		// Slider Control options
455
		$minValue=$this->getMinValue();
456
		$maxValue=$this->getMaxValue();
457
		$options['axis'] = strtolower($this->getDirection());
458
		$options['maximum'] = $maxValue;
459
		$options['minimum'] = $minValue;
460
		$options['range'] = 'javascript:$R('.$minValue.",".$maxValue.")";
461
		$options['sliderValue'] = $this->getValue();
462
		$options['disabled'] = !$this->getEnabled();
463
		$values=$this->getValues();
464
		if (!empty($values))
465
		{
466
			// Values are provided. Check if min/max are present in them
467
			if (!in_array($minValue, $values)) $values[]=$minValue;
468
			if (!in_array($maxValue, $values)) $values[]=$maxValue;
469
			// Remove all values outsize the range [min..max]
470
			foreach ($values as $idx=>$value)
471
			{
472
				if ($value < $minValue) unset ($values[$idx]);
473
				if ($value > $maxValue) unset ($values[$idx]);
474
			}
475
		}
476
		else
477
		{
478
			// Values are not provided, generate automatically using stepsize
479
			$step=$this->getStepSize();
480
			// We want at most self::MAX_STEPS values, so, change the step if necessary
481
			if (($maxValue-$minValue)/$step > self::MAX_STEPS)
482
			{
483
				$step=($maxValue-$minValue)/self::MAX_STEPS;
484
			}
485
			$values=array();
486
			for ($i=$minValue;$i<=$maxValue;$i+=$step)
487
				$values[]=$i;
488
			// Add max if it's not in the array because of step
489
			if (!in_array($maxValue, $values)) $values[]=$maxValue;
490
		}
491
		$options['values'] = TJavaScript::Encode($values,false);
492
		if($this->_clientScript!==null)
493
			$options = array_merge($options,$this->_clientScript->getOptions()->toArray());
494
		return $options;
495
	}
496
}
497
 
498
/**
499
 * TSliderClientScript class.
500
 *
501
 * Client-side slider events {@link setOnChange OnChange} and {@line setOnMove OnMove}
502
 * can be modified through the {@link TSlider:: getClientSide ClientSide}
503
 * property of a slider.
504
 *
505
 * The current value of the slider can be get in the 'value' js variable
506
 *
507
 * The <tt>OnMove</tt> event is raised when the slider moves
508
 * The <tt>OnChange</tt> event is raised when the slider value is changed (or at the end of a move)
509
 *
510
 * @author Christophe Boulain <Christophe.Boulain@gmail.com>
511
 * @version $Id: TSlider.php 2564 2008-11-11 21:56:02Z carlgmathisen $
512
 * @package System.Web.UI.WebControls
513
 * @since 3.1.1
514
 */
515
class TSliderClientScript extends TClientSideOptions
516
{
517
	/**
518
	 * Javascript code to execute when the slider value is changed.
519
	 * @param string javascript code
520
	 */
521
	public function setOnChange($javascript)
522
	{
523
		$code="javascript: function (value) { {$javascript} }";
524
		$this->setFunction('onChange', $code);
525
	}
526
 
527
	/**
528
	 * @return string javascript code to execute when the slider value is changed.
529
	 */
530
	public function getOnChange()
531
	{
532
		return $this->getOption('onChange');
533
	}
534
 
535
	/* Javascript code to execute when the slider moves.
536
	 * @param string javascript code
537
	 */
538
	public function setOnSlide($javascript)
539
	{
540
		$code="javascript: function (value) { {$javascript} }";
541
		$this->setFunction('onSlide', $code);
542
	}
543
 
544
	/**
545
	 * @return string javascript code to execute when the slider moves.
546
	 */
547
	public function getOnSlide()
548
	{
549
		return $this->getOption('onSlide');
550
	}
551
}
552
 
553
 
554
/**
555
 * TSliderDirection class.
556
 *
557
 * TSliderDirection defines the enumerable type for the possible direction that can be used in a {@link TSlider}
558
 *
559
 * The following enumerable values are defined :
560
 * - Horizontal : Horizontal slider
561
 * - Vertical : Vertical slider
562
 *
563
 * @author Christophe Boulain <Christophe.Boulain@gmail.com>
564
 * @version $Id: TSlider.php 2564 2008-11-11 21:56:02Z carlgmathisen $
565
 * @package System.Web.UI.WebControls
566
 * @since 3.1.1
567
 */
568
class TSliderDirection extends TEnumerable
569
{
570
	const Horizontal='Horizontal';
571
	const Vertical='Vertical';
572
}
573
 
574