From 31908a1465d907769dd94a6d0c19d6162568741d Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Wed, 26 Aug 2015 11:45:15 +0200 Subject: [PATCH] Calendar: Make header prev / next buttons min / max option aware * Disable / enable header buttons according to min / max * Add tests for header button states * Improve header button rendering and refreshing * Improve header button label escaping on create * Create button pane for multiple pickers (bugfix) --- tests/unit/calendar/options.js | 27 +++++++++++++- ui/widgets/calendar.js | 67 ++++++++++++++++++++++++---------- 2 files changed, 74 insertions(+), 20 deletions(-) diff --git a/tests/unit/calendar/options.js b/tests/unit/calendar/options.js index 01522ebee..202b497d6 100644 --- a/tests/unit/calendar/options.js +++ b/tests/unit/calendar/options.js @@ -191,10 +191,13 @@ test( "showWeek", function() { }); test( "min / max", function() { - expect( 7 ); + expect( 14 ); // With existing date var element = $( "#calendar" ).calendar(), + container = element.calendar( "widget" ), + prevButton = container.find( ".ui-calendar-prev" ), + nextButton = container.find( ".ui-calendar-next" ), minDate = new Date( 2008, 2 - 1, 29 ), maxDate = new Date( 2008, 12 - 1, 7 ); @@ -233,6 +236,28 @@ test( "min / max", function() { .calendar( "option", { min: minDate, max: maxDate } ) .calendar( "value", "1/4/09" ); testHelper.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 6 - 1, 4 ), "Min/max - value > max" ); + + element + .calendar( "option", { min: minDate, max: maxDate } ) + .calendar( "value", "3/4/08" ); + ok( !prevButton.hasClass( "ui-state-disabled" ), "Prev button enabled" ); + prevButton.simulate( "click" ); + ok( prevButton.hasClass( "ui-state-disabled" ), "Prev button disabled" ); + + element.calendar( "value", "11/4/08" ); + ok( !nextButton.hasClass( "ui-state-disabled" ), "Next button enabled" ); + nextButton.simulate( "click" ); + ok( nextButton.hasClass( "ui-state-disabled" ), "Next button disabled" ); + + element + .calendar( "option", { max: null } ) + .calendar( "value", "1/4/15" ) + .calendar( "option", { max: maxDate } ); + ok( nextButton.hasClass( "ui-state-disabled" ), "Other year: Next button disabled" ); + nextButton.simulate( "click" ); + ok( nextButton.hasClass( "ui-state-disabled" ), "Other year: Next button disabled after click" ); + nextButton.simulate( "click" ); + ok( !nextButton.hasClass( "ui-state-disabled" ), "Other year: Next button enabled after click" ); }); test( "numberOfMonths", function() { diff --git a/ui/widgets/calendar.js b/ui/widgets/calendar.js index 709622e8a..e274e558c 100644 --- a/ui/widgets/calendar.js +++ b/ui/widgets/calendar.js @@ -233,6 +233,10 @@ return $.widget( "ui.calendar", { } ) .html( pickerHtml ); + this.prevButton = this.element.find( ".ui-calendar-prev" ); + this.nextButton = this.element.find( ".ui-calendar-next" ); + this._refreshHeaderButtons(); + this._createButtonPane(); this.grid = this.element.find( ".ui-calendar-calendar" ); @@ -283,24 +287,14 @@ return $.widget( "ui.calendar", { }, _buildPreviousLink: function() { - var prevText = this._getTranslation( "prevText" ); - - return ""; }, _buildNextLink: function() { - var nextText = this._getTranslation( "nextText" ); - - return ""; }, @@ -517,14 +511,49 @@ return $.widget( "ui.calendar", { this.grid = $( this._buildGrid() ); this.element.find( ".ui-calendar-title" ).html( this._buildTitle() ); this.element.find( ".ui-calendar-calendar" ).replaceWith( this.grid ); - $( ".ui-calendar-prev", this.element ).attr( "title", this.labels.prevText ) - .children().html( this.labels.prevText ); - $( ".ui-calendar-next", this.element ).attr( "title", this.labels.nextText ) - .children().html( this.labels.nextText ); - this._createButtons(); } else { this._refreshMultiplePicker(); } + + this._refreshHeaderButtons(); + this._createButtons(); + }, + + _refreshHeaderButtons: function() { + var prevText = this._getTranslation( "prevText" ), + nextText = this._getTranslation( "nextText" ); + + this.prevButton.attr( "title", prevText ).children().html( prevText ); + this.nextButton.attr( "title", nextText ).children().html( nextText ); + this._headerButtonsState(); + }, + + _headerButtonsState: function() { + var months = this.viewDate.months( this.options.numberOfMonths - 1 ), + i = 0; + + for ( ; i < months.length; i++ ) { + if ( this.options.min !== null && months[ i ].first ) { + this._disableElement( this.prevButton, + ( this.options.min.getMonth() >= months[ i ].month() && + this.options.min.getFullYear() === months[ i ].year() ) || + this.options.min.getFullYear() > months[ i ].year() + ); + } + if ( this.options.max !== null && months[ i ].last ) { + this._disableElement( this.nextButton, + ( this.options.max.getMonth() <= months[ i].month() && + this.options.max.getFullYear() === months[ i ].year() ) || + this.options.max.getFullYear() < months[ i ].year() + ); + } + } + }, + + _disableElement: function( element, state ) { + element + .attr( "aria-disabled", state ) + .toggleClass( "ui-state-disabled", state ); }, _refreshMultiplePicker: function() { -- 2.39.5