Skip to content

Commit 3d11ca7

Browse files
committed
Merge remote branch 'hanshillen/datepicker-hh' into datepicker
2 parents 193bdd6 + 915847f commit 3d11ca7

File tree

3 files changed

+128
-34
lines changed

3 files changed

+128
-34
lines changed

datepicker-rewrite/date.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ $.date = function ( datestring, formatstring ) {
3434
var day = period == "D" ? date.getDate() + offset : date.getDate(),
3535
month = period == "M" ? date.getMonth() + offset : date.getMonth(),
3636
year = period == "Y" ? date.getFullYear() + offset : date.getFullYear();
37+
38+
if ( period != "D" ) {
39+
day = Math.max(1, Math.min( day, this.daysInMonth( year, month ) ) );
40+
}
3741
date = new Date( year, month, day );
3842
return this;
3943
},
@@ -45,6 +49,12 @@ $.date = function ( datestring, formatstring ) {
4549
monthname: function() {
4650
return calendar.months.names[ date.getMonth() ];
4751
},
52+
day: function() {
53+
return date.getDate();
54+
},
55+
month: function() {
56+
return date.getMonth();
57+
},
4858
year: function() {
4959
return date.getFullYear();
5060
},
@@ -55,7 +65,7 @@ $.date = function ( datestring, formatstring ) {
5565
var day = ( dow + calendar.firstDay ) % 7;
5666
result.push( {
5767
shortname: calendar.days.namesShort[ day ],
58-
fullname: calendar.days.names[ day ],
68+
fullname: calendar.days.names[ day ]
5969
});
6070
}
6171
return result;

datepicker-rewrite/index.html

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
<style>
2020
body { font:62.5% Verdana,Arial,sans-serif; }
2121
.ui-datepicker-multi-3 { width: 51em !important; }
22+
23+
.ui-datepicker-calendar a.ui-state-focus {
24+
text-decoration: underline;
25+
}
2226
</style>
2327
</head>
2428
<body>
@@ -79,7 +83,7 @@
7983
}
8084
});
8185
$( "#datepicker, #datepicker2" ).datepicker();
82-
86+
8387
var input = $("#datepicker3");
8488
var button = $("<button>").insertAfter(input);
8589
var picker = $("<div>").css( {
@@ -100,31 +104,36 @@
100104
</script>
101105

102106
<script id="ui-datepicker-tmpl" type="text/x-jquery-tmpl">
103-
<div class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all">
107+
<div class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all" role="region" aria-labelledby="${instance.id} + "-title"">
104108
<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix ui-corner-all">
105-
<a class="ui-datepicker-prev ui-corner-all" title="${labels.prevText}"><span class="ui-icon ui-icon-circle-triangle-w">${labels.prevText}</span></a>
106-
<a class="ui-datepicker-next ui-corner-all" title="${labels.nextText}"><span class="ui-icon ui-icon-circle-triangle-e">${labels.nextText}</span></a>
107-
<div class="ui-datepicker-title">
108-
<span class="ui-datepicker-month">${date.monthname()}</span> <span class="ui-datepicker-year">${date.year()}</span>
109+
<a href="#" class="ui-datepicker-prev ui-corner-all" title="${labels.prevText}"><span class="ui-icon ui-icon-circle-triangle-w">${labels.prevText}</span></a>
110+
<a href="#" class="ui-datepicker-next ui-corner-all" title="${labels.nextText}"><span class="ui-icon ui-icon-circle-triangle-e">${labels.nextText}</span></a>
111+
<div role="header" id="${instance.id} + "-title"" class="ui-datepicker-title" aria-live="assertive" aria-atomic="true">
112+
<div id="${instance.id}-month-lbl">
113+
<span class="ui-datepicker-month">${date.monthname()}</span> <span class="ui-datepicker-year">${date.year()}</span>
114+
</div>
115+
<span class="ui-helper-hidden-accessible">Date Picker</span>
109116
</div>
110117
</div>
111-
<table class="ui-datepicker-calendar">
112-
<thead>
113-
<tr>
118+
<table class="ui-datepicker-calendar" role="grid" aria-labelledby="${instance.id}-month-lbl" tabindex="0" aria-activedescendant="${instance.id}-${instance.focusedDay}">
119+
<thead role="presentation">
120+
<tr role="row">
114121
{{each(index, day) date.weekdays()}}
115-
<th class=""><span title="${day.fullname}">${day.shortname}</span></th>
122+
<th class="" role="columnheader" abbr="${day.fullname}" aria-label="${day.fullname}"><span title="${day.fullname}">${day.shortname}</span></th>
116123
{{/each}}
117124
</tr>
118125
</thead>
119-
<tbody>
120-
{{each(index, week) date.days()}}
121-
<tr>
122-
{{each(index, day) week.days}}
123-
<td>
126+
<tbody role="presentation">
127+
{{each(weekIndex, week) date.days()}}
128+
<tr role="row">
129+
{{each(dayIndex, day) week.days}}
130+
<td {{if day.render}}id="${instance.id}-${day.date}"{{/if}} role="gridcell" aria-selected="{{if day.current}}true{{else}}false{{/if}}" {{if !day.selectable}}aria-disabled="true"{{/if}}>
124131
{{if day.render}}
125132
{{if day.selectable}}
126-
<a title="${day.title}" class="ui-state-default{{if day.current}} ui-state-active{{/if}}{{if day.today}} ui-state-highlight{{/if}} ${day.extraClasses}" href="#">
133+
<a title="${day.title}" class="{{if day.date == instance.focusedDay}}ui-state-focus {{/if}}ui-state-default{{if day.current}} ui-state-active{{/if}}{{if day.today}} ui-state-highlight{{/if}} ${day.extraClasses}" href="#" tabindex="-1" data-day=${day.date}>
127134
${day.date}
135+
{{if day.today}} <span class="ui-helper-hidden-accessible">, today</span>{{/if}}
136+
{{if day.current}}<span class="ui-helper-hidden-accessible">, selected</span>{{/if}}
128137
</a>
129138
{{/if}}
130139
{{if !day.selectable}}
@@ -145,7 +154,7 @@
145154
</div>
146155
</div>
147156
</script>
148-
157+
149158
<script id="ui-datepicker-weeks-tmpl" type="text/x-jquery-tmpl">
150159
<div class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all">
151160
<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix ui-corner-all">
@@ -193,29 +202,29 @@
193202

194203
<script id="ui-datepicker-multi-tmpl" type="text/x-jquery-tmpl">
195204
<div class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-datepicker-multi-3 ui-datepicker-multi">
196-
{{each(index, month) date.months(2)}}
205+
{{each(index, monthObj) date.months(2)}}
197206
<div class="ui-datepicker-group">
198-
<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix {{if month.first}}ui-corner-left{{/if}}{{if month.last}}ui-corner-right{{/if}}">
199-
{{if month.first}}
207+
<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix {{if monthObj.first}}ui-corner-left{{/if}}{{if monthObj.last}}ui-corner-right{{/if}}">
208+
{{if monthObj.first}}
200209
<a class="ui-datepicker-prev ui-corner-all" title="${labels.prevText}"><span class="ui-icon ui-icon-circle-triangle-w">${labels.prevText}</span></a>
201210
{{/if}}
202-
{{if month.last}}
211+
{{if monthObj.last}}
203212
<a class="ui-datepicker-next ui-corner-all" title="${labels.nextText}"><span class="ui-icon ui-icon-circle-triangle-e">${labels.nextText}</span></a>
204213
{{/if}}
205214
<div class="ui-datepicker-title">
206-
<span class="ui-datepicker-month">${month.monthname()}</span> <span class="ui-datepicker-year">${month.year()}</span>
215+
<span class="ui-datepicker-month">${monthObj.monthname()}</span> <span class="ui-datepicker-year">${monthObj.year()}</span>
207216
</div>
208217
</div>
209218
<table class="ui-datepicker-calendar">
210219
<thead>
211220
<tr>
212-
{{each(index, day) month.weekdays()}}
221+
{{each(index, day) monthObj.weekdays()}}
213222
<th class=""><span title="${day.fullname}">${day.shortname}</span></th>
214223
{{/each}}
215224
</tr>
216225
</thead>
217226
<tbody>
218-
{{each(index, week) month.days()}}
227+
{{each(index, week) monthObj.days()}}
219228
<tr>
220229
{{each(index, day) week.days}}
221230
<td>

datepicker-rewrite/picker.js

Lines changed: 84 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
/*
22
* Experimental datepicker rewrite to evaluate jquery-tmpl.
3-
*
3+
*
44
* Based on Marc Grabanski's https://github.com/1Marc/jquery-ui-datepicker-lite
55
*/
66
(function( $, undefined ) {
77

8+
var idIncrement = 0;
89
$.widget( "ui.datepicker", {
910
options: {
1011
eachDay: $.noop,
@@ -18,6 +19,8 @@ $.widget( "ui.datepicker", {
1819
var self = this;
1920
this.date = $.date();
2021
this.date.eachDay = this.options.eachDay;
22+
this.id = "ui-datepicker-" + idIncrement;
23+
idIncrement++;
2124
if ( this.element.is( "input" ) ) {
2225
self._bind( {
2326
click: "open",
@@ -39,50 +42,122 @@ $.widget( "ui.datepicker", {
3942
});
4043
this.picker.delegate( ".ui-datepicker-next", "click", function( event ) {
4144
event.preventDefault();
42-
self.date.adjust( "M", +1 )
45+
self.date.adjust( "M", 1 );
4346
self.refresh();
4447
});
4548
this.picker.delegate( ".ui-datepicker-calendar a", "click", function( event ) {
4649
event.preventDefault();
4750
// TODO exclude clicks on lead days or handle them correctly
4851
// 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();
5053
if ( !self.inline ) {
5154
self.element.val( self.date.format() );
5255
self.close();
5356
} else {
5457
self.refresh();
5558
}
5659
self._trigger( "select", event, {
57-
date: self.date.format(),
60+
date: self.date.format()
5861
});
5962
});
60-
63+
6164
this.picker.delegate( ".ui-datepicker-header a, .ui-datepicker-calendar a", "mouseenter.datepicker mouseleave.datepicker", function() {
6265
$( this ).toggleClass( "ui-state-hover" );
6366
});
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+
65134
this.refresh();
66135
},
67136
refresh: function() {
68137
this.date.refresh();
69138
this.picker.empty();
70139

140+
//determine which day gridcell to focus after refresh
141+
//TODO: Prevent disabled cells from being focused
142+
var focusedDay = this.date.day();
143+
71144
$( this.options.tmpl ).tmpl( {
72145
date: this.date,
73-
labels: $.global.localize( "datepicker" )
146+
labels: $.global.localize( "datepicker" ),
147+
instance : {id : this.id, focusedDay : focusedDay}
74148
}).appendTo( this.picker )
75149
.find( "button" ).button().end()
76150

77151
if ( this.inline ) {
78152
this.picker.children().addClass( "ui-datepicker-inline" );
79-
}
153+
}
80154
// against display:none in datepicker.css
81155
this.picker.find( ".ui-datepicker" ).css( "display", "block" );
156+
this.grid = this.picker.find( ".ui-datepicker-calendar" );
82157
},
83158
open: function( event ) {
84159
this.picker.fadeIn( "fast" );
85-
160+
86161
this.picker.position( $.extend( {
87162
of: this.element
88163
}, this.options.position ));

0 commit comments

Comments
 (0)