-
Notifications
You must be signed in to change notification settings - Fork 1
/
ext.ux.datepickerplus.js
2753 lines (2426 loc) · 99.5 KB
/
ext.ux.datepickerplus.js
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
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* Ext.ux.DatePickerPlus Addon
* Ext.ux.form.DateFieldPlus Addon
*
* @author Marco Wienkoop (wm003/lubber)
* @copyright (c) 2008-2018, Marco Wienkoop (marco.wienkoop@lubber.de) http://www.lubber.de
*
* @class Ext.ux.DatePickerPlus
* @extends Ext.DatePicker
*
* v.1.4.6
*
* @class Ext.ux.form.DateFieldPlus
* @extends Ext.form.DateField
*
You need at least ExtJS 2.0.2 or higher
Also adds Ext.util.EasterDate
Calculates the Date-Object of easter-sunday of a given year
Commercial License available! See http://www.lubber.de/extjs/datepickerplus for more info
* Donations are always welcome :)
* Any amount is greatly appreciated and will help to continue on developing ExtJS Widgets
*
* You can donate via PayPal to donate@lubber.de
-----------------------------------------------------------------------------------------------------
-- DatePickerPlus Extension based on 4 contributed extensions from the ext-forum
-- and of course the original Datepicker from the awesome ExtJS Javascript Library
-----------------------------------------------------------------------------------------------------
-- (1) Multimonth calendar extension (enhanced integration)
-- (2) Datepicker extension for multiple day/week/month selection (basic idea adopted)
-- (3) Weeknumber display (enhanced integration)
-- (4) XDateField with configurable submitFormat (full integration)
-- using my own getFirstDateOfWeek routine as it is more flexible for choosing which day is the first day of a week (in some countries its sunday, not monday!)
-----------------------------------------------------------------------------------------------------
-- (2) (multimonth calendar)
-- Author: aungii
-- Source: http://extjs.com/forum/showthread.php?t=20597
--
-- (2) (multiple day/week/month selection)
-- Author: cocorossello / stevenvegt
-- Source: http://extjs.com/forum/showthread.php?t=22473
--
-- (3) (weeknumber display)
-- Author: eni.kao
-- Source: http://extjs.com/forum/showthread.php?t=15635
--
-- (4) (XDateField with configurable submitFormat)
-- Author: jsakalos
-- Source: http://extjs.com/forum/showthread.php?t=25900
* @license licensing of Ext.ux.DatePickerPlus and Ext.ux.form.DateFieldPlus depends of the underlying ExtJS Framework Version
*
* If you use ExtJS <= 2.0.2 Ext.ux.DatePickerPlus and Ext.ux.form.DateFieldPlus are licensed under the terms of the
* LGPL v3
* License details: http://www.gnu.org/licenses/lgpl.html
*
* If you use ExtJS >= 2.1 Ext.ux.DatePickerPlus and Ext.ux.form.DateFieldPlus are licensed under the terms of the
* GPL v3
* License details: http://www.gnu.org/licenses/gpl.html
*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
* This Addon requires the ExtJS Library, which is distributed under the terms of the GPL v3 (since ExtJs V2.1)
* See http://extjs.com/license for more info
Revision History:
v.1.4.6 [2018/02/05]
- support option "clickRepeaterConfig" to supply clickrepeater options for prevnext trigger buttons
v.1.4.5 [2012/03/08]
- respect minDate/maxDate on prevnext trigger buttons
- add minDate/maxDate to minText/maxText in Datepicker Core
v.1.4.4 [2012/03/08]
- fixed prevNextButtons when switching on days between summer/wintertime
- checked to work with ExtJS 3.4.0
- added an optional deleteTrigger on Datefield
- BUGFIX: setMinDate throws Error, when value was not defined
- TBD BUGFIX: summarizeHeader got more height when showWeekNumber was set to false
- TBD BUGFIX: a white gap column appeared when showWeekNumber was set to false (only on latest chromium?)
v.1.4.3 [2011/03/18]
- BUGFIX: Config wasn't set when used in Editorgridpanel
v.1.4.2 [2011/02/23]
- checked to work with ExtJS 3.3.1
- added config: showPrevNextTrigger (DateFieldPlus only and not with multiselection) to display 2 buttons next to the DateFieldPlus
- added config: prevNextTriggerType (DateFieldPlus only not with multiselection): m means +/- month (valid End of month will be considered), any numeric value means amount of +/- days
- added Event "onPrevTriggerRelease", (DateFieldPlus only not with multiselection) which triggers when the PrevTrigger MouseUp Event occurs (if omitted the usual select-handler will be triggered)
- added Event "onNextTriggerRelease", (DateFieldPlus only not with multiselection) which triggers when the PrevTrigger MouseUp Event occurs (if omitted the usual select-handler will be triggered)
- BUGFIX: When specifying that weeknumbers should not be rendered and showing more than 1 row of months,the widths of daily columns in the 2nd and subsequent rows of months are too small. (reported by josefhaydn)
- BUGFIX: select event was triggered twice on Datefieldplus
- BUGFIX: When using strictRangeSelection all clicked dates outside gaps were still selected even when not displayed (reported by gkarmadi)
v.1.4.1 [2010/11/09]
- checked to work with ExtJS 3.3.0
- Forced to update viewport on setValue
- BUGFIX: correctly position picker in datefield with hiddenfield on IE in some cases
v.1.4 [2010/04/30]
- checked to work with ExtJS 3.2.1
- BUGFIX: Datepickers with shown months > 1 had a white glitch obove them (thanks to radubrehar)
- BUGFIX: CSS Fixes for Datemenus and more than 1 row of months when using IE8 in Compatibility Mode
- added romanian locale (thanks to radubrehar)
- added japanese locale (thanks to itheart)
- added polish locale (thanks to maboch)
v.1.4 RC1 [2010/03/04]
- checked to work with ExtJS 3.1.1
- BUGFIX: DateField Events did not work properly (reported by yuewah)
- BUGFIX: beforedestroy throws exception when parent control of datepickerplus gets destroyed (reported by yuewah)
- spanish locale corrected (holiday had a leading zero)
v.1.4 Beta 2 [2009/09/18]
- checked to work with ExtJS 3.0.0
- checked to work with ExtJS 2.3.0
- Adopted config item prevNextDaysView to DateFieldPlus
- Adopted events beforedateclick, beforeweekclick and beforemonthclick to DateFieldPlus
- more code optimization for Ext 3.0 compatibility
- support option "defaultvalue" on datefieldplus
- BUGFIX: setDisabled did not work under Ext 3.0 (reported by radtad)
v.1.4 Beta [2009/07/03]
- checked to work with ExtJS 3.0-RC3
- checked to work with ExtJS 2.2.1
- support of jsondates (e.g. "2008-08-04T12:22:00") in setEventDates, setSelectedDates, setAllowedDates,setMindate and setMaxdate
- some Code optimizations
- corrected holidays in german locale
- added events beforedateclick, beforeweekclick and beforemonthclick
- added dutch locale (thanks to walldorff)
- added french locale (thanks to dubdub)
- added Norwegian bokmål locale (thanks to Alex Brasetvik)
- added spanish locale (thanks to erzsebet)
- added version config
- added config prevNextDaysView ("mark","nomark",false) to disable automatic selection/view of selected days of current months in previous and next month, so only the current months days are selectable (suggested by sirtimbly)
- BUGFIX: select-event on datefieldplus was added again each time the trigger has been clicked
- BUGFIX: Fix for updatehidden in case of multiselection (thanks to Hunyi)
- BUGFIX: do not handle dateselection when disabled-property is set
v.1.3 [2008/08/05]
- Support of ExtJS 2.2
- Adopted new config items from 1.2 to DateFieldPlus also
v.1.2 [2008/08/04]
- support "allowOtherMenus" Config for DateFieldPlus
- datefieldplus can be hidden by clicking the triggerbutton again in cases hiding by clicking outside isn't possible
- added config "styleDisabledDates" to be able to set custom style dates (eventdates/weekends..) on disabled dates also (suggested by descheret)
- added config "eventDatesSelectable" to disble event-dates selection if desired (even if the dates are not disabled at all) (thanks to descheret)
- added config "disableSingleDateSelection" to force user to use week- or monthselection only (suggested by chemist458)
- added config "stayInAllowedRange" when setting minDate/maxDate, this will prevent to change months outside the allowed daterange (suggested by descheret)
- added config "summarizeHeader" to add an optional global header when using multimonth display containing the month range (e.g. january 2008-october 2008)
- added italian locale (thanks to andreabat)
- BUGFIX: setMinDate/MaxDate/DateLimits did not update the viewport properly
V1.1 Final [2008/06/12]
- added config "allowMouseWheel" to generally turn on/off Mousewheelsupport (suggested by boraldo)
- added event "beforemousewheel" to be able to temporary disable the mousewheel if desired
- added event "beforemaxdays" to be able to cancel the default MessageBox but do something on your own instead
- Implemented fix for xdatefield code to support applyTo Config (thanks to mystix)
- updated russian locale (thanks to WhiteRussian)
- BUGFIX: updating eventclasses (and others) could result in wrong class-definition per cell (reported by aacraig)
V1.1 RC4 [2008/05/20]
- DateFieldPlus now also supports multiselection (thanks to Nohcs777)
- extended xdatefield to support multiselection
- "value" config for datefieldplus now also supports arrays in multiselection mode instead of just one date
- range selection is now also possible for a wider period than only the visible months (suggested by jo2008)
- updated xdatefield code integration to disable/enable the hidden submitfield from datefieldplus also, if the mainformfield gets disabled/enabled
- improved xdatefield code to fill the hiddenField with a given value at config time
- Improved some code-sections (mainly for respecting summertime changings when handling with Date.gettime())
- Corrected eventhandling on Datemenu and DateFieldPlus
- support for minDate and maxDate for Datefieldplus (as an alias for datepickers minValue and maxValue) to be more compatible to usual datepicker/datemenu config options
- added "multiSelectionDelimiter" config (datefieldplus and multiselection only)
- added "renderPrevNextButtons" config (if you want the user not to be able to change the month or force him to use the monthpicker)
- added "renderPrevNextYearButtons" config to display 2 small double-arrow buttons for changing next/previous year
- added "nextYearText" config which will be displayed as tooltip on NextYear Button (updated locale!)
- added "prevYearText" config which will be displayed as tooltip on PrevYear Button (updated locale!)
- added "showActiveDate" will display the active Date to use keynavigation
- added "shiftSpaceSelect" if set to true (default) and showactivedate is set to true you can select dates on keynavigation by using shift+Space (because the space-key alone will select the today-date)
if this is set to false , this behaviour reverses (shift+space selects today, space alone select the date under the shown activedate from keynavigation)
- added "disableMonthPicker" config
- added "disabledLetter" config to display e.g. a "X" instead of the daynumber if a date is disabled. (default false)
- added event "beforeyearchange"
- added event "afteryearchange"
- added russian locale (thanks to WhiteRussian)
- UP/DOWN/LEFT/RIGHT Keynavigation is now only available if showActiveDate is set to true and works much faster
- CTRL+UP/DOWN for year changing is now only available if either disableMonthPicker is false or renderPrevNextYearButtons is true
- CTRL+LEFT/RIGHT for month changing is now only available if either disableMonthPicker is false or renderPrevNextButtons is true
- BUGFIX: setEventDates did not update the viewport (reported by aacraig)
- BUGFIX: Array-Cloning was done in a wrong way (reported by lpfLoveExt)
- BUGFIX: weekselection was wrong when a different startDay was given (reported by WhiteRussian)
- Minor Upgrade Version because of much added features instead of a bugfix-only release
V1.0 RC3 [2008/04/21]
- checked to work with ExtJS 2.1
- added config strictRangeSelect (suggested by sigaref)
- added config displayMask and displayMaskText to support update masking
- added config defaultEventDatesText and defaultEventDatesCls. used if no text/cls-object is given in eventdates
- added Events "aftermonthchange" and "beforemonthchange" (fires everytime the first month changes (by monthpicker or prev/next-month buttons)
- added method setEventDates, to automatically transform given arrays/or objects to working functions, if not already specified
- BUGFIX: range selection over specific months was incorrect
V1.0 RC2 [2008/04/10]
- BUGFIX: typo in DateFieldPlus corrected (reported by sigaref)
V1.0 RC1 [2008/04/10]
- BUGFIX: Undo-Function works again
- BUGFIX: Config items allowedDates and allowedDatesText had no effect on DateFieldPlus
V0.9 Beta 9 [2008/04/09]
- Added config items allowedDates and allowedDatesText
- Added method setAllowedDates()
V0.9 Beta 8 [2008/04/09]
- BUGFIX: setSelectedDates had another BUG...(thanks to wehtam for reporting!)
V0.9 Beta 7 [2008/04/08]
- added the state of the afterdateclick to examine, if the date was selected or unselected, same with week/month
- added option to cleanSelectedDates to not update the picker (e.g. to immediatly add dates manually by setSelectedDates(that would call update twice)
- added option to setSelectedDates to clean the selectedDates before setting the new once and to not update the picker
- BUGFIX: setSelectedDates did not work properly
V0.9 Beta 6 [2008/04/08]
- Added method clearSelectedDates() (suggested by wehtam)
- Added method setSelectedDates() (suggested by wehtam)
- Changes eventtriggering for afterdateclick. It now will always be fired when a date is clicked . Regardless, whether multiSelection is enabled or not.
- BUGFIX: Given listeners to DateFieldPlus have been ignored (reported by Richie1985)
V0.9 Beta 5 [2008/04/07]
- Added method setDateLimits() to change minDate and maxDate at once at runtime
- BUGFIX: Range selection by using the SHIFT-Key for a range more than one month, did not select some remaining days at the end of the range (reported by Spirit)
V0.9 Beta 4 [2008/04/06]
- Added method setMinDate() to change the minDate at runtime and immediatly update the datepicker
- Added method setMaxDate() to change the maxDate at runtime and immediatly update the datepicker
- BUGFIX: hidden submitformat Field had same name as original field, thus confuses IE with duplicate id/name. if name has not been specified in the config or is same as id datefieldplus will add a suffix to the hiddenfield (default "-format"). this field holds the custom submitFormat value
V0.9 Beta 3 [2008/04/06]
- Added xtype "datefieldplus"
- BUGFIX: DateFieldPlus accidently had renderTodayButton set to false by default...
V0.9 Beta 2 [2008/04/06]
- BUGFIX: Width on DateMenu and DateFieldPlus was broken in Firefox 3 (tested on latest Beta 5) (reported by ludoo)
- BUGFIX: Some old testpath in generating transparent GIF images was left in the code and has been deleted now (reported by sanjshah)
- Added new config options
"disablePartialUnselect" : Boolean/String (default true) (suggested by DVSDevise)
When multiselecting whole months or weeks, already selected days within this week/month will _not_ get unselected anymore. Set this to false, if you want them to get unselected.
Note: When the _whole set_ of the month/week are already selected, they get _all_ unselected anyway.
"renderOkUndoButtons" : Boolean (default true) (suggested by jsakalos)
If set to false, the OK- and Undo-Buttons will not be rendered on Multiselection Calendars
This way any selected Date will be immediatly available in the "selectedDates" Array. If used together with DateMenu or DateFieldPlus you need to click outside the Calendar to make it disappear or press Return (if calendar got focus...)
Works only if multiSelection is set to true
"renderTodayButton" : Boolean (default true) (suggested by jsakalos)
Whether the Today-Button should be rendered
V0.9 Beta [2008/04/05]
Initial Release:
Joined the extensions together nicely and added even more features:
- fixed some bugs/improved the original extensions a bit
- works on Original DateMenu and DateField (Ext.ux.form.DateFieldPlus) also
- Definable Multimonths (rows,amount,fill..)
- Custom CSS for definable days
- Weeknumber Display
- Weekend CSS Styling
- National Holidays CSS Styling
- Quicktip support
- Function based custom displayed days
- Multiselection support by CTRL-Key to add single days (when clicked on a date)
- Multiselection support by CTRL-Key to add single weeks (when clicked on a weeknumber)
- Multiselection support by CTRL-Key to add single months (when clicked on the weeknumber header)
- Multiselection support by SHIFT-Key to add a range of days depending on the lastclicked day (when clicked on a single date)
- returned the prev/next monthbuttons to the monthlabelrow
- implemented mousewheel-event again for comfortable increasing/decreasing months
- implemented monthpicker again to comfortably select the starting month. the monthpicker is rendered on the very first monthname so with only 1 month given, it acts just like the original datepicker
- added quick dayselection routine without calling update() every time. MUCH faster selection, especially when using huge multimonth calendars!
- added "OK"- and "Undo"-Buttons when multiSelection is set to true
- unneccessary renderupdate trigger eliminated (performance-leak on huge multimonthcalendars!) (setvalue-function changed, much more faster now)
- prevented opening a new browsertab in IE7/IE8 when CTRL multiselecting (occured in original multimonth calendar extension and datepicker also if clicked on an empty area within the cell) (default behaviour for a-tags, prevented this by CSS)
- extend keynavigation (RETURN=ok-Button, CTRL as usual)
- added Tooltip functionality to DateFieldPlus just like Buttons (tooltip show on triggerbutton only, this way invalidtext tooltips stay intact)
- Tested in FF2/3/3.5,IE6/7/8,Op9/10b,Saf3/4(Win),Chrome2/3
- Default Language is (of course) english (including US Holidays!)
- Current available localization files (including Holidays):
german
russian
italian
dutch
french
norwegian
spanish
romanian
japanese
polish
english (for your own translations)
Create a copy of ext.ux.datepickerplus-lang-en.js and change it to your language settings to get this widget easily translated
Be sure to include it AFTER the datepickerwidget!
--- See Release-Notes for Full API Documentation ---
ROAD MAP:
v1.5 (~ Summer 2011)
- support stores for selectedDates, allowedDates, disabledDates and eventDates
- Check if given value for first renderered month stays within a given min/maxdate (suggested by bholyoak)
- add a config item to be able to hide specific dates just like disableddays but they are not even visible
- add a config item to be able to hide specific days (do not even display a column for that days)
- add an additional event when the Ok-button is clicked
- separate method to add/remove an eventdate or an array of eventdates without the need to supply the full set of eventdates
- same for disableddates/alloweddates/selecteddates (creating something like addAllowedDates/removeAllowedDates)
- support of multiple events at the same date
- support of month-gaps (e.g. display every 3rd Month only)
- support of descending month display on multimonths and navigation
- give eventdates tooltips more priority or merge them with the today/holidays tooltips (suggested by RuiDC)
- turned today button into cyclebutton to be able to also use "Begin of year" "next decade"...(idea from Peter seliger -> http://extjs.com/forum/showthread.php?t=61645)
- added "resizable" to support resizing of datepicker when displayed as datemenu or datefield and automatically create more/less months and adjust noOfMonth, noOfMonthPerRow
- support selection of all weekdays per month by clicking on the apropriate weekday shortcut column header
- support hovering a full week/month/days when moving the mouse over weekday/weeknumber/weeknumberheader
- support dateranges for eventdates
v1.6/2.0 (~ Fall 2011/Spring 2012)
- change monthselection to combobox selection of month and year as an option
- implement time selection also like http://extjs.com/forum/showthread.php?p=170472#post170472
- use the spinner plugin for above selections if available (or integrate it) or combobox instead (?)
- optional combobox as an alternative to the monthpicker with a given range of previous/next months to select from
- context menu to select predefined dates (12 months ago, next 3 thursdays, etc...thinking of integrating datejs for this ?)
- usage of window.createPopup for IE only to render more quickly (? based on http://extjs.com/forum/showthread.php?t=33331)
- create a new form.datelist item (select-box with multiselect and no dropdown) component to be able to display multiselected dates like datefield after selection
- add config to define the sorting of prevnext(year) buttons (currently the prevnextyear buttons are rendered inside as the usual prevnextmonth buttons are outside anytime)
- support drag selection of days/weeks/months (like in dataview example)
- extend property grid/create plugin to use datepickerplus aswell for date-fields in there
- show monthpicker only (requested in http://extjs.com/forum/showthread.php?t=13911)
- full support of editor grids
- support shiftclick without deleting all previous selected dates
- try to speed up rendering-performance, when clicking on next/previous month (update()) and on startup (onRender()) (IE and FF are much slower than Opera(which is equal slow, but renders immediatly every part of the calendar while IE/FF are rendering the complete calender at the end). Safari3.2(Win) and Chrome render very fast by now!
* ? BROWSER BUGS ? *
- FF2: CTRL-multiselect clicking leaves an odd blue frame on the cell when clicking in empty areas of the cell (the CSS-Trick for preventing new TABs in IE does not work here...yet :)
*/
Date.prototype.getFirstDateOfWeek = function(startDay) {
//set startDay to Sunday by default
if (typeof startDay === "undefined") {
startDay=(Ext.DatePicker?Ext.DatePicker.prototype.startDay:0);
}
var dayDiff = this.getDay()-startDay;
if (dayDiff<0) {
dayDiff+=7;
}
return this.add(Date.DAY,-dayDiff);
};
Array.prototype.sortDates = function() {
return this.sort(function(a,b){
return a.getTime() - b.getTime();
});
};
if (!Ext.util.EasterDate) {
Ext.util.EasterDate = function(year, plusDays) {
if (typeof year === "undefined") {
year = new Date().getFullYear();
}
year = parseInt(year,10);
if (typeof plusDays === "undefined") {
plusDays = 0;
}
plusDays = parseInt(plusDays,10);
//difference to first sunday after first fullmoon after beginning of spring
var a = year % 19;
var d = (19 * a + 24) % 30;
var diffDay = d + (2 * (year % 4) + 4 * (year % 7) + 6 * d + 5) % 7;
if ((diffDay == 35) || ((diffDay == 34) && (d == 28) && (a > 10))) {
diffDay -= 7;
}
var EasterDate = new Date(year, 2, 22); //beginning of spring
EasterDate.setTime(EasterDate.getTime() + 86400000 * diffDay + 86400000 * plusDays);
return EasterDate;
};
}
Ext.namespace('Ext.ux','Ext.ux.form');
/**
* @class Ext.ux.DatePickerPlus
* @extends Ext.DatePicker
* @constructor
* @param {Object} config The config object
*/
Ext.ux.DatePickerPlus = Ext.extend(Ext.DatePicker, {
version: "1.4.6",
/**
* @cfg {Number} noOfMonth
* No of Month to be displayed
* Default to 1 so it will displayed as original Datepicker
*/
noOfMonth : 1,
/**
* @cfg {Array} noOfMonthPerRow
* No. Of Month to be displayed in a row
*/
noOfMonthPerRow : 3,
/**
* @cfg {Array} fillupRows
* eventually extends the number of months to view to fit the given row/column matrix and avoid odd white gaps (especially when using as datemenu fill will lookup ugly when set to false
*/
fillupRows : true,
/**
* @cfg {Function returns Array} eventDates
* a Function which returns an Object List of Dates which have an event (show in separate given css-class)
* This function is called everytime a year has changed when rendering the calendar
* attributes are date, text(optional) and cls(optional)
* Its implemented as a function to be able to create cycling days for year
* example
* eventDates: function(year) {
var myDates =
[{
date: new Date(2008,0,1), //fixed date marked only on 2008/01/01
text: "New Year 2008",
cls: "x-datepickerplus-eventdates"
},
{
date: new Date(year,4,11), //will be marked every year on 05/11
text: "May 11th, Authors Birthday (Age:"+(year-1973)+")",
cls: "x-datepickerplus-eventdates"
}];
return myDates;
*
*
*/
eventDates : function(year) {
return [];
},
styleDisabledDates: false,
eventDatesSelectable : true,
defaultEventDatesText : '',
defaultEventDatesCls : 'x-datepickerplus-eventdates',
clickRepeaterConfig: {},
setEventDates : function(edArray,update) {
if (typeof update === "undefined") {
update=true;
}
this.edArray = [];
var i=0,il=edArray.length;
for (;i<il;++i) {
if (Ext.isDate(edArray[i])) {
this.edArray.push({
date:edArray[i],
text:this.defaultEventDatesText,
cls:this.defaultEventDatesCls
});
}
else if (edArray[i].date) {
edArray[i].date = this.jsonDate(edArray[i].date);
this.edArray.push(edArray[i]);
}
}
this.eventDates = function(year) {
return this.edArray;
};
if (this.rendered && update) {
this.eventDatesNumbered = this.convertCSSDatesToNumbers(this.eventDates(this.activeDate.getFullYear()));
this.update(this.activeDate);
}
},
/**
* @cfg {Boolean} eventDatesRE
* To selected specific Days over a regular expression
*/
eventDatesRE : false,
/**
* @cfg {String} eventDatesRECls
* Specifies what CSS Class will be applied to the days found by "eventDatesRE"
*/
eventDatesRECls : '',
/**
* @cfg {String} eventDatesRECls
* Specifies what Quicktip will be displayed to the days found by "eventDatesRE"
*/
eventDatesREText : '',
/**
* @cfg {Boolean} showWeekNumber
* Whether the week number should be shown
*/
showWeekNumber : true,
/**
* @cfg {String} weekName
* The short name of the week number column
*/
weekName : "Wk.",
/**
* @cfg {String} selectWeekText
* Text to display when hovering over the weekNumber and multiSelection is enabled
*/
selectWeekText : "Click to select all days of this week",
/**
* @cfg {String} selectMonthText
* Text to display when hovering over the MonthNumber and multiSelection is enabled
* Whole Month selection is disabled when displaying only 1 Month (think twice..)
*/
selectMonthText : "Click to select all weeks of this month",
/**
* @cfg {String} multiSelection
* whether multiselection of dates is allowed. selection of weeks depends on displaying of weeknumbers
*/
multiSelection : false,
/**
* @cfg {String} multiSelectByCTRL
* whether multiselection is made by pressing CTRL (default behaviour, a single click without CTRL will set the selection list to the last selected day/week) or without (ever click a day is added/removed)
*/
multiSelectByCTRL : true,
/**
* @cfg {Array of Dateobjects} selectedDates
* List of Dates which have been selected when multiselection is set to true (this.value only sets the startmonth then)
*/
selectedDates : [],
/**
* @cfg {String/Bool} prevNextDaysView
* "mark" selected days will be marke in prev/next months also
* "nomark" will not be marked and are not selectable
* false: will hide them, thus are not selectable too
*/
prevNextDaysView: "mark",
/**
* @cfg {Array of Dateobjects} preSelectedDates
* contains the same at selection runtime (until "OK" is pressed)
*/
preSelectedDates : [],
/**
* @cfg {Object} lastSelectedDate
* contains the last selected Date or false right after initializing the object..
*/
lastSelectedDate : false,
/**
* @cfg {Array} markNationalHolidays
* trigger to add existing nationalHolidays to the eventdates list (nationalholidays can be changed in locale files, so these are independant from custom event Dates
*/
markNationalHolidays :true,
/**
* @cfg {String} nationalHolidaysCls
* CSS Class displayed to national Holidays if markNationalHolidays is set to true
*/
nationalHolidaysCls : 'x-datepickerplus-nationalholidays',
/**
* @cfg {Function} nationalHolidays
* returns an Array-List of national Holiday Dates which could by marked with separate given CSS. Will be shown if markNationalHolidays is set to true
* Change this in your local file to override it with you country's own national Holiday Dates
*
* if markNationalHolidays is set to true, a new instance of this array (and thus recalculation of holidays) will be generated at month update, if year has been changed from last drawn month.
*
*/
nationalHolidays : function(year) {
year = (typeof year === "undefined" ? (this.lastRenderedYear ? this.lastRenderedYear : new Date().getFullYear()) : parseInt(year,10));
//per default the US national holidays are calculated (according to http://en.wikipedia.org/wiki/Public_holidays_of_the_United_States)
//override this function in your local file to calculate holidays for your own country
//but remember to include the locale file _AFTER_ datepickerplus !
var dayOfJan01 = new Date(year,0,1).getDay();
var dayOfFeb01 = new Date(year,1,1).getDay();
var dayOfMay01 = new Date(year,4,1).getDay();
var dayOfSep01 = new Date(year,8,1).getDay();
var dayOfOct01 = new Date(year,9,1).getDay();
var dayOfNov01 = new Date(year,10,1).getDay();
var holidays =
[{
text: "New Year's Day",
date: new Date(year,0,1)
},
{
text: "Martin Luther King Day", //(every third monday in january)
date: new Date(year,0,(dayOfJan01>1?16+7-dayOfJan01:16-dayOfJan01))
},
{
text: "Washington's Birthday", //(every third monday in february)
date: new Date(year,1,(dayOfFeb01>1?16+7-dayOfFeb01:16-dayOfFeb01))
},
{
text: "Memorial Day",//(last Monday in May)
date: new Date(year,4,(dayOfMay01==6?31:30-dayOfMay01))
},
{
text: "Independence Day",
date: new Date(year,6,4)
},
{
text: "Labor Day",//(every first monday in September)
date: new Date(year,8,(dayOfSep01>1?2+7-dayOfSep01:2-dayOfSep01))
},
{
text: "Columbus Day",//(every second monday in october)
date: new Date(year,9,(dayOfOct01>1?9+7-dayOfOct01:9-dayOfOct01))
},
{
text: "Veterans Day",
date: new Date(year,10,11)
},
{
text: "Thanksgiving Day",//(Fourth Thursday in November)
date: new Date(year,10,(dayOfNov01>4?26+7-dayOfNov01:26-dayOfNov01))
},
{
text: "Christmas Day",
date: new Date(year,11,25)
}];
return holidays;
},
/**
* @cfg {Boolean} markWeekends
* whether weekends should be displayed differently
*/
markWeekends :true,
/**
* @cfg {String} weekendCls
* CSS class to use for styling Weekends
*/
weekendCls : 'x-datepickerplus-weekends',
/**
* @cfg {String} weekendText
* Quicktip for Weekends
*/
weekendText :'',
/**
* @cfg {Array} weekendDays
* Array of Days (according to Days from dateobject thus Sunday=0,Monday=1,...Saturday=6)
* Additionally to weekends, you could use this to display e.g. every Tuesday and Thursday with a separate CSS class
*/
weekendDays: [6,0],
/**
* @cfg {Boolean} useQuickTips
* Wheter TIps should be displayed as Ext.quicktips or browsercontrolled title-attributes
*/
useQuickTips : true,
/**
* @cfg {Number} pageKeyWarp
* Amount of Months the picker will move forward/backward when pressing the pageUp/pageDown Keys
*/
pageKeyWarp : 1,
/**
* @cfg {Number} maxSelectionDays
* Amount of Days that are selectable, set to false for unlimited selection
*/
maxSelectionDays : false,
maxSelectionDaysTitle : 'Datepicker',
maxSelectionDaysText : 'You can only select a maximum amount of %0 days',
undoText : "Undo",
/**
* @cfg {Boolean} stayInAllowedRange
* used then mindate/maxdate is set to prevent changing to a month that does not contain allowed dates
*/
stayInAllowedRange: true,
/**
* @cfg {Boolean} summarizeHeader
* displays the from/to daterange on top of the datepicker
*/
summarizeHeader:false,
/**
* @cfg {Boolean} resizable
* Whether the calendar can be extended with more/less months by simply resizing it like window
*/
resizable: false,
/**
* @cfg {Boolean} renderOkUndoButtons
* If set to true, the OK- and Undo-Buttons will not be rendered on Multiselection Calendars
*/
renderOkUndoButtons : true,
/**
* @cfg {Boolean} renderTodayButton
* Whether the Today Button should be rendered
*/
renderTodayButton : true,
/**
* @cfg {Boolean} disablePartialUnselect
* When multiselecting whole months or weeks, already selected days within this week/month will _not_ get unselected anymore. Set this to false, if you want them to get unselected.
* Note: When the _whole set_ of the month/week are already selected, they get _all_ unselected anyway.
*/
disablePartialUnselect: true,
allowedDates : false,
allowedDatesText : '',
strictRangeSelect : false,
/**
* @cfg {Boolean/Number} displayMask
* As huge multimonth calendars can take some updating time this will display a mask when the noOfMonth property is higher than the given value in displayMask.
* Set to false to never display the mask
* default is 3
*/
displayMask:3,
displayMaskText: 'Please wait...',
renderPrevNextButtons: true,
renderPrevNextYearButtons: false,
disableMonthPicker:false,
nextYearText: "Next Year (Control+Up)",
prevYearText: "Previous Year (Control+Down)",
showActiveDate: false,
shiftSpaceSelect: true,
disabledLetter: false,
allowMouseWheel: true,
//this is accidently called too often in the original (when hovering over monthlabel or bottombar..there is no need to update the cells again and just leaks performance)
focus: Ext.emptyFn,
initComponent : function(){
Ext.ux.DatePickerPlus.superclass.initComponent.call(this);
this.noOfMonthPerRow = this.noOfMonthPerRow > this.noOfMonth ?this.noOfMonth : this.noOfMonthPerRow;
this.addEvents(
/**
* @event beforeyearchange
* Fires before a new year is selected (or prevYear/nextYear buttons)
* @param {DatePicker} this
* @param {oldyearnumber} dates The previous selected year
* @param {newyearnumber} dates The new selected year
*/
'beforeyearchange',
/**
* @event afteryearchange
* Fires before a new year is selected (by prevYear/nextYear buttons)
* @param {DatePicker} this
* @param {oldyearnumber} dates The previous selected year
* @param {newyearnumber} dates The new selected year
*/
'afteryearchange',
/**
* @event beforemonthchange
* Fires before a new startmonth is selected (by monthpicker or prev/next buttons)
* @param {DatePicker} this
* @param {oldmonthnumber} dates The previous selected month
* @param {newmonthnumber} dates The new selected month
*/
'beforemonthchange',
/**
* @event aftermonthchange
* Fires before a new startmonth is selected (by monthpicker or prev/next buttons)
* @param {DatePicker} this
* @param {oldmonthnumber} dates The previous selected month
* @param {newmonthnumber} dates The new selected month
*/
'aftermonthchange',
/**
* @event beforemonthclick
* Fires before a full month is (un)selected
* @param {DatePicker} this
* @param {monthnumber} dates The selected month
*/
'beforemonthclick',
/**
* @event beforeweekclick
* Fires before a week is (un)selected
* @param {DatePicker} this
* @param {dateobject} dates The first date of selected week
*/
'beforeweekclick',
/**
* @event beforeweekclick
* Fires before a single day is (un)selected
* @param {DatePicker} this
* @param {dateobject} dates The selected date
*/
'beforedateclick',
/**
* @event aftermonthclick
* Fires after a full month is (un)selected
* @param {DatePicker} this
* @param {monthnumber} dates The selected month
*/
'aftermonthclick',
/**
* @event afterweekclick
* Fires after a week is (un)selected
* @param {DatePicker} this
* @param {dateobject} dates The first date of selected week
*/
'afterweekclick',
/**
* @event afterweekclick
* Fires after a single day is (un)selected
* @param {DatePicker} this
* @param {dateobject} dates The selected date
*/
'afterdateclick',
/**
* @event undo
* Fires when Undo Button is clicked on multiselection right before deleting the preselected dates
* @param {DatePicker} this
* @param {Array} dates The preselected Dates
*/
'undo',
/**
* @event beforemousewheel
* Fires before a mousewheel event should be triggered return false in your function to disable the month change
* @param {DatePicker} this
* @param {object} event object
*/
'beforemousewheel',
/**
* @event beforemousewheel
* Fires before the default message box appears when max days have been reached
* return false to cancel the messagebox (to do something on your own)
* @param {DatePicker} this
* @param {object} event object
*/
'beforemaxdays');
},
activeDateKeyNav: function(direction) {
if (this.showActiveDate) {
this.activeDate = this.activeDate.add("d", direction);
var adCell = this.activeDateCell.split("#");
var tmpMonthCell = parseInt(adCell[0],10);
var tmpDayCell = parseInt(adCell[1],10);
var currentGetCell = Ext.get(this.cellsArray[tmpMonthCell].elements[tmpDayCell]);
//cursor gets out of visible range?
if ( (tmpDayCell+direction>41 && tmpMonthCell+1>=this.cellsArray.length) ||
(tmpDayCell+direction<0 && tmpMonthCell-1<0) ){
this.update(this.activeDate);
}
else {
currentGetCell.removeClass("x-datepickerplus-activedate");
tmpDayCell+=direction;
if (tmpDayCell>41) {
tmpDayCell-=42;
tmpMonthCell++;
}
else if (tmpDayCell<0) {
tmpDayCell+=42;
tmpMonthCell--;
}
currentGetCell = Ext.get(this.cellsArray[tmpMonthCell].elements[tmpDayCell]);
currentGetCell.addClass("x-datepickerplus-activedate");
this.activeDateCell = tmpMonthCell+"#"+tmpDayCell;
}
}
},
handleMouseWheel : function(e){
if(this.fireEvent("beforemousewheel", this,e) !== false){
var oldStartMonth = (this.activeDate ? this.activeDate.getMonth() : 99);
var oldStartYear = (this.activeDate ? this.activeDate.getFullYear() : 0);
Ext.ux.DatePickerPlus.superclass.handleMouseWheel.call(this,e);
var newStartMonth = (this.activeDate ? this.activeDate.getMonth() : 999);
var newStartYear = (this.activeDate ? this.activeDate.getFullYear() : 9999);
if (oldStartMonth!=newStartMonth) {
this.fireEvent("aftermonthchange", this, oldStartMonth, newStartMonth);
}
if (oldStartYear!=newStartYear) {
this.fireEvent("afteryearchange", this, oldStartYear, newStartYear);
}
}
},
doDisabled: function(disabled){
this.keyNav.setDisabled(disabled);
if (this.renderPrevNextButtons) {
this.leftClickRpt.setDisabled(disabled);
this.rightClickRpt.setDisabled(disabled);
}
if (this.renderPrevNextYearButtons) {
this.leftYearClickRpt.setDisabled(disabled);
this.rightYearClickRpt.setDisabled(disabled);
}
if(this.todayBtn){
this.todayKeyListener.setDisabled(disabled);
this.todayBtn.setDisabled(disabled);
}
},
// private
onRender : function(container, position){
if (this.noOfMonthPerRow===0) {
this.noOfMonthPerRow = 1;
}
if (this.fillupRows && this.noOfMonthPerRow > 1 && this.noOfMonth % this.noOfMonthPerRow!==0) {
this.noOfMonth+= (this.noOfMonthPerRow - (this.noOfMonth % this.noOfMonthPerRow));
}
var addIEClass = (Ext.isIE?' x-datepickerplus-ie':'');
var m = ['<table cellspacing="0"',(this.multiSelection?' class="x-date-multiselect'+addIEClass+'" ':(addIEClass!==''?'class="'+addIEClass+'" ':'')),'>'];
m.push("<tr>");
var widfaker = (Ext.isIE?'<img src="'+Ext.BLANK_IMAGE_URL+'" />':'');
var weekNumberQuickTip = (this.multiSelection ? (this.useQuickTips? ' ext:qtip="'+this.selectWeekText+'" ' :' title="'+this.selectWeekText+'" ') : '');
//as weekends (or defined weekly cycles) are displayed on every month at the same place, we can render the quicktips here to save time in update process
var weekEndQuickTip = (this.markWeekends && this.weekendText!==''? (this.useQuickTips? ' ext:qtip="'+this.weekendText+'" ' :' title="'+this.weekendText+'" '):'');
//calculate the HTML of one month at first to gain some speed when rendering many calendars
var mpre = ['<thead><tr>'];
if (this.showWeekNumber) {
mpre.push('<th class="x-date-weeknumber-header"><a href="#" hidefocus="on" class="x-date-weeknumber" tabIndex="1"><em><span ',(this.multiSelection ? (this.useQuickTips? ' ext:qtip="'+this.selectMonthText+'" ' :' title="'+this.selectMonthText+'" ') : ''),'>' + this.weekName + '</span></em></a></th>');
}
var dn = this.dayNames, i=0, d, k = 0, x=0, xk=this.noOfMonth;
for(; i < 7; ++i){
d = this.startDay+i;
if(d > 6){
d = d-7;
}
mpre.push('<th><span>', dn[d].substr(0,1), '</span></th>');
}
mpre.push('</tr></thead><tbody><tr>');
if (this.showWeekNumber) {
mpre.push('<td class="x-date-weeknumber-cell"><a href="#" hidefocus="on" class="x-date-weeknumber" tabIndex="1"><em><span ',weekNumberQuickTip,'></span></em></a></td>');
}
for(; k < 42; ++k) {
if(k % 7 === 0 && k > 0){
if (this.showWeekNumber) {
mpre.push('</tr><tr><td class="x-date-weeknumber-cell"><a href="#" hidefocus="on" class="x-date-weeknumber" tabIndex="1"><em><span ',weekNumberQuickTip,'></span></em></a></td>');
} else {
mpre.push('</tr><tr>');
}
}
mpre.push('<td class="x-date-date-cell"><a href="#" hidefocus="on" class="x-date-date" tabIndex="1"><em><span ',(this.weekendDays.indexOf((k+this.startDay)%7)!=-1?weekEndQuickTip:''),'></span></em></a></td>');
}
mpre.push('</tr></tbody></table></td></tr></table></td>');
var prerenderedMonth = mpre.join("");
if (this.summarizeHeader && this.noOfMonth > 1) {
m.push('<td align="center" id="',this.id,'-summarize" colspan="',this.noOfMonthPerRow,'" class="x-date-middle x-date-pickerplus-middle"></td></tr>');
m.push("<tr>");
}