mirror of
https://github.com/jquery/jquery-ui.git
synced 2025-01-07 20:34:24 +00:00
Calendar: Fix month jumping WIP
Fixes multiple-month demo and other-month demo.
This commit is contained in:
parent
ec0d679e64
commit
4c2229fc51
2
external/date.js
vendored
2
external/date.js
vendored
@ -151,6 +151,8 @@ $.date.prototype = {
|
|||||||
var day = week.days[ week.days.length ] = {
|
var day = week.days[ week.days.length ] = {
|
||||||
lead: printDate.getMonth() != date.getMonth(),
|
lead: printDate.getMonth() != date.getMonth(),
|
||||||
date: printDate.getDate(),
|
date: printDate.getDate(),
|
||||||
|
month: printDate.getMonth(),
|
||||||
|
year: printDate.getFullYear(),
|
||||||
timestamp: printDate.getTime(),
|
timestamp: printDate.getTime(),
|
||||||
today: today.equal( printDate )
|
today: today.equal( printDate )
|
||||||
};
|
};
|
||||||
|
@ -62,26 +62,26 @@ return $.widget( "ui.calendar", {
|
|||||||
this.buttonClickContext = this.element[ 0 ];
|
this.buttonClickContext = this.element[ 0 ];
|
||||||
|
|
||||||
this.date = $.date( this.options.value, this.options.dateFormat );
|
this.date = $.date( this.options.value, this.options.dateFormat );
|
||||||
this.date.eachDay = this.options.eachDay;
|
this.viewDate = this.date.clone();
|
||||||
this.options.value = this.date.date();
|
this.viewDate.eachDay = this.options.eachDay;
|
||||||
|
|
||||||
this._on( this.element, {
|
this._on( this.element, {
|
||||||
"click .ui-calendar-prev": function( event ) {
|
"click .ui-calendar-prev": function( event ) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.date.adjust( "M", -this.options.numberOfMonths );
|
this.date.adjust( "M", -this.options.numberOfMonths );
|
||||||
this.refresh();
|
this._refresh();
|
||||||
},
|
},
|
||||||
"click .ui-calendar-next": function( event ) {
|
"click .ui-calendar-next": function( event ) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.date.adjust( "M", this.options.numberOfMonths );
|
this.date.adjust( "M", this.options.numberOfMonths );
|
||||||
this.refresh();
|
this._refresh();
|
||||||
},
|
},
|
||||||
"mousedown .ui-calendar-calendar button": function( event ) {
|
"mousedown .ui-calendar-calendar button": function( event ) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
// TODO Exclude clicks on lead days or handle them correctly
|
this._setOption( "value", new Date( $( event.currentTarget ).data( "timestamp" ) ) );
|
||||||
// TODO Store/read more then just date, also required for multi month picker
|
this.refresh();
|
||||||
this._select( event, $( event.currentTarget ).data( "timestamp" ) );
|
this._trigger( "select", event );
|
||||||
this.grid.focus();
|
this.grid.focus();
|
||||||
},
|
},
|
||||||
"mouseenter .ui-calendar-header button": "_hover",
|
"mouseenter .ui-calendar-header button": "_hover",
|
||||||
@ -99,10 +99,6 @@ return $.widget( "ui.calendar", {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_handleKeydown: function( event ) {
|
_handleKeydown: function( event ) {
|
||||||
var oldMonth = this.date.month(),
|
|
||||||
oldYear = this.date.year();
|
|
||||||
|
|
||||||
// TODO: Handle for pickers with multiple months
|
|
||||||
switch ( event.keyCode ) {
|
switch ( event.keyCode ) {
|
||||||
case $.ui.keyCode.ENTER:
|
case $.ui.keyCode.ENTER:
|
||||||
this.activeDescendant.mousedown();
|
this.activeDescendant.mousedown();
|
||||||
@ -136,16 +132,26 @@ return $.widget( "ui.calendar", {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( this.date.month() !== oldMonth || this.date.year() !== oldYear ) {
|
if ( this._needsRefresh() ) {
|
||||||
this.refresh();
|
this._refresh();
|
||||||
this.grid.focus();
|
this.grid.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
this._setActiveDescendant();
|
this._setActiveDescendant();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_needsRefresh: function() {
|
||||||
|
if ( this.date.month() !== this.viewDate.month() || this.date.year() !== this.viewDate.year() ) {
|
||||||
|
return !this.grid.find(
|
||||||
|
this._sanitizeSelector( "#" + this._getDayId( this.date ) )
|
||||||
|
).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
_setActiveDescendant: function() {
|
_setActiveDescendant: function() {
|
||||||
var id = this.id + "-" + this.date.day();
|
var id = this._getDayId( this.date );
|
||||||
|
|
||||||
this.grid
|
this.grid
|
||||||
.attr( "aria-activedescendant", id )
|
.attr( "aria-activedescendant", id )
|
||||||
@ -184,14 +190,14 @@ return $.widget( "ui.calendar", {
|
|||||||
_buildMultiplePicker: function() {
|
_buildMultiplePicker: function() {
|
||||||
var headerClass,
|
var headerClass,
|
||||||
html = "",
|
html = "",
|
||||||
currentDate = this.date,
|
currentDate = this.viewDate,
|
||||||
months = this.date.months( this.options.numberOfMonths - 1 ),
|
months = this.viewDate.months( this.options.numberOfMonths - 1 ),
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
for ( ; i < months.length; i++ ) {
|
for ( ; i < months.length; i++ ) {
|
||||||
|
|
||||||
// TODO: Shouldn't we pass date as a parameter to build* fns instead of setting this.date?
|
// TODO: Shouldn't we pass date as a parameter to build* fns instead of setting this.date?
|
||||||
this.date = months[ i ];
|
this.viewDate = months[ i ];
|
||||||
headerClass = "ui-calendar-header ui-widget-header ui-helper-clearfix";
|
headerClass = "ui-calendar-header ui-widget-header ui-helper-clearfix";
|
||||||
if ( months[ i ].first ) {
|
if ( months[ i ].first ) {
|
||||||
headerClass += " ui-corner-left";
|
headerClass += " ui-corner-left";
|
||||||
@ -212,7 +218,7 @@ return $.widget( "ui.calendar", {
|
|||||||
|
|
||||||
html += "<div class='ui-calendar-row-break'></div>";
|
html += "<div class='ui-calendar-row-break'></div>";
|
||||||
|
|
||||||
this.date = currentDate;
|
this.viewDate = currentDate;
|
||||||
|
|
||||||
return html;
|
return html;
|
||||||
},
|
},
|
||||||
@ -260,17 +266,17 @@ return $.widget( "ui.calendar", {
|
|||||||
|
|
||||||
_buildTitle: function() {
|
_buildTitle: function() {
|
||||||
return "<span class='ui-calendar-month'>" +
|
return "<span class='ui-calendar-month'>" +
|
||||||
this.date.monthName() +
|
this.viewDate.monthName() +
|
||||||
"</span> " +
|
"</span> " +
|
||||||
"<span class='ui-calendar-year'>" +
|
"<span class='ui-calendar-year'>" +
|
||||||
this.date.year() +
|
this.viewDate.year() +
|
||||||
"</span>";
|
"</span>";
|
||||||
},
|
},
|
||||||
|
|
||||||
_buildGrid: function() {
|
_buildGrid: function() {
|
||||||
return "<table class='ui-calendar-calendar' role='grid' aria-readonly='true' " +
|
return "<table class='ui-calendar-calendar' role='grid' aria-readonly='true' " +
|
||||||
"aria-labelledby='" + this.id + "-month-label' tabindex='0' " +
|
"aria-labelledby='" + this.id + "-month-label' tabindex='0' " +
|
||||||
"aria-activedescendant='" + this.id + "-" + this.date.day() + "'>" +
|
"aria-activedescendant='" + this._getDayId( this.date ) + "'>" +
|
||||||
this._buildGridHeading() +
|
this._buildGridHeading() +
|
||||||
this._buildGridBody() +
|
this._buildGridBody() +
|
||||||
"</table>";
|
"</table>";
|
||||||
@ -279,7 +285,7 @@ return $.widget( "ui.calendar", {
|
|||||||
_buildGridHeading: function() {
|
_buildGridHeading: function() {
|
||||||
var cells = "",
|
var cells = "",
|
||||||
i = 0,
|
i = 0,
|
||||||
weekDayLength = this.date.weekdays().length;
|
weekDayLength = this.viewDate.weekdays().length;
|
||||||
|
|
||||||
if ( this.options.showWeek ) {
|
if ( this.options.showWeek ) {
|
||||||
cells += "<th class='ui-calendar-week-col'>" + this._getTranslation( "weekHeader" ) + "</th>";
|
cells += "<th class='ui-calendar-week-col'>" + this._getTranslation( "weekHeader" ) + "</th>";
|
||||||
@ -304,7 +310,7 @@ return $.widget( "ui.calendar", {
|
|||||||
_buildGridBody: function() {
|
_buildGridBody: function() {
|
||||||
|
|
||||||
// this.date.days() needs caching as it has O(n^2) complexity.
|
// this.date.days() needs caching as it has O(n^2) complexity.
|
||||||
var days = this.date.days(),
|
var days = this.viewDate.days(),
|
||||||
i = 0,
|
i = 0,
|
||||||
rows = "";
|
rows = "";
|
||||||
|
|
||||||
@ -338,7 +344,7 @@ return $.widget( "ui.calendar", {
|
|||||||
selectable = ( day.selectable && this._isValid( new Date( day.timestamp ) ) );
|
selectable = ( day.selectable && this._isValid( new Date( day.timestamp ) ) );
|
||||||
|
|
||||||
if ( day.render ) {
|
if ( day.render ) {
|
||||||
attributes.push( "id='" + this.id + "-" + day.date + "'" );
|
attributes.push( "id='" + this.id + "-" + day.year + "-" + day.month + "-" + day.date + "'" );
|
||||||
|
|
||||||
if ( !selectable ) {
|
if ( !selectable ) {
|
||||||
attributes.push( "aria-disabled='true'" );
|
attributes.push( "aria-disabled='true'" );
|
||||||
@ -351,6 +357,10 @@ return $.widget( "ui.calendar", {
|
|||||||
return "<td " + attributes.join( " " ) + ">" + content + "</td>";
|
return "<td " + attributes.join( " " ) + ">" + content + "</td>";
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_getDayId: function( date ) {
|
||||||
|
return this.id + "-" + date.year() + "-" + date.month() + "-" + date.day();
|
||||||
|
},
|
||||||
|
|
||||||
_buildDayElement: function( day, selectable ) {
|
_buildDayElement: function( day, selectable ) {
|
||||||
var attributes, content,
|
var attributes, content,
|
||||||
classes = [ "ui-state-default" ];
|
classes = [ "ui-state-default" ];
|
||||||
@ -364,7 +374,6 @@ return $.widget( "ui.calendar", {
|
|||||||
if ( day.today ) {
|
if ( day.today ) {
|
||||||
classes.push( "ui-state-highlight" );
|
classes.push( "ui-state-highlight" );
|
||||||
}
|
}
|
||||||
// TODO Explain and document this
|
|
||||||
if ( day.extraClasses ) {
|
if ( day.extraClasses ) {
|
||||||
classes.push( day.extraClasses.split( " " ) );
|
classes.push( day.extraClasses.split( " " ) );
|
||||||
}
|
}
|
||||||
@ -385,7 +394,7 @@ return $.widget( "ui.calendar", {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_isCurrent: function( day ) {
|
_isCurrent: function( day ) {
|
||||||
return day.timestamp === this.options.value.getTime();
|
return this.options.value && day.timestamp === this.options.value.getTime();
|
||||||
},
|
},
|
||||||
|
|
||||||
_createButtonPane: function() {
|
_createButtonPane: function() {
|
||||||
@ -439,6 +448,11 @@ return $.widget( "ui.calendar", {
|
|||||||
this.buttonPane.appendTo( this.element );
|
this.buttonPane.appendTo( this.element );
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_refresh: function() {
|
||||||
|
this.viewDate.setTime( this.date.date().getTime() );
|
||||||
|
this.refresh();
|
||||||
|
},
|
||||||
|
|
||||||
// Refreshing the entire calendar during interaction confuses screen readers, specifically
|
// Refreshing the entire calendar during interaction confuses screen readers, specifically
|
||||||
// because the grid heading is marked up as a live region and will often not update if it's
|
// because the grid heading is marked up as a live region and will often not update if it's
|
||||||
// destroyed and recreated instead of just having its text change. Additionally, interacting
|
// destroyed and recreated instead of just having its text change. Additionally, interacting
|
||||||
@ -469,9 +483,9 @@ return $.widget( "ui.calendar", {
|
|||||||
for ( ; i < this.options.numberOfMonths; i++ ) {
|
for ( ; i < this.options.numberOfMonths; i++ ) {
|
||||||
this.element.find( ".ui-calendar-title" ).eq( i ).html( this._buildTitle() );
|
this.element.find( ".ui-calendar-title" ).eq( i ).html( this._buildTitle() );
|
||||||
this.element.find( ".ui-calendar-calendar" ).eq( i ).html( this._buildGrid() );
|
this.element.find( ".ui-calendar-calendar" ).eq( i ).html( this._buildGrid() );
|
||||||
this.date.adjust( "M", 1 );
|
this.viewDate.adjust( "M", 1 );
|
||||||
}
|
}
|
||||||
this.date.adjust( "M", -this.options.numberOfMonths );
|
this.viewDate.adjust( "M", -this.options.numberOfMonths );
|
||||||
|
|
||||||
// TODO: This assumes focus is on the first grid. For multi pickers, the widget needs
|
// TODO: This assumes focus is on the first grid. For multi pickers, the widget needs
|
||||||
// to maintain the currently focused grid and base queries like this off of it.
|
// to maintain the currently focused grid and base queries like this off of it.
|
||||||
@ -493,11 +507,6 @@ return $.widget( "ui.calendar", {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_select: function( event, time ) {
|
|
||||||
this.valueAsDate( new Date( time ) );
|
|
||||||
this._trigger( "select", event );
|
|
||||||
},
|
|
||||||
|
|
||||||
value: function( value ) {
|
value: function( value ) {
|
||||||
if ( arguments.length ) {
|
if ( arguments.length ) {
|
||||||
this.valueAsDate( Globalize.parseDate( value, this.options.dateFormat ) );
|
this.valueAsDate( Globalize.parseDate( value, this.options.dateFormat ) );
|
||||||
@ -556,7 +565,7 @@ return $.widget( "ui.calendar", {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if ( refresh ) {
|
if ( refresh ) {
|
||||||
this.refresh();
|
this._refresh();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -589,7 +598,7 @@ return $.widget( "ui.calendar", {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( key === "eachDay" ) {
|
if ( key === "eachDay" ) {
|
||||||
this.date.eachDay = value;
|
this.viewDate.eachDay = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( key === "dateFormat" ) {
|
if ( key === "dateFormat" ) {
|
||||||
|
Loading…
Reference in New Issue
Block a user