1
1
/*
2
2
* Experimental datepicker rewrite to evaluate jquery-tmpl.
3
- *
3
+ *
4
4
* Based on Marc Grabanski's https://github.com/1Marc/jquery-ui-datepicker-lite
5
5
*/
6
6
( function ( $ , undefined ) {
7
7
8
+ var idIncrement = 0 ;
8
9
$ . widget ( "ui.datepicker" , {
9
10
options : {
10
11
eachDay : $ . noop ,
@@ -18,6 +19,8 @@ $.widget( "ui.datepicker", {
18
19
var self = this ;
19
20
this . date = $ . date ( ) ;
20
21
this . date . eachDay = this . options . eachDay ;
22
+ this . id = "ui-datepicker-" + idIncrement ;
23
+ idIncrement ++ ;
21
24
if ( this . element . is ( "input" ) ) {
22
25
self . _bind ( {
23
26
click : "open" ,
@@ -39,50 +42,122 @@ $.widget( "ui.datepicker", {
39
42
} ) ;
40
43
this . picker . delegate ( ".ui-datepicker-next" , "click" , function ( event ) {
41
44
event . preventDefault ( ) ;
42
- self . date . adjust ( "M" , + 1 )
45
+ self . date . adjust ( "M" , 1 ) ;
43
46
self . refresh ( ) ;
44
47
} ) ;
45
48
this . picker . delegate ( ".ui-datepicker-calendar a" , "click" , function ( event ) {
46
49
event . preventDefault ( ) ;
47
50
// TODO exclude clicks on lead days or handle them correctly
48
51
// TODO store/read more then just date, also required for multi month picker
49
- self . date . setDay ( + $ ( this ) . text ( ) ) . select ( ) ;
52
+ self . date . setDay ( + $ ( this ) . data ( "day" ) ) . select ( ) ;
50
53
if ( ! self . inline ) {
51
54
self . element . val ( self . date . format ( ) ) ;
52
55
self . close ( ) ;
53
56
} else {
54
57
self . refresh ( ) ;
55
58
}
56
59
self . _trigger ( "select" , event , {
57
- date : self . date . format ( ) ,
60
+ date : self . date . format ( )
58
61
} ) ;
59
62
} ) ;
60
-
63
+
61
64
this . picker . delegate ( ".ui-datepicker-header a, .ui-datepicker-calendar a" , "mouseenter.datepicker mouseleave.datepicker" , function ( ) {
62
65
$ ( this ) . toggleClass ( "ui-state-hover" ) ;
63
66
} ) ;
64
-
67
+
68
+
69
+ this . picker . delegate ( ".ui-datepicker-calendar" , "keydown" , function ( event ) {
70
+ if ( jQuery . inArray ( event . keyCode , [ 13 , 33 , 34 , 35 , 36 , 37 , 38 , 39 , 40 ] ) == - 1 ) {
71
+ //only interested navigation keys
72
+ return ;
73
+ }
74
+ event . stopPropagation ( ) ;
75
+ event . preventDefault ( ) ;
76
+
77
+ var noDateChange = false ,
78
+ activeCell = $ ( "#" + self . grid . attr ( "aria-activedescendant" ) )
79
+ oldMonth = self . date . month ( ) ;
80
+ oldYear = self . date . year ( ) ;
81
+
82
+ switch ( event . keyCode ) {
83
+ case $ . ui . keyCode . ENTER :
84
+ activeCell . children ( "a" ) . first ( ) . click ( ) ;
85
+ self . grid . focus ( 1 ) ;
86
+ return ;
87
+ break ;
88
+ case $ . ui . keyCode . PAGE_UP :
89
+ self . date . adjust ( event . ctrlKey || event . metaKey ? "Y" : "M" , 1 ) ;
90
+ break ;
91
+ case $ . ui . keyCode . PAGE_DOWN :
92
+ self . date . adjust ( event . ctrlKey || event . metaKey ? "Y" : "M" , - 1 ) ;
93
+ break ;
94
+ case $ . ui . keyCode . END :
95
+ self . date . setDay ( self . date . daysInMonth ( ) ) ;
96
+ break ;
97
+ case $ . ui . keyCode . HOME :
98
+ self . date . setDay ( 1 ) ;
99
+ break ;
100
+ case $ . ui . keyCode . LEFT :
101
+ self . date . adjust ( "D" , - 1 ) ;
102
+ break ;
103
+ case $ . ui . keyCode . UP :
104
+ self . date . adjust ( "D" , - 7 ) ;
105
+ break ;
106
+ case $ . ui . keyCode . RIGHT :
107
+ self . date . adjust ( "D" , 1 ) ;
108
+ break ;
109
+ case $ . ui . keyCode . DOWN :
110
+ self . date . adjust ( "D" , 7 ) ;
111
+ break ;
112
+ default :
113
+ return ;
114
+ }
115
+
116
+ if ( self . date . month ( ) != oldMonth || self . date . year ( ) != oldYear ) {
117
+ self . refresh ( ) ;
118
+ self . grid . focus ( 1 ) ;
119
+ }
120
+ else {
121
+ var newId = self . id + "-" + self . date . day ( ) ,
122
+ newCell = $ ( "#" + newId ) ;
123
+
124
+ if ( ! newCell . length ) {
125
+ return ;
126
+ }
127
+ self . grid . attr ( "aria-activedescendant" , newId ) ;
128
+
129
+ activeCell . children ( "a" ) . removeClass ( "ui-state-focus" ) ;
130
+ newCell . children ( "a" ) . addClass ( "ui-state-focus" ) ;
131
+ }
132
+ } ) ;
133
+
65
134
this . refresh ( ) ;
66
135
} ,
67
136
refresh : function ( ) {
68
137
this . date . refresh ( ) ;
69
138
this . picker . empty ( ) ;
70
139
140
+ //determine which day gridcell to focus after refresh
141
+ //TODO: Prevent disabled cells from being focused
142
+ var focusedDay = this . date . day ( ) ;
143
+
71
144
$ ( this . options . tmpl ) . tmpl ( {
72
145
date : this . date ,
73
- labels : $ . global . localize ( "datepicker" )
146
+ labels : $ . global . localize ( "datepicker" ) ,
147
+ instance : { id : this . id , focusedDay : focusedDay }
74
148
} ) . appendTo ( this . picker )
75
149
. find ( "button" ) . button ( ) . end ( )
76
150
77
151
if ( this . inline ) {
78
152
this . picker . children ( ) . addClass ( "ui-datepicker-inline" ) ;
79
- }
153
+ }
80
154
// against display:none in datepicker.css
81
155
this . picker . find ( ".ui-datepicker" ) . css ( "display" , "block" ) ;
156
+ this . grid = this . picker . find ( ".ui-datepicker-calendar" ) ;
82
157
} ,
83
158
open : function ( event ) {
84
159
this . picker . fadeIn ( "fast" ) ;
85
-
160
+
86
161
this . picker . position ( $ . extend ( {
87
162
of : this . element
88
163
} , this . options . position ) ) ;
0 commit comments