Subversion-Projekte lars-tiefland.prado

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * TDatePicker class file.
4
 *
5
 * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
6
 * @link http://www.pradosoft.com/
7
 * @copyright Copyright &copy; 2005-2008 PradoSoft
8
 * @license http://www.pradosoft.com/license/
9
 * @version $Id: TDatePicker.php 2575 2008-12-01 13:18:33Z carlgmathisen $
10
 * @package System.Web.UI.WebControls
11
 */
12
 
13
/**
14
 * Includes TTextBox class
15
 */
16
Prado::using('System.Web.UI.WebControls.TTextBox');
17
 
18
/**
19
 *
20
 * TDatePicker class.
21
 *
22
 * TDatePicker displays a text box for date input purpose.
23
 * When the text box receives focus, a calendar will pop up and users can
24
 * pick up from it a date that will be automatically entered into the text box.
25
 * The format of the date string displayed in the text box is determined by
26
 * the <b>DateFormat</b> property. Valid formats are the combination of the
27
 * following tokens,
28
 *
29
 * <code>
30
 *  Character Format Pattern (en-US)
31
 *  -----------------------------------------
32
 *  d          day digit
33
 *  dd         padded day digit e.g. 01, 02
34
 *  M          month digit
35
 *  MM         padded month digit
36
 *  MMMM       localized month name, e.g. March, April
37
 *  yy         2 digit year
38
 *  yyyy       4 digit year
39
 *  -----------------------------------------
40
 * </code>
41
 *
42
 * TDatePicker has three <b>Mode</b> to show the date picker popup.
43
 *
44
 *  # <b>Basic</b> -- Only shows a text input, focusing on the input shows the
45
 *                    date picker.
46
 *  # <b>Button</b> -- Shows a button next to the text input, clicking on the
47
 *                     button shows the date, button text can be by the
48
 *                     <b>ButtonText</b> property
49
 *  # <b>ImageButton</b> -- Shows an image next to the text input, clicking on
50
 *                          the image shows the date picker, image source can be
51
 *                          change through the <b>ButtonImageUrl</b> property.
52
 *
53
 * The <b>CssClass</b> property can be used to override the css class name
54
 * for the date picker panel. <b>CalendarStyle</b> property sets the packages
55
 * styles available. E.g. <b>default</b>.
56
 *
57
 * The <b>InputMode</b> property can be set to "TextBox" or "DropDownList" with
58
 * default as "TextBox".
59
 * In <tt>DropDownList</tt> mode, in addition to the popup date picker, three
60
 * drop down list (day, month and year) are presented to select the date .
61
 *
62
 * The <b>PositionMode</b> property can be set to "Top" or "Bottom" with default
63
 * as "Bottom". It specifies the position of the calendar popup, relative to the
64
 * input field.
65
 *
66
 * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
67
 * @author Carl G. Mathisen <carlgmathisen@gmail.com>
68
 * @version $Id: TDatePicker.php 2575 2008-12-01 13:18:33Z carlgmathisen $
69
 * @package System.Web.UI.WebControls
70
 * @since 3.0
71
 */
72
class TDatePicker extends TTextBox
73
{
74
	/**
75
	 * Script path relative to the TClientScriptManager::SCRIPT_PATH
76
	 */
77
	const SCRIPT_PATH = 'prado/datepicker';
78
 
79
	/**
80
	 * @var TDatePickerClientScript validator client-script options.
81
	 */
82
	private $_clientScript;
83
		/**
84
	 * AutoPostBack is not supported.
85
	 */
86
	public function setAutoPostBack($value)
87
	{
88
		throw new TNotSupportedException('tdatepicker_autopostback_unsupported',
89
			get_class($this));
90
	}
91
 
92
	/**
93
	 * @return string the format of the date string
94
	 */
95
	public function getDateFormat()
96
	{
97
		return $this->getViewState('DateFormat','dd-MM-yyyy');
98
	}
99
 
100
	/**
101
	 * Sets the format of the date string.
102
	 * @param string the format of the date string
103
	 */
104
	public function setDateFormat($value)
105
	{
106
		$this->setViewState('DateFormat',$value,'dd-MM-yyyy');
107
	}
108
 
109
	/**
110
	 * @return boolean whether the calendar window should pop up when the control receives focus
111
	 */
112
	public function getShowCalendar()
113
	{
114
		return $this->getViewState('ShowCalendar',true);
115
	}
116
 
117
	/**
118
	 * Sets whether to pop up the calendar window when the control receives focus
119
	 * @param boolean whether to show the calendar window
120
	 */
121
	public function setShowCalendar($value)
122
	{
123
		$this->setViewState('ShowCalendar',TPropertyValue::ensureBoolean($value),true);
124
	}
125
 
126
	/**
127
	 * Gets the current culture.
128
	 * @return string current culture, e.g. en_AU.
129
	 */
130
	public function getCulture()
131
	{
132
		return $this->getViewState('Culture', '');
133
	}
134
 
135
	/**
136
	 * Sets the culture/language for the date picker.
137
	 * @param string a culture string, e.g. en_AU.
138
	 */
139
	public function setCulture($value)
140
	{
141
		$this->setViewState('Culture', $value, '');
142
	}
143
 
144
	/**
145
	 * @param TDatePickerInputMode input method of date values
146
	 */
147
	public function setInputMode($value)
148
	{
149
		$this->setViewState('InputMode', TPropertyValue::ensureEnum($value, 'TDatePickerInputMode'), TDatePickerInputMode::TextBox);
150
	}
151
 
152
	/**
153
	 * @return TDatePickerInputMode input method of date values. Defaults to TDatePickerInputMode::TextBox.
154
	 */
155
	public function getInputMode()
156
	{
157
		return $this->getViewState('InputMode', TDatePickerInputMode::TextBox);
158
	}
159
 
160
	/**
161
	 * @param TDatePickerMode calendar UI mode
162
	 */
163
	public function setMode($value)
164
	{
165
	   $this->setViewState('Mode', TPropertyValue::ensureEnum($value, 'TDatePickerMode'), TDatePickerMode::Basic);
166
	}
167
 
168
	/**
169
	 * @return TDatePickerMode current calendar UI mode.
170
	 */
171
	public function getMode()
172
	{
173
	   return $this->getViewState('Mode', TDatePickerMode::Basic);
174
	}
175
	/**
176
	 * @param string the image url for "Image" UI mode.
177
	 */
178
	public function setButtonImageUrl($value)
179
	{
180
	   $this->setViewState('ImageUrl', $value, '');
181
	}
182
 
183
	/**
184
	 * @return string the image url for "Image" UI mode.
185
	 */
186
	public function getButtonImageUrl()
187
	{
188
	   return $this->getViewState('ImageUrl', '');
189
	}
190
 
191
	/**
192
	 * @param string set the calendar style
193
	 */
194
	public function setCalendarStyle($value)
195
	{
196
	   $this->setViewState('CalendarStyle', $value, 'default');
197
	}
198
 
199
	/**
200
	 * @return string current calendar style
201
	 */
202
	public function getCalendarStyle()
203
	{
204
	   return $this->getViewState('CalendarStyle', 'default');
205
	}
206
 
207
	/**
208
	 * Set the first day of week, with 0 as Sunday, 1 as Monday, etc.
209
	 * @param integer 0 for Sunday, 1 for Monday, 2 for Tuesday, etc.
210
	 */
211
	public function setFirstDayOfWeek($value)
212
	{
213
		$this->setViewState('FirstDayOfWeek', TPropertyValue::ensureInteger($value), 1);
214
	}
215
 
216
	/**
217
	 * @return integer first day of the week
218
	 */
219
	public function getFirstDayOfWeek()
220
	{
221
		return $this->getViewState('FirstDayOfWeek', 1);
222
	}
223
 
224
	/**
225
	 * @return string text for the date picker button. Default is "...".
226
	 */
227
	public function getButtonText()
228
	{
229
		return $this->getViewState('ButtonText', '...');
230
	}
231
 
232
	/**
233
	 * @param string text for the date picker button
234
	 */
235
	public function setButtonText($value)
236
	{
237
		$this->setViewState('ButtonText', $value, '...');
238
	}
239
 
240
	/**
241
	 * @param integer date picker starting year, default is 2000.
242
	 */
243
	public function setFromYear($value)
244
	{
245
		$this->setViewState('FromYear', TPropertyValue::ensureInteger($value), intval(@date('Y'))-5);
246
	}
247
 
248
	/**
249
	 * @return integer date picker starting year, default is -5 years
250
	 */
251
	public function getFromYear()
252
	{
253
		return $this->getViewState('FromYear', intval(@date('Y'))-5);
254
	}
255
 
256
	/**
257
	 * @param integer date picker ending year, default +10 years
258
	 */
259
	public function setUpToYear($value)
260
	{
261
		$this->setViewState('UpToYear', TPropertyValue::ensureInteger($value), intval(@date('Y'))+10);
262
	}
263
 
264
	/**
265
	 * @return integer date picker ending year, default +10 years
266
	 */
267
	public function getUpToYear()
268
	{
269
		return $this->getViewState('UpToYear', intval(@date('Y'))+10);
270
	}
271
 
272
	/**
273
	 * @param TDatePickerPositionMode calendar UI position
274
	 */
275
	public function setPositionMode($value)
276
	{
277
	   $this->setViewState('PositionMode', TPropertyValue::ensureEnum($value, 'TDatePickerPositionMode'), TDatePickerPositionMode::Bottom);
278
	}
279
 
280
	/**
281
	 * @return TDatePickerPositionMode current calendar UI position.
282
	 */
283
	public function getPositionMode()
284
	{
285
	   return $this->getViewState('PositionMode', TDatePickerPositionMode::Bottom);
286
	}
287
 
288
	/**
289
	 * @return integer current selected date from the date picker as timestamp, NULL if timestamp is not set previously.
290
	 */
291
	public function getTimeStamp()
292
	{
293
		if(trim($this->getText())==='')
294
			return null;
295
		else
296
			return $this->getTimeStampFromText();
297
	}
298
 
299
	/**
300
	 * Sets the date for the date picker using timestamp.
301
	 * @param float time stamp for the date picker
302
	 */
303
	public function setTimeStamp($value)
304
	{
305
		if($value===null || (is_string($value) && trim($value)===''))
306
			$this->setText('');
307
		else
308
		{
309
			$date = TPropertyValue::ensureFloat($value);
310
			$formatter = Prado::createComponent('System.Util.TSimpleDateFormatter',$this->getDateFormat());
311
			$this->setText($formatter->format($date));
312
		}
313
	}
314
 
315
	/**
316
	 * Returns the timestamp selected by the user.
317
	 * This method is required by {@link IDataRenderer}.
318
	 * It is the same as {@link getTimeStamp()}.
319
	 * @return integer the timestamp of the TDatePicker control.
320
	 * @see getTimeStamp
321
	 * @since 3.1.2
322
	 */
323
	public function getData()
324
	{
325
		return $this->getTimeStamp();
326
	}
327
 
328
	/**
329
	 * Sets the timestamp represented by this control.
330
	 * This method is required by {@link IDataRenderer}.
331
	 * It is the same as {@link setTimeStamp()}.
332
	 * @param integer the timestamp of the TDatePicker control.
333
	 * @see setTimeStamp
334
	 * @since 3.1.2
335
	 */
336
	public function setData($value)
337
	{
338
		$this->setTimeStamp($value);
339
	}
340
 
341
	/**
342
	 * @return string the date string.
343
	 */
344
	public function getDate()
345
	{
346
		return $this->getText();
347
	}
348
 
349
	/**
350
	 * @param string date string
351
	 */
352
	public function setDate($value)
353
	{
354
		$this->setText($value);
355
	}
356
 
357
	/**
358
	 * Gets the TDatePickerClientScript to set the TDatePicker event handlers.
359
	 *
360
	 * The date picker on the client-side supports the following events.
361
	 * # <tt>OnDateChanged</tt> -- raised when the date is changed.
362
	 *
363
	 * You can attach custom javascript code to each of these events
364
	 *
365
	 * @return TDatePickerClientScript javascript validator event options.
366
	 */
367
	public function getClientSide()
368
	{
369
		if(is_null($this->_clientScript))
370
			$this->_clientScript = $this->createClientScript();
371
		return $this->_clientScript;
372
	}
373
 
374
	/**
375
	 * @return TDatePickerClientScript javascript validator event options.
376
	 */
377
	protected function createClientScript()
378
	{
379
		return new TDatePickerClientScript;
380
	}
381
 
382
	/**
383
	 * Returns the value to be validated.
384
	 * This methid is required by IValidatable interface.
385
	 * @return integer the interger timestamp if valid, otherwise the original text.
386
	 */
387
	public function getValidationPropertyValue()
388
	{
389
		if(($text = $this->getText()) === '')
390
			return '';
391
		$date = $this->getTimeStamp();
392
		return $date == null ? $text : $date;
393
	}
394
 
395
	/**
396
	 * Publish the date picker Css asset files.
397
	 */
398
	public function onPreRender($param)
399
	{
400
		parent::onPreRender($param);
401
		if($this->getInputMode() === TDatePickerInputMode::DropDownList)
402
		{
403
			$page = $this->getPage();
404
			$uniqueID = $this->getUniqueID();
405
			$page->registerPostDataLoader($uniqueID.TControl::ID_SEPARATOR.'day');
406
			$page->registerPostDataLoader($uniqueID.TControl::ID_SEPARATOR.'month');
407
			$page->registerPostDataLoader($uniqueID.TControl::ID_SEPARATOR.'year');
408
		}
409
		$this->publishCalendarStyle();
410
	}
411
 
412
	/**
413
	 * Renders body content.
414
	 * This method overrides parent implementation by adding
415
	 * additional date picker button if Mode is Button or ImageButton.
416
	 * @param THtmlWriter writer
417
	 */
418
	public function render($writer)
419
	{
420
		if($this->getInputMode() == TDatePickerInputMode::TextBox)
421
		{
422
			parent::render($writer);
423
			$this->renderDatePickerButtons($writer);
424
		}
425
		else
426
		{
427
			$this->renderDropDownListCalendar($writer);
428
			if($this->hasDayPattern())
429
			{
430
				$this->registerCalendarClientScript();
431
				$this->renderDatePickerButtons($writer);
432
			}
433
		}
434
	}
435
 
436
	/**
437
	 * Renders the date picker popup buttons.
438
	 */
439
	protected function renderDatePickerButtons($writer)
440
	{
441
		if($this->getShowCalendar())
442
		{
443
			switch ($this->getMode())
444
			{
445
				case TDatePickerMode::Button:
446
					$this->renderButtonDatePicker($writer);
447
					break;
448
				case TDatePickerMode::ImageButton :
449
					$this->renderImageButtonDatePicker($writer);
450
					break;
451
			}
452
		}
453
	}
454
 
455
	/**
456
	 * Loads user input data. Override parent implementation, when InputMode
457
	 * is DropDownList call getDateFromPostData to get date data.
458
	 * This method is primarly used by framework developers.
459
	 * @param string the key that can be used to retrieve data from the input data collection
460
	 * @param array the input data collection
461
	 * @return boolean whether the data of the component has been changed
462
	 */
463
	public function loadPostData($key,$values)
464
	{
465
		if($this->getInputMode() == TDatePickerInputMode::TextBox)
466
			return parent::loadPostData($key, $values);
467
		$value = $this->getDateFromPostData($key, $values);
468
		if(!$this->getReadOnly() && $this->getText()!==$value)
469
		{
470
			$this->setText($value);
471
			return true;
472
		}
473
		else
474
			return false;
475
	}
476
 
477
	/**
478
	 * Loads date from drop down list data.
479
	 * @param string the key that can be used to retrieve data from the input data collection
480
	 * @param array the input data collection
481
	 * @return array the date selected
482
	 */
483
	protected function getDateFromPostData($key, $values)
484
	{
485
		$date = @getdate();
486
 
487
		if(isset($values[$key.'$day']))
488
			$day = intval($values[$key.'$day']);
489
		else
490
			$day = 1;
491
 
492
		if(isset($values[$key.'$month']))
493
			$month = intval($values[$key.'$month']) + 1;
494
		else
495
			$month = $date['mon'];
496
 
497
		if(isset($values[$key.'$year']))
498
			$year = intval($values[$key.'$year']);
499
		else
500
			$year = $date['year'];
501
 
502
		$s = Prado::createComponent('System.Util.TDateTimeStamp');
503
		$date = $s->getTimeStamp(0, 0, 0, $month, $day, $year);
504
		//$date = @mktime(0, 0, 0, $month, $day, $year);
505
 
506
		$pattern = $this->getDateFormat();
507
		$pattern = str_replace(array('MMMM', 'MMM'), array('MM','MM'), $pattern);
508
		$formatter = Prado::createComponent('System.Util.TSimpleDateFormatter', $pattern);
509
		return $formatter->format($date);
510
	}
511
 
512
	/**
513
	 * Get javascript date picker options.
514
	 * @return array date picker client-side options
515
	 */
516
	protected function getDatePickerOptions()
517
	{
518
		$options['ID'] = $this->getClientID();
519
		$options['InputMode'] = $this->getInputMode();
520
		$options['Format'] = $this->getDateFormat();
521
		$options['FirstDayOfWeek'] = $this->getFirstDayOfWeek();
522
		if(($cssClass=$this->getCssClass())!=='')
523
			$options['ClassName'] = $cssClass;
524
		$options['CalendarStyle'] = $this->getCalendarStyle();
525
		$options['FromYear'] = $this->getFromYear();
526
		$options['UpToYear'] = $this->getUpToYear();
527
		if($this->getMode()!==TDatePickerMode::Basic)
528
			$options['Trigger'] = $this->getDatePickerButtonID();
529
		$options['PositionMode'] = $this->getPositionMode();
530
 
531
		$options = array_merge($options, $this->getCulturalOptions());
532
		if(!is_null($this->_clientScript))
533
			$options = array_merge($options,
534
				$this->_clientScript->getOptions()->toArray());
535
		return $options;
536
	}
537
 
538
	/**
539
	 * Get javascript localization options, e.g. month and weekday names.
540
	 * @return array localization options.
541
	 */
542
	protected function getCulturalOptions()
543
	{
544
		if($this->getCurrentCulture() == 'en')
545
			return array();
546
 
547
		$date = $this->getLocalizedCalendarInfo();
548
		$options['MonthNames'] = TJavaScript::encode($date->getMonthNames(),false);
549
		$options['AbbreviatedMonthNames'] = TJavaScript::encode($date->getAbbreviatedMonthNames(),false);
550
		$options['ShortWeekDayNames'] = TJavaScript::encode($date->getAbbreviatedDayNames(),false);
551
 
552
		return $options;
553
	}
554
 
555
	/**
556
	 * @return string the current culture, falls back to application if culture is not set.
557
	 */
558
	protected function getCurrentCulture()
559
	{
560
		$app = $this->getApplication()->getGlobalization(false);
561
		return $this->getCulture() == '' ?
562
				($app ? $app->getCulture() : 'en') : $this->getCulture();
563
	}
564
 
565
	/**
566
	 * @return DateTimeFormatInfo date time format information for the current culture.
567
	 */
568
	protected function getLocalizedCalendarInfo()
569
	{
570
		//expensive operations
571
		$culture = $this->getCurrentCulture();
572
		Prado::using('System.I18N.core.DateTimeFormatInfo');
573
		$info = Prado::createComponent('System.I18N.core.CultureInfo', $culture);
574
		return $info->getDateTimeFormat();
575
	}
576
 
577
	/**
578
	 * Renders the drop down list date picker.
579
	 */
580
	protected function renderDropDownListCalendar($writer)
581
	{
582
		if($this->getMode() == TDatePickerMode::Basic)
583
			$this->setMode(TDatePickerMode::ImageButton);
584
		parent::addAttributesToRender($writer);
585
		$writer->removeAttribute('name');
586
		$writer->removeAttribute('type');
587
		$writer->addAttribute('id', $this->getClientID());
588
 
589
		if(strlen($class = $this->getCssClass()) > 0)
590
			$writer->addAttribute('class', $class);
591
		$writer->renderBeginTag('span');
592
 
593
		$s = Prado::createComponent('System.Util.TDateTimeStamp');
594
		$date = $s->getDate($this->getTimeStampFromText());
595
		//$date = @getdate($this->getTimeStampFromText());
596
 
597
		$this->renderCalendarSelections($writer, $date);
598
 
599
		//render a hidden input field
600
		$writer->addAttribute('name', $this->getUniqueID());
601
		$writer->addAttribute('type', 'hidden');
602
		$writer->addAttribute('value', $this->getText());
603
		$writer->renderBeginTag('input');
604
 
605
		$writer->renderEndTag();
606
		$writer->renderEndTag();
607
	}
608
 
609
	protected function hasDayPattern()
610
	{
611
		$formatter = Prado::createComponent('System.Util.TSimpleDateFormatter',
612
						$this->getDateFormat());
613
		return !is_null($formatter->getDayPattern());
614
	}
615
 
616
	/**
617
	 * Renders the calendar drop down list depending on the DateFormat pattern.
618
	 * @param THtmlWriter the Html writer to render the drop down lists.
619
	 * @param array the current selected date
620
	 */
621
	protected function renderCalendarSelections($writer, $date)
622
	{
623
		$formatter = Prado::createComponent('System.Util.TSimpleDateFormatter',
624
						$this->getDateFormat());
625
 
626
		foreach($formatter->getDayMonthYearOrdering() as $type)
627
		{
628
			if($type == 'day')
629
				$this->renderCalendarDayOptions($writer,$date['mday']);
630
			elseif($type == 'month')
631
				$this->renderCalendarMonthOptions($writer,$date['mon']);
632
			elseif($type == 'year')
633
				$this->renderCalendarYearOptions($writer,$date['year']);
634
		}
635
	}
636
 
637
	/**
638
	 * Gets the date from the text input using TSimpleDateFormatter
639
	 * @return integer current selected date timestamp
640
	 */
641
	protected function getTimeStampFromText()
642
	{
643
		$pattern = $this->getDateFormat();
644
		$pattern = str_replace(array('MMMM', 'MMM'), array('MM','MM'), $pattern);
645
		$formatter = Prado::createComponent('System.Util.TSimpleDateFormatter',$pattern);
646
		return $formatter->parse($this->getText());
647
	}
648
 
649
	/**
650
	 * Renders a drop down lists.
651
	 * @param THtmlWriter the writer used for the rendering purpose
652
	 * @param array list of selection options
653
	 * @param mixed selected key.
654
	 */
655
	private function renderDropDownListOptions($writer,$options,$selected=null)
656
	{
657
		foreach($options as $k => $v)
658
		{
659
			$writer->addAttribute('value', $k);
660
			if($k == $selected)
661
				$writer->addAttribute('selected', 'selected');
662
			$writer->renderBeginTag('option');
663
			$writer->write($v);
664
			$writer->renderEndTag();
665
		}
666
	}
667
 
668
	/**
669
	 * Renders the day drop down list options.
670
	 * @param THtmlWriter the writer used for the rendering purpose
671
	 * @param mixed selected day.
672
	 */
673
	protected function renderCalendarDayOptions($writer, $selected=null)
674
	{
675
		$days = $this->getDropDownDayOptions();
676
		$writer->addAttribute('id', $this->getClientID().TControl::CLIENT_ID_SEPARATOR.'day');
677
		$writer->addAttribute('name', $this->getUniqueID().TControl::ID_SEPARATOR.'day');
678
		$writer->addAttribute('class', 'datepicker_day_options');
679
		if($this->getReadOnly() || !$this->getEnabled(true))
680
			$writer->addAttribute('disabled', 'disabled');
681
		$writer->renderBeginTag('select');
682
		$this->renderDropDownListOptions($writer, $days, $selected);
683
		$writer->renderEndTag();
684
	}
685
 
686
	/**
687
	 * @return array list of day options for a drop down list.
688
	 */
689
	protected function getDropDownDayOptions()
690
	{
691
		$formatter = Prado::createComponent('System.Util.TSimpleDateFormatter',
692
						$this->getDateFormat());
693
		$days = array();
694
		$requiresPadding = $formatter->getDayPattern() === 'dd';
695
		for($i=1;$i<=31;$i++)
696
		{
697
			$days[$i] = $requiresPadding ? str_pad($i, 2, '0', STR_PAD_LEFT) : $i;
698
		}
699
		return $days;
700
	}
701
 
702
	/**
703
	 * Renders the month drop down list options.
704
	 * @param THtmlWriter the writer used for the rendering purpose
705
	 * @param mixed selected month.
706
	 */
707
	protected function renderCalendarMonthOptions($writer, $selected=null)
708
	{
709
		$info = $this->getLocalizedCalendarInfo();
710
		$writer->addAttribute('id', $this->getClientID().TControl::CLIENT_ID_SEPARATOR.'month');
711
		$writer->addAttribute('name', $this->getUniqueID().TControl::ID_SEPARATOR.'month');
712
		$writer->addAttribute('class', 'datepicker_month_options');
713
		if($this->getReadOnly() || !$this->getEnabled(true))
714
			$writer->addAttribute('disabled', 'disabled');
715
		$writer->renderBeginTag('select');
716
		$this->renderDropDownListOptions($writer,
717
					$this->getLocalizedMonthNames($info), $selected-1);
718
		$writer->renderEndTag();
719
	}
720
 
721
	/**
722
	 * Returns the localized month names that depends on the month format pattern.
723
	 * "MMMM" will return the month names, "MM" or "MMM" return abbr. month names
724
	 * and "M" return month digits.
725
	 * @param DateTimeFormatInfo localized date format information.
726
	 * @return array localized month names.
727
	 */
728
	protected function getLocalizedMonthNames($info)
729
	{
730
		$formatter = Prado::createComponent('System.Util.TSimpleDateFormatter',
731
						$this->getDateFormat());
732
		switch($formatter->getMonthPattern())
733
		{
734
			case 'MMM': return $info->getAbbreviatedMonthNames();
735
			case 'MM':
736
				$array = array();
737
				for($i=1;$i<=12;$i++)
738
						$array[$i-1] = $i < 10 ? '0'.$i : $i;
739
				return $array;
740
			case 'M':
741
				$array = array(); for($i=1;$i<=12;$i++) $array[$i-1] = $i;
742
				return $array;
743
			default :	return $info->getMonthNames();
744
		}
745
	}
746
 
747
	/**
748
	 * Renders the year drop down list options.
749
	 * @param THtmlWriter the writer used for the rendering purpose
750
	 * @param mixed selected year.
751
	 */
752
	protected function renderCalendarYearOptions($writer, $selected=null)
753
	{
754
		$years = array();
755
		for($i = $this->getFromYear(); $i <= $this->getUpToYear(); $i++)
756
			$years[$i] = $i;
757
		$writer->addAttribute('id', $this->getClientID().TControl::CLIENT_ID_SEPARATOR.'year');
758
		$writer->addAttribute('name', $this->getUniqueID().TControl::ID_SEPARATOR.'year');
759
		if($this->getReadOnly() || !$this->getEnabled(true))
760
			$writer->addAttribute('disabled', 'disabled');
761
		$writer->renderBeginTag('select');
762
		$writer->addAttribute('class', 'datepicker_year_options');
763
		$this->renderDropDownListOptions($writer, $years, $selected);
764
		$writer->renderEndTag();
765
	}
766
 
767
	/**
768
	 * Gets the ID for the date picker trigger button.
769
	 * @return string unique button ID
770
	 */
771
	protected function getDatePickerButtonID()
772
	{
773
		return $this->getClientID().'button';
774
	}
775
 
776
	/**
777
	 * Adds an additional button such that when clicked it shows the date picker.
778
	 * @return THtmlWriter writer
779
	 */
780
	protected function renderButtonDatePicker($writer)
781
	{
782
		$writer->addAttribute('id', $this->getDatePickerButtonID());
783
		$writer->addAttribute('type', 'button');
784
		$writer->addAttribute('class', $this->getCssClass().' TDatePickerButton');
785
		$writer->addAttribute('value',$this->getButtonText());
786
		if(!$this->getEnabled(true))
787
			$writer->addAttribute('disabled', 'disabled');
788
		$writer->renderBeginTag("input");
789
		$writer->renderEndTag();
790
	}
791
 
792
	/**
793
	 * Adds an additional image button such that when clicked it shows the date picker.
794
	 * @return THtmlWriter writer
795
	 */
796
	 protected function renderImageButtonDatePicker($writer)
797
	{
798
		$url = $this->getButtonImageUrl();
799
		$url = empty($url) ? $this->getAssetUrl('calendar.png') : $url;
800
		$writer->addAttribute('id', $this->getDatePickerButtonID());
801
		$writer->addAttribute('src', $url);
802
		$writer->addAttribute('alt', ' ');
803
		$writer->addAttribute('class', $this->getCssClass().' TDatePickerImageButton');
804
		if(!$this->getEnabled(true))
805
			$writer->addAttribute('disabled', 'disabled');
806
		$writer->renderBeginTag('img');
807
		$writer->renderEndTag();
808
	}
809
 
810
	/**
811
	 * @param string date picker asset file in the self::SCRIPT_PATH directory.
812
	 * @return string date picker asset url.
813
	 */
814
	protected function getAssetUrl($file='')
815
	{
816
		$base = $this->getPage()->getClientScript()->getPradoScriptAssetUrl();
817
		return $base.'/'.self::SCRIPT_PATH.'/'.$file;
818
	}
819
 
820
	/**
821
	 * Publish the calendar style Css asset file.
822
	 * @return string Css file url.
823
	 */
824
	protected function publishCalendarStyle()
825
	{
826
		$url = $this->getAssetUrl($this->getCalendarStyle().'.css');
827
		$cs = $this->getPage()->getClientScript();
828
		if(!$cs->isStyleSheetFileRegistered($url))
829
			$cs->registerStyleSheetFile($url, $url);
830
		return $url;
831
	}
832
 
833
	/**
834
	 * Add the client id to the input textbox, and register the client scripts.
835
	 * @param THtmlWriter writer
836
	 */
837
	protected function addAttributesToRender($writer)
838
	{
839
		parent::addAttributesToRender($writer);
840
		$writer->addAttribute('id',$this->getClientID());
841
		$this->registerCalendarClientScript();
842
	}
843
 
844
 
845
	/**
846
	 * Registers the javascript code to initialize the date picker.
847
	 */
848
	protected function registerCalendarClientScript()
849
	{
850
		if($this->getShowCalendar())
851
		{
852
			$cs = $this->getPage()->getClientScript();
853
			$cs->registerPradoScript("datepicker");
854
 
855
			if(!$cs->isEndScriptRegistered('TDatePicker.spacer'))
856
			{
857
				$spacer = $this->getAssetUrl('spacer.gif');
858
				$code = "Prado.WebUI.TDatePicker.spacer = '$spacer';";
859
				$cs->registerEndScript('TDatePicker.spacer', $code);
860
			}
861
 
862
			$options = TJavaScript::encode($this->getDatePickerOptions());
863
			$code = "new Prado.WebUI.TDatePicker($options);";
864
			$cs->registerEndScript("prado:".$this->getClientID(), $code);
865
		}
866
	}
867
}
868
 
869
/**
870
 * TDatePickerClientScript class.
871
 *
872
 * Client-side date picker event {@link setOnDateChanged OnDateChanged}
873
 * can be modified through the {@link TDatePicker::getClientSide ClientSide}
874
 * property of a date picker.
875
 *
876
 * The <tt>OnDateChanged</tt> event is raise when the date picker's date
877
 * is changed.
878
 * The formatted date according to {@link TDatePicker::getDateFormat DateFormat} is sent
879
 * as parameter to this event
880
 *
881
 * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
882
 * @version $Id: TDatePicker.php 2575 2008-12-01 13:18:33Z carlgmathisen $
883
 * @package System.Web.UI.WebControls
884
 * @since 3.0.4
885
 */
886
class TDatePickerClientScript extends TClientSideOptions
887
{
888
	/**
889
	 * Javascript code to execute when the date picker's date is changed.
890
	 * @param string javascript code
891
	 */
892
	public function setOnDateChanged($javascript)
893
	{
894
		$this->setFunction('OnDateChanged', $javascript);
895
	}
896
 
897
	/**
898
	 * @return string javascript code to execute when the date picker's date is changed.
899
	 */
900
	public function getOnDateChanged()
901
	{
902
		return $this->getOption('OnDateChanged');
903
	}
904
}
905
 
906
 
907
/**
908
 * TDatePickerInputMode class.
909
 * TDatePickerInputMode defines the enumerable type for the possible datepicker input methods.
910
 *
911
 * The following enumerable values are defined:
912
 * - TextBox: text boxes are used to input date values
913
 * - DropDownList: dropdown lists are used to pick up date values
914
 *
915
 * @author Qiang Xue <qiang.xue@gmail.com>
916
 * @version $Id: TDatePicker.php 2575 2008-12-01 13:18:33Z carlgmathisen $
917
 * @package System.Web.UI.WebControls
918
 * @since 3.0.4
919
 */
920
class TDatePickerInputMode extends TEnumerable
921
{
922
	const TextBox='TextBox';
923
	const DropDownList='DropDownList';
924
}
925
 
926
/**
927
 * TDatePickerMode class.
928
 * TDatePickerMode defines the enumerable type for the possible UI mode
929
 * that a {@link TDatePicker} control can take.
930
 *
931
 * The following enumerable values are defined:
932
 * - Basic: Only shows a text input, focusing on the input shows the date picker
933
 * - Button: Shows a button next to the text input, clicking on the button shows the date, button text can be by the
934
 * - ImageButton: Shows an image next to the text input, clicking on the image shows the date picker,
935
 *
936
 * @author Qiang Xue <qiang.xue@gmail.com>
937
 * @version $Id: TDatePicker.php 2575 2008-12-01 13:18:33Z carlgmathisen $
938
 * @package System.Web.UI.WebControls
939
 * @since 3.0.4
940
 */
941
class TDatePickerMode extends TEnumerable
942
{
943
	const Basic='Basic';
944
	const Button='Button';
945
	const ImageButton='ImageButton';
946
}
947
 
948
/**
949
 * TDatePickerPositionMode class.
950
 * TDatePickerPositionMode defines the positions available for the calendar popup, relative to the corresponding input.
951
 *
952
 * The following enumerable values are defined:
953
 * - Top: the date picker is placed above the input field
954
 * - Bottom: the date picker is placed below the input field
955
 *
956
 * @author Carl G. Mathisen <carlgmathisen@gmail.com>
957
 * @package System.Web.UI.WebControls
958
 * @since 3.1.4
959
 */
960
class TDatePickerPositionMode extends TEnumerable
961
{
962
	const Top='Top';
963
	const Bottom='Bottom';
964
}