From 342fcd13ba061b635d77f631e98f9a360c5362ec Mon Sep 17 00:00:00 2001 From: J Corley Date: Wed, 13 Jan 2016 09:38:20 -0600 Subject: [PATCH 01/25] Added support for marking as today. Added the date property so the day can know which date it represents. --- addon/components/sl-calendar-day.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/addon/components/sl-calendar-day.js b/addon/components/sl-calendar-day.js index 86ba8f9d..17ab903c 100644 --- a/addon/components/sl-calendar-day.js +++ b/addon/components/sl-calendar-day.js @@ -17,7 +17,8 @@ export default Ember.Component.extend({ classNameBindings: [ 'active', 'new', - 'old' + 'old', + 'isToday:today' ], /** @type {String[]} */ @@ -81,7 +82,9 @@ export default Ember.Component.extend({ * * @type {Boolean} */ - old: false + old: false, + + date: null, // ------------------------------------------------------------------------- // Observers @@ -89,4 +92,11 @@ export default Ember.Component.extend({ // ------------------------------------------------------------------------- // Methods + isToday: Ember.computed( + 'date', + function() { + return window.moment().isSame( this.get( 'date' ), 'day' ); + } + ) + }); From 4582b5a30300378eb47a101ee6d5d2d127135278 Mon Sep 17 00:00:00 2001 From: J Corley Date: Wed, 13 Jan 2016 09:41:03 -0600 Subject: [PATCH 02/25] changed the init method from .on to short notation. Added support for fixed week count. Added support for locales where the week does not start on Sunday. Added support for today and removed marking various things by data; replaced with marking them by current selection. --- addon/components/sl-calendar.js | 187 ++++++++++++-------------------- 1 file changed, 71 insertions(+), 116 deletions(-) diff --git a/addon/components/sl-calendar.js b/addon/components/sl-calendar.js index 0d1ff954..a13c801b 100755 --- a/addon/components/sl-calendar.js +++ b/addon/components/sl-calendar.js @@ -175,6 +175,28 @@ export default Ember.Component.extend({ // ------------------------------------------------------------------------- // Events + /** + * Initialize default property values + * + * @function + * @returns {undefined} + */ + init() { + this._super( ...arguments ); + + const today = window.moment(); + + this.set( 'today', today ); + + if ( !this.get( 'currentMonth' ) ) { + this.set( 'currentMonth', today.month() + 1 ); + } + + if ( !this.get( 'currentYear' ) ) { + this.set( 'currentYear', today.year() ); + } + }, + // ------------------------------------------------------------------------- // Properties @@ -221,6 +243,10 @@ export default Ember.Component.extend({ */ locked: false, + today: null, + + fixedWeekCount: true, + /** * The current view mode for the calendar * @@ -231,27 +257,6 @@ export default Ember.Component.extend({ // ------------------------------------------------------------------------- // Observers - /** - * Initialize default property values - * - * @function - * @returns {undefined} - */ - initialize: Ember.on( - 'init', - function() { - const today = new Date(); - - if ( !this.get( 'currentMonth' ) ) { - this.set( 'currentMonth', today.getMonth() + 1 ); - } - - if ( !this.get( 'currentYear' ) ) { - this.set( 'currentYear', today.getFullYear() ); - } - } - ), - // ------------------------------------------------------------------------- // Methods @@ -305,11 +310,10 @@ export default Ember.Component.extend({ */ currentMonthString: Ember.computed( 'currentMonth', - 'currentYear', 'locale', function() { return window.moment([ - this.get( 'currentYear' ), + 2015, this.get( 'currentMonth' ) - 1 ]).locale( this.get( 'locale' ) ).format( 'MMMM' ); } @@ -371,20 +375,16 @@ export default Ember.Component.extend({ * @returns {Object[]} */ monthsInYearView: Ember.computed( - 'contentDates', + 'currentMonth', 'currentYear', function() { - const contentDates = this.get( 'contentDates' ); const currentYear = this.get( 'currentYear' ); + const currentMonth = this.get( 'currentMonth' ); const months = Ember.A(); for ( let month = 1; month <= 12; month++ ) { months.push({ - active: ( - contentDates.hasOwnProperty( currentYear ) && - contentDates[ currentYear ].hasOwnProperty( month ) - ), - + active: month === currentMonth, month }); } @@ -404,15 +404,13 @@ export default Ember.Component.extend({ function() { const m = window.moment().locale( this.get( 'locale' ) ); - return Ember.A([ - m.day( 0 ).format( 'dd' ), - m.day( 1 ).format( 'dd' ), - m.day( 2 ).format( 'dd' ), - m.day( 3 ).format( 'dd' ), - m.day( 4 ).format( 'dd' ), - m.day( 5 ).format( 'dd' ), - m.day( 6 ).format( 'dd' ) - ]); + let weekdays = window.moment.weekdaysMin(); + + for ( let i = m.localeData().firstDayOfWeek(); i > 0; i-- ) { + weekdays.push( weekdays.shift() ); + } + + return weekdays; } ), @@ -472,92 +470,50 @@ export default Ember.Component.extend({ 'contentDates', 'currentMonth', 'currentYear', - 'daysInMonth', + 'fixedWeekCount', + 'locale', function() { - const contentDates = this.get( 'contentDates' ); + const weeks = Ember.A(); + const currentMonth = this.get( 'currentMonth' ); - const currentYear = this.get( 'currentYear' ); - const daysInCurrentMonth = this.get( 'daysInMonth' ); - const firstWeekdayOfCurrentMonth = ( - new Date( currentYear, currentMonth - 1, 1 ) - ).getDay(); - const weeks = Ember.A(); - let inNextMonth = false; - - let previousMonth; - let previousMonthYear; - if ( 1 === currentMonth ) { - previousMonth = 12; - previousMonthYear = currentYear - 1; - } else { - previousMonth = currentMonth - 1; - previousMonthYear = currentYear; - } + let firstOfMonth = window.moment( '01-' + currentMonth + '-' + this.get( 'currentYear' ), 'DD-MM-YYYY' ).locale( this.get( 'locale' ) ); + let firstDayOfWeek = firstOfMonth.localeData().firstDayOfWeek(); + let nextDayToShow = window.moment( firstOfMonth ).subtract( firstOfMonth.day(), 'days' ); - const previousMonthDays = window.moment([ - previousMonthYear, - previousMonth - 1 - ]).daysInMonth(); + // support firstDayOfWeek via locale + nextDayToShow.add( firstDayOfWeek, 'days' ); - let nextMonth; - let nextMonthYear; - if ( 12 === currentMonth ) { - nextMonth = 1; - nextMonthYear = currentYear + 1; - } else { - nextMonth = currentMonth + 1; - nextMonthYear = currentYear; + // if the first day of the week has shifted the first onto last week + if ( nextDayToShow.date() < 6 && nextDayToShow.date() !== 1 ) { + nextDayToShow.subtract( 7, 'days' ); } - let inPreviousMonth; - let day; - let month; - let year; - if ( firstWeekdayOfCurrentMonth > 0 ) { - inPreviousMonth = true; - day = previousMonthDays - firstWeekdayOfCurrentMonth + 1; - month = previousMonth; - year = previousMonthYear; - } else { - inPreviousMonth = false; - day = 1; - month = currentMonth; - year = currentYear; + let weeksToShow = 6; + + if ( !this.get( 'fixedWeekCount' ) ) { + weeksToShow = window.moment( firstOfMonth ).add( 1, 'months' ).subtract( 1, 'days' ).diff( nextDayToShow, 'weeks' ) + 1; } - for ( let week = 0; week < 6; week++ ) { + for ( let i = 1; i <= weeksToShow; i++ ) { const days = Ember.A(); - for ( let wday = 0; wday < 7; wday++ ) { - const active = !inPreviousMonth && !inNextMonth && - contentDates.hasOwnProperty( year ) && - contentDates[ year ].hasOwnProperty( month ) && - contentDates[ year ][ month ].hasOwnProperty( day ); - - days.push({ - active, - content: active ? - contentDates[ year ][ month ][ day ] : - null, - day: day++, - 'new': inNextMonth, - old: inPreviousMonth - }); - - if ( inPreviousMonth ) { - if ( day > previousMonthDays ) { - inPreviousMonth = false; - day = 1; - month = currentMonth; - year = currentYear; - } - } else if ( day > daysInCurrentMonth ) { - inNextMonth = true; - day = 1; - month = nextMonth; - year = nextMonthYear; + for ( let k = 0; k < 7; k++ ) { + let inNextMonth = nextDayToShow.month() === currentMonth; + let inPrevMonth = nextDayToShow.month() === currentMonth - 2; + + if ( currentMonth === 1 && nextDayToShow.month() === 11 ) { + inPrevMonth = true; } + + const day = { + date: window.moment( nextDayToShow ), + day: nextDayToShow.date(), + old: inPrevMonth, + new: inNextMonth + }; + days.push( day ); + nextDayToShow.add( 1, 'days' ); } weeks.push( days ); @@ -580,18 +536,17 @@ export default Ember.Component.extend({ * @returns {Object[]} */ yearsInDecadeView: Ember.computed( - 'contentDates', 'decadeEnd', 'decadeStart', function() { - const contentDates = this.get( 'contentDates' ); const decadeStart = this.get( 'decadeStart' ); const decadeEnd = this.get( 'decadeEnd' ); + const currentYear = this.get( 'currentYear' ); const years = Ember.A(); for ( let year = decadeStart - 1; year <= decadeEnd + 1; year++ ) { years.push({ - active: contentDates.hasOwnProperty( year ), + active: year === currentYear, 'new': year > decadeEnd, old: year < decadeStart, year From 99ce56bb897bdd3f7bea51629f0c9b0e6ccabcd4 Mon Sep 17 00:00:00 2001 From: J Corley Date: Wed, 13 Jan 2016 09:41:56 -0600 Subject: [PATCH 03/25] support for day knowing which date it is --- addon/templates/components/sl-calendar.hbs | 1 + 1 file changed, 1 insertion(+) diff --git a/addon/templates/components/sl-calendar.hbs b/addon/templates/components/sl-calendar.hbs index a951e619..5bd01835 100644 --- a/addon/templates/components/sl-calendar.hbs +++ b/addon/templates/components/sl-calendar.hbs @@ -31,6 +31,7 @@ day=day.day new=day.new old=day.old + date=day.date }} {{/each}} From 0f10a5e313a1bf8b370366bfc7dd9ba2895ad102 Mon Sep 17 00:00:00 2001 From: J Corley Date: Wed, 13 Jan 2016 09:43:10 -0600 Subject: [PATCH 04/25] removed unnecessary class. added two properties for testing. --- tests/dummy/app/templates/demos/sl-calendar.hbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/dummy/app/templates/demos/sl-calendar.hbs b/tests/dummy/app/templates/demos/sl-calendar.hbs index 5412a7f2..062205e5 100755 --- a/tests/dummy/app/templates/demos/sl-calendar.hbs +++ b/tests/dummy/app/templates/demos/sl-calendar.hbs @@ -21,7 +21,7 @@
Rendered Component
- {{sl-calendar action="logLabel" class="col-sm-6" content=content}} + {{sl-calendar action="logLabel" content=content fixedWeekCount=false locale="en"}}
From eea0801233bd588b02255f2518b19169fdee9169 Mon Sep 17 00:00:00 2001 From: J Corley Date: Thu, 14 Jan 2016 14:30:18 -0600 Subject: [PATCH 05/25] Modified demo console log event to be more verbose. Changed some calendar property names to be 'showingMonth' instead of 'currentMonth' to separate selection functionality from view functionality. Changed 'setMonth' naming to 'selectMonth' naming for my concise conveyance of function. Modified sl-calendar-month to yield and removed the idea that it should know its own name since that should come from calendar and locale. Commented out several properties in sl-calendar-month. Modified the sl-calendar-day click action to send the date as well as any content or data it may have. Separated changeMonth style functions from setMonth style functions so that one will use the other. Added a selectDate action for when days are clicked. Sl-calendar now has a separation of selectedDate vs viewingDate. showingMonth and showingYear are based on viewingDate. Active months and years are now based on the selectedDate and not arbitrary data points. Added sl-calendar as subcomponent on sl-date-picker. Added an action to sl-date-picker to listen for the calendar date selection. Added locale awareness to sl-date-picker. Commented old datepicker plugin initialization code in sl-date-picker. --- addon/components/sl-calendar-day.js | 7 +- addon/components/sl-calendar-month.js | 13 +- addon/components/sl-calendar.js | 225 +++++++++++------- addon/components/sl-date-picker.js | 34 ++- addon/templates/components/sl-calendar.hbs | 14 +- addon/templates/components/sl-date-picker.hbs | 13 + .../app/controllers/demos/sl-calendar.js | 4 +- 7 files changed, 204 insertions(+), 106 deletions(-) diff --git a/addon/components/sl-calendar-day.js b/addon/components/sl-calendar-day.js index 17ab903c..5f06d8c9 100644 --- a/addon/components/sl-calendar-day.js +++ b/addon/components/sl-calendar-day.js @@ -44,10 +44,11 @@ export default Ember.Component.extend({ */ click() { const content = this.get( 'content' ); + const date = this.get( 'date' ); - if ( content ) { - this.sendAction( 'action', content ); - } + //if ( content ) { + this.sendAction( 'action', date, content ); + //} }, // ------------------------------------------------------------------------- diff --git a/addon/components/sl-calendar-month.js b/addon/components/sl-calendar-month.js index 59449325..f37d087d 100755 --- a/addon/components/sl-calendar-month.js +++ b/addon/components/sl-calendar-month.js @@ -1,5 +1,5 @@ import Ember from 'ember'; -import layout from '../templates/components/sl-calendar-month'; +//import layout from '../templates/components/sl-calendar-month'; /** * @module @@ -23,9 +23,6 @@ export default Ember.Component.extend({ 'month' ], - /** @type {Object} */ - layout, - /** @type {String} */ tagName: 'span', @@ -59,14 +56,14 @@ export default Ember.Component.extend({ * * @type {String} */ - locale: 'en', + //locale: 'en', /** * The number of the month (1-12) * * @type {?Number} */ - month: null, + month: null//, // ------------------------------------------------------------------------- // Observers @@ -80,13 +77,13 @@ export default Ember.Component.extend({ * @function * @returns {String} */ - shortName: Ember.computed( + /*shortName: Ember.computed( 'month', function() { return window.moment([ 1, this.get( 'month' ) - 1 ]) .locale( this.get( 'locale' ) ) .format( 'MMM' ); } - ) + )*/ }); diff --git a/addon/components/sl-calendar.js b/addon/components/sl-calendar.js index b96f3c2c..c432addb 100755 --- a/addon/components/sl-calendar.js +++ b/addon/components/sl-calendar.js @@ -47,61 +47,53 @@ export default Ember.Component.extend({ return; } - this.incrementProperty( 'currentYear', 10 * decadeMod ); + this.incrementProperty( 'showingYear', 10 * decadeMod ); }, /** * Change the currently-viewed month by incrementing or decrementing - * the currentMonth (and currentYear if needed) + * the showingMonth (and showingYear if needed) * * @function actions:changeMonth - * @param {Number} monthMod - A number to adjust the currentMonth by + * @param {Number} monthMod - A number to adjust the showingMonth by * (positive to increment, negative to decrement). The - * currentYear is adjusted as needed. + * showingYear is adjusted as needed. * @returns {undefined} */ changeMonth( monthMod ) { - let month; - let year; + const newMonth = ( this.get( 'viewingDate' ).month() + 1 ) + monthMod; + this.setMonth( newMonth );/* if ( this.get( 'locked' ) ) { return; } - month = this.get( 'currentMonth' ) + monthMod; - year = this.get( 'currentYear' ); + const viewingDate = this.get( 'viewingDate' ); - while ( month < 1 ) { - month += 12; - year -= 1; - } - - while ( month > 12 ) { - month -= 12; - year += 1; - } - - this.setProperties({ - currentYear: year, - currentMonth: month - }); + this.set( 'viewingDate', window.moment( viewingDate ).add( monthMod, 'months' ) );*/ }, /** * Change the currently-viewed year by increment or decrementing the - * currentYear + * showingYear * * @function actions:changeYear - * @param {Number} yearMod - A number to adjust the currentYear by + * @param {Number} yearMod - A number to adjust the showingYear by * (positive to increment, negative to decrement) * @returns {undefined} */ changeYear( yearMod ) { + const newYear = this.get( 'viewingDate' ).year() + yearMod; + + this.setYear( newYear );/* + if ( this.get( 'locked' ) ) { return; } - this.incrementProperty( 'currentYear', yearMod ); + const viewingDate = this.get( 'viewingDate' ); + + this.set( 'viewingDate', window.moment( viewingDate ).add( yearMod, 'years' ) );*/ }, /** @@ -119,22 +111,34 @@ export default Ember.Component.extend({ } }, + selectDate( date, data ) { + this.setDate( date ); + + this.sendAction( 'action', date, data ); + }, + /** * Set the current month and change view mode to that month * - * @function actions:setMonth + * @function actions:selectMonth * @param {Number} month - The number of the month to change view to * @returns {undefined} */ - setMonth( month ) { - if ( this.get( 'locked' ) ) { - return; - } + selectMonth( month ) { + this.setMonth( month ); + this.send( 'setView', 'days' ); + }, - this.setProperties({ - currentMonth: month, - viewMode: 'days' - }); + /** + * Set the current year and change the view mode to that year + * + * @function actions:selectYear + * @param {Number} year - The year to set to the current value + * @returns {undefined} + */ + selectYear( year ) { + this.setYear( year ); + this.send( 'setView', 'months' ); }, /** @@ -151,24 +155,6 @@ export default Ember.Component.extend({ } this.set( 'viewMode', view ); - }, - - /** - * Set the current year - * - * @function actions:setYear - * @param {Number} year - The year to set to the current value - * @returns {undefined} - */ - setYear( year ) { - if ( this.get( 'locked' ) ) { - return; - } - - this.setProperties({ - viewMode: 'months', - currentYear: year - }); } }, @@ -187,13 +173,19 @@ export default Ember.Component.extend({ this.set( 'today', today ); - if ( !this.get( 'currentMonth' ) ) { - this.set( 'currentMonth', today.month() + 1 ); + if ( !this.get( 'viewingDate' ) ) { + this.set( 'viewingDate', today ); } +/* + const viewingDate = this.get( 'viewingDate' ); - if ( !this.get( 'currentYear' ) ) { - this.set( 'currentYear', today.year() ); + if ( !this.get( 'showingMonth' ) ) { + this.set( 'showingMonth', viewingDate.month() + 1 ); } + + if ( !this.get( 'showingYear' ) ) { + this.set( 'showingYear', viewingDate.year() ); + }*/ }, // ------------------------------------------------------------------------- @@ -211,14 +203,14 @@ export default Ember.Component.extend({ * * @type {?Number} */ - currentMonth: null, + //showingMonth: null, /** * The currently selected/viewed year * * @type {?Number} */ - currentYear: null, + //showingYear: null, /** * String lookup for the date value on the content objects @@ -246,6 +238,10 @@ export default Ember.Component.extend({ fixedWeekCount: true, + viewingDate: null, + + selectedDate: null, + /** * The current view mode for the calendar * @@ -259,6 +255,44 @@ export default Ember.Component.extend({ // ------------------------------------------------------------------------- // Methods + setDate( date ) { + this.set( 'selectedDate', window.moment( date ) ); + }, + + setMonth( month ) { + if ( this.get( 'locked' ) ) { + return; + } + + const viewingDate = this.get( 'viewingDate' ); + + this.set( 'viewingDate', window.moment( viewingDate ).month( month - 1 ) ); + }, + + setYear( year ) { + if ( this.get( 'locked' ) ) { + return; + } + + const viewingDate = this.get( 'viewingDate' ); + + this.set( 'viewingDate', window.moment( viewingDate ).year( year ) ); + }, + + showingMonth: Ember.computed( + 'viewingDate', + function() { + return this.get( 'viewingDate' ).month() + 1; + } + ), + + showingYear: Ember.computed( + 'viewingDate', + function() { + return this.get( 'viewingDate' ).year(); + } + ), + /** * Object of nested year, month, and day values, representing the dates * supplied by the calendar's content values @@ -307,13 +341,13 @@ export default Ember.Component.extend({ * @function * @returns {String} */ - currentMonthString: Ember.computed( - 'currentMonth', + showingMonthString: Ember.computed( + 'showingMonth', 'locale', function() { return window.moment([ 2015, - this.get( 'currentMonth' ) - 1 + this.get( 'showingMonth' ) - 1 ]).locale( this.get( 'locale' ) ).format( 'MMMM' ); } ), @@ -325,12 +359,12 @@ export default Ember.Component.extend({ * @returns {Number} */ daysInMonth: Ember.computed( - 'currentMonth', - 'currentYear', + 'showingMonth', + 'showingYear', function() { return window.moment([ - this.get( 'currentYear' ), - this.get( 'currentMonth' ) - 1 + this.get( 'showingYear' ), + this.get( 'showingMonth' ) - 1 ]).daysInMonth(); } ), @@ -355,11 +389,11 @@ export default Ember.Component.extend({ * @returns {Number} */ decadeStart: Ember.computed( - 'currentYear', + 'showingYear', function() { - const currentYear = this.get( 'currentYear' ); + const showingYear = this.get( 'showingYear' ); - return currentYear - ( currentYear % 10 ); + return showingYear - ( showingYear % 10 ); } ), @@ -374,16 +408,26 @@ export default Ember.Component.extend({ * @returns {Object[]} */ monthsInYearView: Ember.computed( - 'currentMonth', - 'currentYear', + 'showingYear', + 'selectedDate', + 'locale', function() { - const currentYear = this.get( 'currentYear' ); - const currentMonth = this.get( 'currentMonth' ); + const showingYear = this.get( 'showingYear' ); + const selectedDate = this.get( 'selectedDate' ); + const m = window.moment().locale( this.get( 'locale' ) ); + const monthNames = window.moment.monthsShort(); const months = Ember.A(); for ( let month = 1; month <= 12; month++ ) { + let isActive = false; + + if ( selectedDate ) { + isActive = ( selectedDate.month() + 1 ) === month && selectedDate.year() === showingYear; + } + months.push({ - active: month === currentMonth, + active: isActive, + monthName: monthNames[ month - 1 ], month }); } @@ -467,16 +511,18 @@ export default Ember.Component.extend({ */ weeksInMonthView: Ember.computed( 'contentDates', - 'currentMonth', - 'currentYear', + 'showingMonth', + 'showingYear', + 'selectedDate', 'fixedWeekCount', 'locale', function() { const weeks = Ember.A(); - const currentMonth = this.get( 'currentMonth' ); + const showingMonth = this.get( 'showingMonth' ); + const selectedDate = this.get( 'selectedDate' ); - let firstOfMonth = window.moment( '01-' + currentMonth + '-' + this.get( 'currentYear' ), 'DD-MM-YYYY' ).locale( this.get( 'locale' ) ); + let firstOfMonth = window.moment( '01-' + showingMonth + '-' + this.get( 'showingYear' ), 'DD-MM-YYYY' ).locale( this.get( 'locale' ) ); let firstDayOfWeek = firstOfMonth.localeData().firstDayOfWeek(); let nextDayToShow = window.moment( firstOfMonth ).subtract( firstOfMonth.day(), 'days' ); @@ -498,18 +544,24 @@ export default Ember.Component.extend({ const days = Ember.A(); for ( let k = 0; k < 7; k++ ) { - let inNextMonth = nextDayToShow.month() === currentMonth; - let inPrevMonth = nextDayToShow.month() === currentMonth - 2; + let isActive = false; + let inNextMonth = nextDayToShow.month() === showingMonth; + let inPrevMonth = nextDayToShow.month() === showingMonth - 2; - if ( currentMonth === 1 && nextDayToShow.month() === 11 ) { + if ( showingMonth === 1 && nextDayToShow.month() === 11 ) { inPrevMonth = true; } + if ( selectedDate ) { + isActive = nextDayToShow.isSame( selectedDate ); + } + const day = { date: window.moment( nextDayToShow ), day: nextDayToShow.date(), old: inPrevMonth, - new: inNextMonth + new: inNextMonth, + active: isActive }; days.push( day ); nextDayToShow.add( 1, 'days' ); @@ -537,15 +589,22 @@ export default Ember.Component.extend({ yearsInDecadeView: Ember.computed( 'decadeEnd', 'decadeStart', + 'selectedDate', function() { const decadeStart = this.get( 'decadeStart' ); const decadeEnd = this.get( 'decadeEnd' ); - const currentYear = this.get( 'currentYear' ); + const selectedDate = this.get( 'selectedDate' ); const years = Ember.A(); for ( let year = decadeStart - 1; year <= decadeEnd + 1; year++ ) { + let isActive = false; + + if ( selectedDate ) { + isActive = year === selectedDate.year(); + } + years.push({ - active: year === currentYear, + active: isActive, 'new': year > decadeEnd, old: year < decadeStart, year diff --git a/addon/components/sl-date-picker.js b/addon/components/sl-date-picker.js index 629a979f..108fd4dc 100755 --- a/addon/components/sl-date-picker.js +++ b/addon/components/sl-date-picker.js @@ -31,6 +31,15 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa // ------------------------------------------------------------------------- // Actions + /** @type {Object} */ + actions: { + + selectDate( date ) { + this.selectDate( date ); + } + + }, + // ------------------------------------------------------------------------- // Events @@ -256,6 +265,10 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa */ weekStart: 0, + isOpen: false, + + locale: 'en', + // ------------------------------------------------------------------------- // Observers @@ -300,7 +313,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa 'endDate', 'startDate', function() { - const input = this.$( 'input.date-picker' ); + /*const input = this.$( 'input.date-picker' ); const datepicker = input.data( 'datepicker' ); datepicker.setStartDate( this.get( 'startDate' ) ); @@ -308,13 +321,20 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa if ( 'Invalid Date' === datepicker.getDate().toString() ) { input.val( '' ); - } + }*/ } ), // ------------------------------------------------------------------------- // Methods + selectDate( date ) { + const format = window.moment().localeData().longDateFormat( 'L' ); + + this.set( 'value', date.format( format ) ); + this.set( 'isOpen', false ); + }, + /** * Setup the bootstrap-datepicker plugin and events * @@ -322,11 +342,17 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * @returns {undefined} */ setupDatepicker() { - const datepicker = this.$( 'input.date-picker' ) + /*const datepicker = this.$( 'input.date-picker' ) .datepicker( this.get( 'options' ) ); datepicker.on( this.namespaceEvent( 'changeDate' ), () => { this.sendAction(); + });*/ + const context = this; + + this.$( '> input' ).on( 'focus', function() { + context.set( 'isOpen', true ); + console.log( 'opening' ); }); }, @@ -337,6 +363,6 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * @returns {undefined} */ unregisterEvents() { - this.$( 'input.date-picker' ).off( this.namespaceEvent( 'changeDate' ) ); + //this.$( 'input.date-picker' ).off( this.namespaceEvent( 'changeDate' ) ); } }); diff --git a/addon/templates/components/sl-calendar.hbs b/addon/templates/components/sl-calendar.hbs index 5bd01835..938ed99b 100644 --- a/addon/templates/components/sl-calendar.hbs +++ b/addon/templates/components/sl-calendar.hbs @@ -8,7 +8,7 @@ previous month - {{currentMonthString}} {{currentYear}} + {{showingMonthString}} {{showingYear}} next month @@ -25,7 +25,7 @@ {{#each weekDays as |day|}} {{sl-calendar-day - action="sendDateContent" + action="selectDate" active=day.active content=day.content day=day.day @@ -50,7 +50,7 @@ previous year - {{currentYear}} + {{showingYear}} next year @@ -61,12 +61,14 @@ {{#each monthsInYearView as |month|}} - {{sl-calendar-month - action="setMonth" + {{#sl-calendar-month + action="selectMonth" active=month.active locale=locale month=month.month }} + {{month.monthName}} + {{/sl-calendar-month}} {{/each}} @@ -96,7 +98,7 @@ {{#each yearsInDecadeView as |year|}} {{sl-calendar-year - action="setYear" + action="selectYear" active=year.active old=year.old new=year.new diff --git a/addon/templates/components/sl-date-picker.hbs b/addon/templates/components/sl-date-picker.hbs index 0083f863..ee09ab5c 100644 --- a/addon/templates/components/sl-date-picker.hbs +++ b/addon/templates/components/sl-date-picker.hbs @@ -11,6 +11,19 @@ value=value }} +{{#if isOpen}} +
+
+
+ {{sl-calendar + action="selectDate" + fixedWeekCount=true + locale=locale + }} +
+
+{{/if}} + {{#if helpText}}

{{helpText}}

{{/if}} diff --git a/tests/dummy/app/controllers/demos/sl-calendar.js b/tests/dummy/app/controllers/demos/sl-calendar.js index d1bdcae9..761016de 100644 --- a/tests/dummy/app/controllers/demos/sl-calendar.js +++ b/tests/dummy/app/controllers/demos/sl-calendar.js @@ -2,8 +2,8 @@ import Ember from 'ember'; export default Ember.Controller.extend({ actions: { - logLabel( dateObjects ) { - window.console.log( dateObjects ); + logLabel( date, data ) { + window.console.log( 'logLabel: ', date, data ); } } }); From 8f7748aae836f495404edf0eab9668f3c10a2d67 Mon Sep 17 00:00:00 2001 From: J Corley Date: Tue, 19 Jan 2016 15:29:02 -0600 Subject: [PATCH 06/25] **CALENDAR** Added aria-role attributes to calendar. Added tabIndex to allow the calendar to be focused. Added focusIn, focusOut, and keyDown events. Added focusable and hasFocus properties. SetDate() now sets viewingDate as well. Added a temporary style for checking focus. Added support for focused day. **CALENDAR DAY** Added support for tabIndex. Added support for aria-selected. Added aria-role. Added support for focus. **DATE PICKER** Added a temporary inline style to correctly place the popover. Changed isOpen to hasFocus. Added focus-in, focus-out, and key-up actions to the input helper. Added focusIn, focusOut, and keyPress events. Removed default format value as it should be seeded from Moment.js using locale. Added a losingFocus property to hold onto an Ember.run.next scheduled event. Added an observer for date selection. Added checkInput() method to validate input value as it is typed. Added parseFormats property to pre-seed with Moment.js locale strings to validate against. Added selectDate() method that will set the selectedDate to a passed date. Added viewingDate property that enforces the calendar viewingDate to be the selectedDate. Removed jQuery event hooks. Added updateValue() method for setting the input value if the current input is a valid date. --- addon/components/sl-calendar-day.js | 36 +++++ addon/components/sl-calendar.js | 109 ++++++++++++- addon/components/sl-date-picker.js | 152 ++++++++++++++++-- addon/templates/components/sl-calendar.hbs | 9 +- addon/templates/components/sl-date-picker.hbs | 9 +- app/styles/sl-calendar.less | 3 + 6 files changed, 295 insertions(+), 23 deletions(-) diff --git a/addon/components/sl-calendar-day.js b/addon/components/sl-calendar-day.js index 5f06d8c9..a89fcc11 100644 --- a/addon/components/sl-calendar-day.js +++ b/addon/components/sl-calendar-day.js @@ -13,6 +13,11 @@ export default Ember.Component.extend({ // ------------------------------------------------------------------------- // Attributes + attributeBindings: [ + 'ariaSelected:aria-selected', + 'tabIndex' + ], + /** @type {String[]} */ classNameBindings: [ 'active', @@ -87,17 +92,48 @@ export default Ember.Component.extend({ date: null, + focused: false, + + ariaRole: 'gridcell', + // ------------------------------------------------------------------------- // Observers + applyFocus: Ember.observer( + 'focused', + function() { + if ( this.get( 'focused' ) ) { + console.log( 'focused' ); + Ember.run.scheduleOnce( 'afterRender', this, () => { + this.$().get( 0 ).focus(); + }); + } + } + ), + // ------------------------------------------------------------------------- // Methods + ariaSelected: Ember.computed( + 'active', + function() { + const active = this.get( 'active' ); + return active ? active : null; + } + ), + isToday: Ember.computed( 'date', function() { return window.moment().isSame( this.get( 'date' ), 'day' ); } + ), + + tabIndex: Ember.computed( + 'focused', + function() { + return this.get( 'focused' ) ? 0 : null; + } ) }); diff --git a/addon/components/sl-calendar.js b/addon/components/sl-calendar.js index c432addb..cbd14030 100755 --- a/addon/components/sl-calendar.js +++ b/addon/components/sl-calendar.js @@ -13,6 +13,10 @@ export default Ember.Component.extend({ // ------------------------------------------------------------------------- // Attributes + attributeBindings: [ + 'tabIndex' + ], + /** @type {String[]} */ classNameBindings: [ 'locked:sl-calendar-locked' @@ -161,6 +165,94 @@ export default Ember.Component.extend({ // ------------------------------------------------------------------------- // Events + focusIn() { + this._super( ...arguments ); + + console.log( 'calendar focus in' ); + this.set( 'hasFocus', true ); + }, + + focusOut() { + this._super( ...arguments ); + + console.log( 'calendar focus out' ); + this.set( 'hasFocus', false ); + }, + + keyDown( event ) { + this._super( ...arguments ); + + // handle wai-aria here + // https://www.w3.org/TR/2009/WD-wai-aria-practices-20090224/#datepicker + // https://web.archive.org/web/20130127091925/http://codetalks.org/source/widgets/datepicker/datepicker.sample.html + + const viewingDate = window.moment( this.get( 'viewingDate' ) ); + + let timePeriod; + + switch ( event.keyCode ) { + case 38: // up arrow + this.set( 'viewingDate', viewingDate.subtract( 1, 'weeks' ) ); + break; + + case 40: // down arrow + this.set( 'viewingDate', viewingDate.add( 1, 'weeks' ) ); + break; + + case 37: // left arrow + this.set( 'viewingDate', viewingDate.subtract( 1, 'days' ) ); + break; + + case 39: // right arrow + this.set( 'viewingDate', viewingDate.add( 1, 'days' ) ); + break; + + case 33: // page up + timePeriod = 'months'; + if ( event.shiftKey ) { + timePeriod = 'years'; + } + this.set( 'viewingDate', viewingDate.subtract( 1, timePeriod ) ); + break; + + case 34: // page down + timePeriod = 'months'; + if ( event.shiftKey ) { + timePeriod = 'years'; + } + this.set( 'viewingDate', viewingDate.add( 1, timePeriod ) ); + break; + + case 35: // end + timePeriod = 'month'; + if ( event.ctrlKey ) { + timePeriod = 'year'; + } + this.set( 'viewingDate', viewingDate.endOf( timePeriod ) ); + break; + + case 36: // home + timePeriod = 'month'; + if ( event.ctrlKey ) { + timePeriod = 'year'; + } + this.set( 'viewingDate', viewingDate.startOf( timePeriod ) ); + break; + + case 32: // space + + case 13: // enter + this.set( 'selectedDate', viewingDate ); + break; + + default: + return true; + } + + // disallow default key event + return false; + }, + /** * Initialize default property values * @@ -242,6 +334,10 @@ export default Ember.Component.extend({ selectedDate: null, + focusable: true, + + hasFocus: false, + /** * The current view mode for the calendar * @@ -257,6 +353,7 @@ export default Ember.Component.extend({ setDate( date ) { this.set( 'selectedDate', window.moment( date ) ); + this.set( 'viewingDate', window.moment( date ) ); }, setMonth( month ) { @@ -293,6 +390,13 @@ export default Ember.Component.extend({ } ), + tabIndex: Ember.computed( + 'focusable', + function() { + return this.get( 'focusable' ) ? 0 : -1; + } + ), + /** * Object of nested year, month, and day values, representing the dates * supplied by the calendar's content values @@ -516,11 +620,13 @@ export default Ember.Component.extend({ 'selectedDate', 'fixedWeekCount', 'locale', + 'viewingDate', function() { const weeks = Ember.A(); const showingMonth = this.get( 'showingMonth' ); const selectedDate = this.get( 'selectedDate' ); + const viewingDate = this.get( 'viewingDate' ); let firstOfMonth = window.moment( '01-' + showingMonth + '-' + this.get( 'showingYear' ), 'DD-MM-YYYY' ).locale( this.get( 'locale' ) ); let firstDayOfWeek = firstOfMonth.localeData().firstDayOfWeek(); @@ -553,7 +659,7 @@ export default Ember.Component.extend({ } if ( selectedDate ) { - isActive = nextDayToShow.isSame( selectedDate ); + isActive = nextDayToShow.isSame( selectedDate, 'day' ); } const day = { @@ -561,6 +667,7 @@ export default Ember.Component.extend({ day: nextDayToShow.date(), old: inPrevMonth, new: inNextMonth, + focused: nextDayToShow.isSame( viewingDate, 'day' ), active: isActive }; days.push( day ); diff --git a/addon/components/sl-date-picker.js b/addon/components/sl-date-picker.js index 108fd4dc..de7e3bf0 100755 --- a/addon/components/sl-date-picker.js +++ b/addon/components/sl-date-picker.js @@ -34,6 +34,25 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa /** @type {Object} */ actions: { + inputBlurred() { + this.trigger( 'focusOut' ); + + this.updateValue(); + }, + + inputFocused() { + this.trigger( 'focusIn' ); + }, + + inputKeyUp( value, event ) { + console.log( 'input key up' ); + + // not a tab or modifier key + if ( event.keyCode !== 9 && ( event.keyCode > 18 || event.keyCode < 16 ) ) { + this.checkInput(); + } + }, + selectDate( date ) { this.selectDate( date ); } @@ -53,6 +72,52 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa this.setupDatepicker(); }, + focusIn( event ) { + this._super( ...arguments ); + + this.set( 'hasFocus', true ); + //this.set( 'isOpen', true ); + + const losingFocus = this.get( 'losingFocus' ); + Ember.run.cancel( losingFocus ); + + if ( event === undefined ) { + return; + } + + if ( event.target === this.$().get( 0 ) ) { + this.$( '> input' ).get( 0 ).focus(); + } + }, + + focusOut( event ) { + this._super( ...arguments ); + + + const runNext = Ember.run.next( this, () => { + /*if ( !this.get( 'hasFocus' ) ) { + this.set( 'isOpen', false ); + }*/ + + this.set( 'hasFocus', false ); + }); + + this.set( 'losingFocus', runNext ); + }, + + init() { + this._super( ...arguments ); + + if ( !this.get( 'format' ) ) { + const format = window.moment().localeData().longDateFormat( 'L' ); + this.set( 'format', format ); + } + }, + + keyPress() { + console.log( 'date picker: keypress' ); + }, + /** * willClearRender event hook * @@ -137,9 +202,9 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * - M, MM: Abbreviated and full month names, respectively * - yy, yyyy: 2- and 4-digit years, respectively * - * @type {String} + * @type {?String} */ - format: 'mm/dd/yyyy', + format: null, /** * The help text below the datepicker @@ -265,13 +330,26 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa */ weekStart: 0, - isOpen: false, - locale: 'en', + selectedDate: null, + + hasFocus: false, + + losingFocus: false, + // ------------------------------------------------------------------------- // Observers + // close calendar and set value with formatting + dateSelected: Ember.observer( + 'selectedDate', + function() { + this.updateValue(); + //this.set( 'isOpen', false ); + } + ), + /** * Datepicker plugin options * @@ -281,7 +359,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa options: Ember.computed( function() { return { - autoclose: this.get( 'autoclose' ), + /*autoclose: this.get( 'autoclose' ), calendarWeeks: this.get( 'calendarWeeks' ), clearBtn: this.get( 'clearBtn' ), daysOfWeekDisabled: this.get( 'daysOfWeekDisabled' ), @@ -298,7 +376,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa startView: this.get( 'startView' ), todayBtn: this.get( 'todayBtn' ), todayHighlight: this.get( 'todayHighlight' ), - weekStart: this.get( 'weekStart' ) + weekStart: this.get( 'weekStart' )*/ }; } ), @@ -328,11 +406,48 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa // ------------------------------------------------------------------------- // Methods - selectDate( date ) { - const format = window.moment().localeData().longDateFormat( 'L' ); + checkInput() { + let value = this.get( 'value' ); + const format = this.get( 'format' ); + const parseFormats = this.get( 'parseFormats' ); - this.set( 'value', date.format( format ) ); - this.set( 'isOpen', false ); + //console.log( 'from value observer: ', this.get( 'value' ) ); + + value = value.replace(/\W+/g, "-"); + + const date = window.moment( value, parseFormats, this.get( 'locale' ), true ); + //console.log( 'date entered: ', date.format( format ) ); + //return; + if ( date.isValid() ) { + this.set( 'selectedDate', date ); + } + }, + + parseFormats: Ember.computed( + 'locale', + function() { + const formats = Ember.A(); + const localeData = window.moment().localeData(); + + formats.push( + localeData.longDateFormat('L').replace(/\W+/g, "-"), + localeData.longDateFormat('LL').replace(/\W+/g, "-"), + localeData.longDateFormat('L').replace('DD', 'D').replace('MM', 'M').replace(/\W+/g, "-") + ); + + return formats; + } + ), + + viewingDate: Ember.computed( + 'selectedDate', + function() { + return this.get( 'selectedDate' ); + } + ), + + selectDate( date ) { + this.set( 'selectedDate', date ); }, /** @@ -348,12 +463,6 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa datepicker.on( this.namespaceEvent( 'changeDate' ), () => { this.sendAction(); });*/ - const context = this; - - this.$( '> input' ).on( 'focus', function() { - context.set( 'isOpen', true ); - console.log( 'opening' ); - }); }, /** @@ -364,5 +473,16 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa */ unregisterEvents() { //this.$( 'input.date-picker' ).off( this.namespaceEvent( 'changeDate' ) ); + }, + + updateValue() { + const date = this.get( 'selectedDate' ); + const format = this.get( 'format' ); + + if ( date === null ) { + return; + } + + this.set( 'value', date.format( format ) ); } }); diff --git a/addon/templates/components/sl-calendar.hbs b/addon/templates/components/sl-calendar.hbs index 938ed99b..c1f97a71 100644 --- a/addon/templates/components/sl-calendar.hbs +++ b/addon/templates/components/sl-calendar.hbs @@ -1,7 +1,7 @@
{{#if viewingDays}}
- +
{{#each shortWeekDayNames as |dayName|}} - + {{/each}} @@ -32,6 +32,7 @@ new=day.new old=day.old date=day.date + focused=day.focused }} {{/each}} @@ -43,7 +44,7 @@ {{#if viewingMonths}}
-
@@ -16,7 +16,7 @@
{{dayName}}{{dayName}}
+
@@ -79,7 +80,7 @@ {{#if viewingYears}}
- +
diff --git a/addon/templates/components/sl-date-picker.hbs b/addon/templates/components/sl-date-picker.hbs index ee09ab5c..055acfd7 100644 --- a/addon/templates/components/sl-date-picker.hbs +++ b/addon/templates/components/sl-date-picker.hbs @@ -9,16 +9,21 @@ id=inputId placeholder=placeholder value=value + focus-in="inputFocused" + focus-out="inputBlurred" + key-up="inputKeyUp" }} -{{#if isOpen}} -
+{{#if hasFocus}} +
{{sl-calendar action="selectDate" fixedWeekCount=true locale=locale + selectedDate=selectedDate + viewingDate=viewingDate }}
diff --git a/app/styles/sl-calendar.less b/app/styles/sl-calendar.less index da4231db..02097d91 100644 --- a/app/styles/sl-calendar.less +++ b/app/styles/sl-calendar.less @@ -21,3 +21,6 @@ } } +td:focus, td.focused { + background: #CCC; +} From ea0eba27af54d3711c1b65e834935418cee87c8f Mon Sep 17 00:00:00 2001 From: J Corley Date: Wed, 20 Jan 2016 15:40:19 -0600 Subject: [PATCH 07/25] Commented out bootstrap-datepicker css include. Temporary addition of selection constraints in dummy app. **CALENDAR** Started removing unnecessary dom structure. Added support for selection constraint. First run of styles. **CALENDAR DAY** Fix for focusing the day (wai-aria support). Added support for disabled days. **DATE PICKER** Initial support for selection constraint. --- addon/components/sl-calendar-day.js | 31 +++++++------ addon/components/sl-calendar.js | 35 ++++++++++++++- addon/components/sl-date-picker.js | 10 ++++- addon/templates/components/sl-calendar.hbs | 11 ++--- app/styles/sl-calendar.less | 44 ++++++++++++++++++- app/styles/sl-ember-components.less | 2 +- .../app/controllers/demos/sl-calendar.js | 4 ++ .../dummy/app/templates/demos/sl-calendar.hbs | 2 +- 8 files changed, 112 insertions(+), 27 deletions(-) diff --git a/addon/components/sl-calendar-day.js b/addon/components/sl-calendar-day.js index a89fcc11..1be38176 100644 --- a/addon/components/sl-calendar-day.js +++ b/addon/components/sl-calendar-day.js @@ -20,10 +20,11 @@ export default Ember.Component.extend({ /** @type {String[]} */ classNameBindings: [ - 'active', + 'active:selected', 'new', 'old', - 'isToday:today' + 'isToday:today', + 'restricted:disabled' ], /** @type {String[]} */ @@ -56,6 +57,12 @@ export default Ember.Component.extend({ //} }, + didInsertElement() { + this._super( ...arguments ); + + this.applyFocus(); + }, + // ------------------------------------------------------------------------- // Properties @@ -96,24 +103,20 @@ export default Ember.Component.extend({ ariaRole: 'gridcell', + restricted: false, + // ------------------------------------------------------------------------- // Observers - applyFocus: Ember.observer( - 'focused', - function() { - if ( this.get( 'focused' ) ) { - console.log( 'focused' ); - Ember.run.scheduleOnce( 'afterRender', this, () => { - this.$().get( 0 ).focus(); - }); - } - } - ), - // ------------------------------------------------------------------------- // Methods + applyFocus() { + if ( this.get( 'focused' ) ) { + this.$().get( 0 ).focus(); + } + }, + ariaSelected: Ember.computed( 'active', function() { diff --git a/addon/components/sl-calendar.js b/addon/components/sl-calendar.js index cbd14030..4cd368ad 100755 --- a/addon/components/sl-calendar.js +++ b/addon/components/sl-calendar.js @@ -262,12 +262,22 @@ export default Ember.Component.extend({ this._super( ...arguments ); const today = window.moment(); + const selectConstraint = this.get( 'selectConstraint' ); this.set( 'today', today ); if ( !this.get( 'viewingDate' ) ) { this.set( 'viewingDate', today ); } + + for ( let i in selectConstraint ) { + selectConstraint[ i ] = window.moment( selectConstraint[i] ); + if ( !selectConstraint[ i ].isValid ) { + // throw an error or warning here + } + } + this.set( 'selectConstraint', selectConstraint ); + console.log( selectConstraint ); /* const viewingDate = this.get( 'viewingDate' ); @@ -338,6 +348,11 @@ export default Ember.Component.extend({ hasFocus: false, + selectConstraint: { + start: null, + end: null + }, + /** * The current view mode for the calendar * @@ -621,12 +636,14 @@ export default Ember.Component.extend({ 'fixedWeekCount', 'locale', 'viewingDate', + 'selectConstraint', function() { const weeks = Ember.A(); const showingMonth = this.get( 'showingMonth' ); const selectedDate = this.get( 'selectedDate' ); const viewingDate = this.get( 'viewingDate' ); + const selectConstraint = this.get( 'selectConstraint' ); let firstOfMonth = window.moment( '01-' + showingMonth + '-' + this.get( 'showingYear' ), 'DD-MM-YYYY' ).locale( this.get( 'locale' ) ); let firstDayOfWeek = firstOfMonth.localeData().firstDayOfWeek(); @@ -653,6 +670,7 @@ export default Ember.Component.extend({ let isActive = false; let inNextMonth = nextDayToShow.month() === showingMonth; let inPrevMonth = nextDayToShow.month() === showingMonth - 2; + let isRestricted = false; if ( showingMonth === 1 && nextDayToShow.month() === 11 ) { inPrevMonth = true; @@ -662,13 +680,26 @@ export default Ember.Component.extend({ isActive = nextDayToShow.isSame( selectedDate, 'day' ); } + if ( selectConstraint.start ) { + if ( nextDayToShow.isBefore( selectConstraint.start ) ) { + isRestricted = true; + } + } + + if ( selectConstraint.end ) { + if ( nextDayToShow.isAfter( selectConstraint.end ) ) { + isRestricted = true; + } + } + const day = { date: window.moment( nextDayToShow ), day: nextDayToShow.date(), old: inPrevMonth, new: inNextMonth, - focused: nextDayToShow.isSame( viewingDate, 'day' ), - active: isActive + focused: nextDayToShow.isSame( viewingDate, 'day' ) && this.get( 'hasFocus' ), + active: isActive, + restricted: isRestricted }; days.push( day ); nextDayToShow.add( 1, 'days' ); diff --git a/addon/components/sl-date-picker.js b/addon/components/sl-date-picker.js index de7e3bf0..f5109bb7 100755 --- a/addon/components/sl-date-picker.js +++ b/addon/components/sl-date-picker.js @@ -125,7 +125,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa */ willClearRender() { this._super( ...arguments ); - this.unregisterEvents(); + //this.unregisterEvents(); }, // ------------------------------------------------------------------------- @@ -338,6 +338,11 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa losingFocus: false, + selectConstraint: { + start: null, + end: null + }, + // ------------------------------------------------------------------------- // Observers @@ -346,7 +351,8 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa 'selectedDate', function() { this.updateValue(); - //this.set( 'isOpen', false ); + //this.$( '> input' ).focus(); + //this.set( 'hasFocus', false ); } ), diff --git a/addon/templates/components/sl-calendar.hbs b/addon/templates/components/sl-calendar.hbs index c1f97a71..4e27d6f3 100644 --- a/addon/templates/components/sl-calendar.hbs +++ b/addon/templates/components/sl-calendar.hbs @@ -4,14 +4,14 @@ - - - @@ -33,6 +33,7 @@ old=day.old date=day.date focused=day.focused + restricted=day.restricted }} {{/each}} diff --git a/app/styles/sl-calendar.less b/app/styles/sl-calendar.less index 02097d91..902ed972 100644 --- a/app/styles/sl-calendar.less +++ b/app/styles/sl-calendar.less @@ -21,6 +21,46 @@ } } -td:focus, td.focused { - background: #CCC; + +@calendar-border-radius-small: @border-radius-small; +@calendar-default-color: @btn-default-color; +@calendar-disabled-bg: @input-bg-disabled; +@calendar-today-bg: @state-warning-bg; +@calendar-selected-bg: @btn-primary-bg; +@calendar-selected-color: @btn-primary-color; +@calendar-focus-bg: @table-bg-active; + +.sl-ember-components.calendar { + table { + th, td { + text-align: center; + } + + td { + border-radius: @calendar-border-radius-small; + } + + td.today { + background-color: @calendar-today-bg; + } + + td.selected { + background-color: @calendar-selected-bg; + color: @calendar-selected-color; + } + + td:focus, td.focused, td:hover { + background-color: @calendar-focus-bg; + color: @calendar-default-color; + } + + td.disabled, td.old, td.new { + color: @gray-light; + } + + td.disabled { + background-color: @calendar-disabled-bg; + border-radius: 0; + } + } } diff --git a/app/styles/sl-ember-components.less b/app/styles/sl-ember-components.less index 05780ebe..ef3ccfb9 100755 --- a/app/styles/sl-ember-components.less +++ b/app/styles/sl-ember-components.less @@ -13,7 +13,7 @@ // ------------------------------------------------------------------------- // Bootstrap Datepicker -@import 'bower_components/bootstrap-datepicker/less/datepicker3'; +//@import 'bower_components/bootstrap-datepicker/less/datepicker3'; // ------------------------------------------------------------------------- diff --git a/tests/dummy/app/controllers/demos/sl-calendar.js b/tests/dummy/app/controllers/demos/sl-calendar.js index 761016de..745b4a27 100644 --- a/tests/dummy/app/controllers/demos/sl-calendar.js +++ b/tests/dummy/app/controllers/demos/sl-calendar.js @@ -5,5 +5,9 @@ export default Ember.Controller.extend({ logLabel( date, data ) { window.console.log( 'logLabel: ', date, data ); } + }, + + tempdates: { + start: '01/05/2016' } }); diff --git a/tests/dummy/app/templates/demos/sl-calendar.hbs b/tests/dummy/app/templates/demos/sl-calendar.hbs index 062205e5..1aee2e29 100755 --- a/tests/dummy/app/templates/demos/sl-calendar.hbs +++ b/tests/dummy/app/templates/demos/sl-calendar.hbs @@ -21,7 +21,7 @@
Rendered Component
- {{sl-calendar action="logLabel" content=content fixedWeekCount=false locale="en"}} + {{sl-calendar action="logLabel" content=content fixedWeekCount=false locale="en" selectConstraint=tempdates}}
From cdd4358d20736f5b5ce7c27a77a342cf05113285 Mon Sep 17 00:00:00 2001 From: J Corley Date: Fri, 22 Jan 2016 10:33:37 -0600 Subject: [PATCH 08/25] First run at styling for new calendar system. Removed datepicker plugin from bower.json. Removed datepicker plugin import from build script. Removed datepicker plugin from readme. Removed datepicker plugin from blueprint. **CALENDAR** Changed month and year list generation to be nested array based. Streamlined the logic for next and prev month marking. Reworked the dom structure to allow easier use of TWBS styling. First run of TWBS styles on new calendar. **CALENDAR MONTH** Changed tagName to TD. Changed active className. **CALENDAR YEAR** Changed tagName to TD. Changed active className. **DATE PICKER** Added some temporary debug statements. **DATE RANGE PICKER** Changed format to default to null. Commented most of the code. Added selectConstraint object. Temporarily removed one of the date pickers. --- README.md | 1 - addon/components/sl-calendar-month.js | 4 +- addon/components/sl-calendar-year.js | 4 +- addon/components/sl-calendar.js | 75 ++++-- addon/components/sl-date-picker.js | 9 + addon/components/sl-date-range-picker.js | 42 +++- addon/templates/components/sl-calendar.hbs | 238 ++++++++++-------- addon/templates/components/sl-date-picker.hbs | 1 + .../components/sl-date-range-picker.hbs | 8 - app/styles/sl-calendar.less | 77 ++++-- app/styles/sl-ember-components.less | 6 - blueprints/sl-ember-components/index.js | 3 - bower.json | 1 - index.js | 1 - .../dummy/app/templates/demos/sl-calendar.hbs | 2 +- 15 files changed, 279 insertions(+), 193 deletions(-) diff --git a/README.md b/README.md index 8c42ad7f..7e117d3b 100755 --- a/README.md +++ b/README.md @@ -98,7 +98,6 @@ Provides a way for individual components to throw errors that are able to be rec All of this functionality is provided through a combination of leveraging the best-of-breed of other component offerings as well as our own implementations when the existing offerings were deficient. Existing offerings that were leveraged include: * [Twitter Bootstrap](http://getbootstrap.com/) -* [Bootstrap-Datepicker](http://bootstrap-datepicker.readthedocs.org/en/release/#) * [Highcharts](http://www.highcharts.com/) * [Select2](http://ivaynberg.github.io/select2/) * [typeahead.js](https://twitter.github.io/typeahead.js/) diff --git a/addon/components/sl-calendar-month.js b/addon/components/sl-calendar-month.js index f37d087d..83da3ff7 100755 --- a/addon/components/sl-calendar-month.js +++ b/addon/components/sl-calendar-month.js @@ -15,7 +15,7 @@ export default Ember.Component.extend({ /** @type {String[]} */ classNameBindings: [ - 'active' + 'active:selected' ], /** @type {String[]} */ @@ -24,7 +24,7 @@ export default Ember.Component.extend({ ], /** @type {String} */ - tagName: 'span', + tagName: 'td', // ------------------------------------------------------------------------- // Actions diff --git a/addon/components/sl-calendar-year.js b/addon/components/sl-calendar-year.js index 27eb7b50..d429f720 100644 --- a/addon/components/sl-calendar-year.js +++ b/addon/components/sl-calendar-year.js @@ -15,7 +15,7 @@ export default Ember.Component.extend({ /** @type {String[]} */ classNameBindings: [ - 'active', + 'active:selected', 'new', 'old' ], @@ -24,7 +24,7 @@ export default Ember.Component.extend({ layout, /** @type {String} */ - tagName: 'span', + tagName: 'td', // ------------------------------------------------------------------------- // Actions diff --git a/addon/components/sl-calendar.js b/addon/components/sl-calendar.js index 4cd368ad..51f611c0 100755 --- a/addon/components/sl-calendar.js +++ b/addon/components/sl-calendar.js @@ -159,6 +159,7 @@ export default Ember.Component.extend({ } this.set( 'viewMode', view ); + this.$().focus(); } }, @@ -363,6 +364,13 @@ export default Ember.Component.extend({ // ------------------------------------------------------------------------- // Observers + fubar: Ember.observer( + 'viewingDate', + function() { + console.log( this.get('viewingDate') ); + } + ), + // ------------------------------------------------------------------------- // Methods @@ -376,6 +384,8 @@ export default Ember.Component.extend({ return; } + console.log( 'setmonth', month ); + const viewingDate = this.get( 'viewingDate' ); this.set( 'viewingDate', window.moment( viewingDate ).month( month - 1 ) ); @@ -536,21 +546,29 @@ export default Ember.Component.extend({ const m = window.moment().locale( this.get( 'locale' ) ); const monthNames = window.moment.monthsShort(); const months = Ember.A(); + let monthCount = 1; + + for ( let rowCount = 1; rowCount <= 3; rowCount++ ) { + const row = Ember.A(); + + for ( let colCount = 1; colCount <= 4; colCount++ ) { + let isActive = false; + + if ( selectedDate ) { + isActive = ( selectedDate.month() + 1 ) === monthCount && selectedDate.year() === showingYear; + } - for ( let month = 1; month <= 12; month++ ) { - let isActive = false; + row.push({ + active: isActive, + monthName: monthNames[ monthCount - 1 ], + month: monthCount + }); - if ( selectedDate ) { - isActive = ( selectedDate.month() + 1 ) === month && selectedDate.year() === showingYear; + monthCount++; } - months.push({ - active: isActive, - monthName: monthNames[ month - 1 ], - month - }); + months.push( row ); } - return months; } ), @@ -668,13 +686,13 @@ export default Ember.Component.extend({ for ( let k = 0; k < 7; k++ ) { let isActive = false; - let inNextMonth = nextDayToShow.month() === showingMonth; - let inPrevMonth = nextDayToShow.month() === showingMonth - 2; + let inNextMonth = nextDayToShow.isAfter( viewingDate, 'month' );//month() === showingMonth; + let inPrevMonth = nextDayToShow.isBefore( viewingDate, 'month' );//.month() === showingMonth - 2; let isRestricted = false; - if ( showingMonth === 1 && nextDayToShow.month() === 11 ) { + /*if ( showingMonth === 1 && nextDayToShow.month() === 11 ) { inPrevMonth = true; - } + }*/ if ( selectedDate ) { isActive = nextDayToShow.isSame( selectedDate, 'day' ); @@ -733,20 +751,29 @@ export default Ember.Component.extend({ const decadeEnd = this.get( 'decadeEnd' ); const selectedDate = this.get( 'selectedDate' ); const years = Ember.A(); + let yearCount = decadeStart - 1; + + for ( let rowCount = 1; rowCount <= 3; rowCount++ ) { + const row = Ember.A(); + + for ( let colCount = 1; colCount <= 4; colCount++ ) { + let isActive = false; + + if ( selectedDate ) { + isActive = yearCount === selectedDate.year(); + } - for ( let year = decadeStart - 1; year <= decadeEnd + 1; year++ ) { - let isActive = false; + row.push({ + active: isActive, + 'new': yearCount > decadeEnd, + old: yearCount < decadeStart, + year: yearCount + }); - if ( selectedDate ) { - isActive = year === selectedDate.year(); + yearCount++; } - years.push({ - active: isActive, - 'new': year > decadeEnd, - old: year < decadeStart, - year - }); + years.push( row ); } return years; diff --git a/addon/components/sl-date-picker.js b/addon/components/sl-date-picker.js index f5109bb7..34e30a4f 100755 --- a/addon/components/sl-date-picker.js +++ b/addon/components/sl-date-picker.js @@ -37,6 +37,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa inputBlurred() { this.trigger( 'focusOut' ); + console.log( '(inputBlurred) format: ', this.get( 'format' ) ); this.updateValue(); }, @@ -108,10 +109,15 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa init() { this._super( ...arguments ); + console.log( 'formatting inside of init', this.get( 'format' ) ); + if ( !this.get( 'format' ) ) { + console.log( 'setting format' ); const format = window.moment().localeData().longDateFormat( 'L' ); this.set( 'format', format ); } + + console.log( this.get( 'format' ) ); }, keyPress() { @@ -350,6 +356,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa dateSelected: Ember.observer( 'selectedDate', function() { + console.log( '(selectedDate) format: ', this.get( 'format' ) ); this.updateValue(); //this.$( '> input' ).focus(); //this.set( 'hasFocus', false ); @@ -485,6 +492,8 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa const date = this.get( 'selectedDate' ); const format = this.get( 'format' ); + console.log( 'updateValue', format ); + if ( date === null ) { return; } diff --git a/addon/components/sl-date-range-picker.js b/addon/components/sl-date-range-picker.js index 116038c1..f9b47adc 100755 --- a/addon/components/sl-date-range-picker.js +++ b/addon/components/sl-date-range-picker.js @@ -36,19 +36,23 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { * * @returns {undefined} */ - didInsertElement() { + /* didInsertElement() { this._super( ...arguments ); - this.setupFocusTransition(); - }, + //this.setupFocusTransition(); + },*/ /** * willClearRender event hook * * @returns {undefined} */ - willClearRender() { + /*willClearRender() { + this._super( ...arguments ); + //this.unregisterEvents(); + },*/ + + init() { this._super( ...arguments ); - this.unregisterEvents(); }, // ------------------------------------------------------------------------- @@ -66,7 +70,7 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { * * @type {String} */ - format: 'mm/dd/yyyy', + format: null, /** * The last valid date for the date range @@ -89,9 +93,21 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { */ startDateValue: null, + selectConstraint: { + start: null, + end: null + }, + // ------------------------------------------------------------------------- // Observers + fubar: Ember.observer( + 'format', + function() { + console.log( '(RANGE obs) format: ', this.get( 'format' ) ); + } + ), + // ------------------------------------------------------------------------- // Methods @@ -106,7 +122,7 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { 'minDate', 'startDateValue', function() { - const minDate = this.get( 'minDate' ); + /*const minDate = this.get( 'minDate' ); const startDateValue = this.get( 'startDateValue' ); if ( startDateValue ) { @@ -117,7 +133,7 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { return minDate; } - return null; + return null;*/ } ), @@ -132,7 +148,7 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { 'endDateValue', 'maxDate', function() { - const endDateValue = this.get( 'endDateValue' ); + /*const endDateValue = this.get( 'endDateValue' ); const maxDate = this.get( 'maxDate' ); if ( endDateValue ) { @@ -143,7 +159,7 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { return maxDate; } - return null; + return null;*/ } ), @@ -155,11 +171,11 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { * @returns {undefined} */ setupFocusTransition() { - this.set( 'startDateInput', this.$( '.sl-daterange-start-date input' ) ); + /*this.set( 'startDateInput', this.$( '.sl-daterange-start-date input' ) ); this.set( 'endDateInput', this.$( '.sl-daterange-end-date input' ) ); this.get( 'startDateInput' ).on( this.namespaceEvent( 'changeDate' ), () => { this.get( 'endDateInput' ).trigger( 'focus' ); - }); + });*/ }, /** @@ -169,7 +185,7 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { * @returns {undefined} */ unregisterEvents() { - this.get( 'startDateInput' ).off( this.namespaceEvent( 'changeDate' ) ); + //this.get( 'startDateInput' ).off( this.namespaceEvent( 'changeDate' ) ); } }); diff --git a/addon/templates/components/sl-calendar.hbs b/addon/templates/components/sl-calendar.hbs index ed54e390..8d636caf 100644 --- a/addon/templates/components/sl-calendar.hbs +++ b/addon/templates/components/sl-calendar.hbs @@ -1,116 +1,140 @@ -
- {{#if viewingDays}} -
-
- previous month + + previous month + {{showingMonthString}} {{showingYear}} - next month + + next month
- - - - - - +{{#if viewingDays}} +
+ +
- previous month - - {{showingMonthString}} {{showingYear}} - - next month -
+ + + + + +
+ + + + {{showingMonthString}} {{showingYear}} + + + +
+ + + + + {{#each shortWeekDayNames as |dayName|}} + + {{/each}} + + + + {{#each weeksInMonthView as |weekDays|}} - {{#each shortWeekDayNames as |dayName|}} - + {{#each weekDays as |day|}} + {{sl-calendar-day + action="selectDate" + active=day.active + content=day.content + day=day.day + new=day.new + old=day.old + date=day.date + focused=day.focused + restricted=day.restricted + }} {{/each}} - - - {{#each weeksInMonthView as |weekDays|}} - - {{#each weekDays as |day|}} - {{sl-calendar-day - action="selectDate" - active=day.active - content=day.content - day=day.day - new=day.new - old=day.old - date=day.date - focused=day.focused - restricted=day.restricted - }} - {{/each}} - - {{/each}} - -
{{dayName}}
{{dayName}}
-
- {{/if}} + {{/each}} + +
+
+{{/if}} - {{#if viewingMonths}} -
- - - - - - - - - - - - - -
- previous year - - {{showingYear}} - - next year -
- {{#each monthsInYearView as |month|}} - {{#sl-calendar-month - action="selectMonth" - active=month.active - locale=locale - month=month.month - }} - {{month.monthName}} - {{/sl-calendar-month}} - {{/each}} -
-
- {{/if}} +{{#if viewingMonths}} +
- {{#if viewingYears}} -
- - +
+ + + + + +
+ + + + {{showingYear}} + + + +
+ + + + {{#each monthsInYearView as |monthRow|}} - - - + {{#each monthRow as |month|}} + {{#sl-calendar-month + action="selectMonth" + active=month.active + locale=locale + month=month.month + }} + {{month.monthName}} + {{/sl-calendar-month}} + {{/each}} - - + {{/each}} + +
- previous decade - - {{decadeStart}}-{{decadeEnd}} - - next decade -
+
+{{/if}} + +{{#if viewingYears}} +
+ + + + + + + +
+ + + + {{decadeStart}}-{{decadeEnd}} + + + +
+ + + + {{#each yearsInDecadeView as |yearRow|}} - + {{#each yearRow as |year|}} + {{sl-calendar-year + action="selectYear" + active=year.active + old=year.old + new=year.new + year=year.year + }} + {{/each}} - -
- {{#each yearsInDecadeView as |year|}} - {{sl-calendar-year - action="selectYear" - active=year.active - old=year.old - new=year.new - year=year.year - }} - {{/each}} -
-
- {{/if}} -
+ {{/each}} + +
+
+{{/if}} diff --git a/addon/templates/components/sl-date-picker.hbs b/addon/templates/components/sl-date-picker.hbs index 055acfd7..f944d994 100644 --- a/addon/templates/components/sl-date-picker.hbs +++ b/addon/templates/components/sl-date-picker.hbs @@ -24,6 +24,7 @@ locale=locale selectedDate=selectedDate viewingDate=viewingDate + selectConstraint=selectConstraint }}
diff --git a/addon/templates/components/sl-date-range-picker.hbs b/addon/templates/components/sl-date-range-picker.hbs index f2a251bb..672b435b 100755 --- a/addon/templates/components/sl-date-range-picker.hbs +++ b/addon/templates/components/sl-date-range-picker.hbs @@ -13,14 +13,6 @@ format=format }} - {{sl-date-picker - class="sl-daterange-end-date col-md-6" - endDate=maxDate - placeholder=endDatePlaceholder - startDate=earliestEndDate - value=endDateValue - format=format - }} {{#if helpText}} diff --git a/app/styles/sl-calendar.less b/app/styles/sl-calendar.less index 8ebc88bf..8d0d8590 100644 --- a/app/styles/sl-calendar.less +++ b/app/styles/sl-calendar.less @@ -1,4 +1,27 @@ +@calendar-border-radius-small: @border-radius-small; + +@calendar-default-color: @btn-default-color; + +@calendar-disabled-bg: @gray-lighter; +@calendar-today-bg: @state-warning-bg;//@btn-warning-bg; +@calendar-today-border: @state-warning-border;//@btn-warning-border; +@calendar-selected-bg: @btn-primary-bg; +@calendar-selected-color: @btn-primary-color; +@calendar-focus-bg: @gray-lighter;//@table-bg-active; + .sl-ember-components.calendar { + + display: inline-block; + + table.controls { + width: 100%; + margin-bottom: @table-condensed-cell-padding; + + th:first-child, th:last-child { + width: 20%; + } + } + .sl-icon-previous::before { content: @icon-calendar-previous; } @@ -7,24 +30,9 @@ content: @icon-calendar-next; } - .datepicker-months, - .datepicker-days, - .datepicker-years { - display: block; - } -} - - -@calendar-border-radius-small: @border-radius-small; -@calendar-default-color: @btn-default-color; -@calendar-disabled-bg: @input-bg-disabled; -@calendar-today-bg: @state-warning-bg; -@calendar-selected-bg: @btn-primary-bg; -@calendar-selected-color: @btn-primary-color; -@calendar-focus-bg: @table-bg-active; - -.sl-ember-components.calendar { table { + border-collapse: separate; + th, td { text-align: center; } @@ -35,6 +43,12 @@ td.today { background-color: @calendar-today-bg; + border: 1px solid @calendar-today-border; + } + + td:focus, td.focused, td:hover { + background-color: @calendar-focus-bg; + /*color: @calendar-default-color;*/ } td.selected { @@ -42,18 +56,23 @@ color: @calendar-selected-color; } - td:focus, td.focused, td:hover { - background-color: @calendar-focus-bg; - color: @calendar-default-color; - } - - td.disabled, td.old, td.new { - color: @gray-light; + td.old, td.new { + /*color: @gray-light;*/ + opacity: .5; } td.disabled { background-color: @calendar-disabled-bg; border-radius: 0; + + &.old, &.new { + //background-color: lighten( @calendar-disabled-bg, 4%, relative ); + } + } + + & > tbody > tr > td > span { + width: 25%; + display: inline-block; } } } @@ -65,3 +84,13 @@ .sl-icon-next { &:extend(.sl-ember-components-icons all); } + + +.datepicker-days td { + width: 2.2em; + height: 2.2em; +} +.datepicker-months td, .datepicker-years td { + width: 3.875em; + height: 4.25em; +} diff --git a/app/styles/sl-ember-components.less b/app/styles/sl-ember-components.less index 2b4f2200..4209f5fe 100755 --- a/app/styles/sl-ember-components.less +++ b/app/styles/sl-ember-components.less @@ -10,12 +10,6 @@ @import 'variables.less'; -// ------------------------------------------------------------------------- -// Bootstrap Datepicker - -//@import 'bower_components/bootstrap-datepicker/less/datepicker3'; - - // ------------------------------------------------------------------------- // sl-ember-components diff --git a/blueprints/sl-ember-components/index.js b/blueprints/sl-ember-components/index.js index 168a669f..e3904b8f 100755 --- a/blueprints/sl-ember-components/index.js +++ b/blueprints/sl-ember-components/index.js @@ -4,9 +4,6 @@ module.exports = { { name: 'bootstrap', target: '~3.2.0' - }, { - name: 'bootstrap-datepicker', - target: '~1.3.0' }, { name: 'highcharts', target: '~4.1.10' diff --git a/bower.json b/bower.json index 6862e7c3..3be35917 100755 --- a/bower.json +++ b/bower.json @@ -2,7 +2,6 @@ "name": "sl-ember-components", "dependencies": { "bootstrap": "3.3.6", - "bootstrap-datepicker": "~1.3.0", "ember": "1.13.7", "ember-cli-shims": "ember-cli/ember-cli-shims#0.0.3", "ember-cli-test-loader": "ember-cli-test-loader#0.2.1", diff --git a/index.js b/index.js index 5ad6d19a..d75cfa0d 100755 --- a/index.js +++ b/index.js @@ -65,7 +65,6 @@ module.exports = { // Javascript app.import( app.bowerDirectory + '/bootstrap/dist/js/bootstrap.js' ); - app.import( app.bowerDirectory + '/bootstrap-datepicker/js/bootstrap-datepicker.js' ); app.import( app.bowerDirectory + '/highcharts/highcharts.src.js' ); app.import( app.bowerDirectory + '/jquery-mousewheel/jquery.mousewheel.js' ); app.import( app.bowerDirectory + '/moment/min/moment-with-locales.js' ); diff --git a/tests/dummy/app/templates/demos/sl-calendar.hbs b/tests/dummy/app/templates/demos/sl-calendar.hbs index 1aee2e29..cc5d7f41 100755 --- a/tests/dummy/app/templates/demos/sl-calendar.hbs +++ b/tests/dummy/app/templates/demos/sl-calendar.hbs @@ -21,7 +21,7 @@
Rendered Component
- {{sl-calendar action="logLabel" content=content fixedWeekCount=false locale="en" selectConstraint=tempdates}} + {{sl-calendar action="logLabel" content=content fixedWeekCount=true locale="en" selectConstraint=tempdates}}
From 672f1c764e396250897ec4c614c2692f55182dac Mon Sep 17 00:00:00 2001 From: J Corley Date: Mon, 25 Jan 2016 09:46:17 -0600 Subject: [PATCH 09/25] Commiting before opimizations. ** CALENDAR ** Fixed a bug that allowed restricted dates to be selected. ** DATE PICKER ** Added seeded date to demo. Commented three unused properties. Moved default format logic from init() to a computed property. Added date constraint logic for typed dates. ** DATE RANGE PICKER ** Added seeded dates to the demo. Temporarily added an init() to force constraints as dates. Commented two unused properties. Added two private properties. Added locale property. Added computed properties for the selectConstraints to be passed to each date-picker. Re-added the removed second date picker to the template. --- addon/components/sl-calendar-day.js | 2 + addon/components/sl-calendar.js | 23 ++++++- addon/components/sl-date-picker.js | 56 +++++++++-------- addon/components/sl-date-range-picker.js | 61 +++++++++++++++---- .../components/sl-date-range-picker.hbs | 14 ++++- .../app/controllers/demos/sl-date-picker.js | 16 +++++ .../controllers/demos/sl-date-range-picker.js | 17 ++++++ .../app/templates/demos/sl-date-picker.hbs | 2 +- .../templates/demos/sl-date-range-picker.hbs | 3 + 9 files changed, 153 insertions(+), 41 deletions(-) create mode 100644 tests/dummy/app/controllers/demos/sl-date-picker.js create mode 100644 tests/dummy/app/controllers/demos/sl-date-range-picker.js diff --git a/addon/components/sl-calendar-day.js b/addon/components/sl-calendar-day.js index 1be38176..2649be59 100644 --- a/addon/components/sl-calendar-day.js +++ b/addon/components/sl-calendar-day.js @@ -53,8 +53,10 @@ export default Ember.Component.extend({ const date = this.get( 'date' ); //if ( content ) { + //if ( !this.get( 'restricted' ) ) { this.sendAction( 'action', date, content ); //} + //} }, didInsertElement() { diff --git a/addon/components/sl-calendar.js b/addon/components/sl-calendar.js index 51f611c0..2df54a16 100755 --- a/addon/components/sl-calendar.js +++ b/addon/components/sl-calendar.js @@ -116,9 +116,11 @@ export default Ember.Component.extend({ }, selectDate( date, data ) { - this.setDate( date ); + const isValid = this.setDate( date ); - this.sendAction( 'action', date, data ); + if ( isValid ) { + this.sendAction( 'action', date, data ); + } }, /** @@ -243,7 +245,8 @@ export default Ember.Component.extend({ case 32: // space case 13: // enter - this.set( 'selectedDate', viewingDate ); + //this.set( 'selectedDate', viewingDate ); + this.setDate( viewingDate ); break; default: @@ -375,6 +378,20 @@ export default Ember.Component.extend({ // Methods setDate( date ) { + const selectConstraint = this.get( 'selectConstraint' ); + + if ( selectConstraint.start ) { + if ( date.isBefore( selectConstraint.start ) ) { + return; + } + } + + if ( selectConstraint.end ) { + if ( date.isAfter( selectConstraint.end ) ) { + return; + } + } + this.set( 'selectedDate', window.moment( date ) ); this.set( 'viewingDate', window.moment( date ) ); }, diff --git a/addon/components/sl-date-picker.js b/addon/components/sl-date-picker.js index 34e30a4f..9e685b47 100755 --- a/addon/components/sl-date-picker.js +++ b/addon/components/sl-date-picker.js @@ -37,7 +37,6 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa inputBlurred() { this.trigger( 'focusOut' ); - console.log( '(inputBlurred) format: ', this.get( 'format' ) ); this.updateValue(); }, @@ -71,6 +70,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa didInsertElement() { this._super( ...arguments ); this.setupDatepicker(); + this.checkInput(); }, focusIn( event ) { @@ -106,20 +106,6 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa this.set( 'losingFocus', runNext ); }, - init() { - this._super( ...arguments ); - - console.log( 'formatting inside of init', this.get( 'format' ) ); - - if ( !this.get( 'format' ) ) { - console.log( 'setting format' ); - const format = window.moment().localeData().longDateFormat( 'L' ); - this.set( 'format', format ); - } - - console.log( this.get( 'format' ) ); - }, - keyPress() { console.log( 'date picker: keypress' ); }, @@ -184,7 +170,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @type {?Date|String} */ - endDate: null, + //endDate: null, /** * Whether or not to force parsing of the input value when the picker is @@ -196,7 +182,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @type {Boolean} */ - forceParse: true, + //forceParse: true, /** * The date format @@ -212,6 +198,12 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa */ format: null, + formatString: Ember.computed( + function() { + return this.get( 'format' ) || window.moment().localeData().longDateFormat( 'L' ); + } + ), + /** * The help text below the datepicker * @@ -294,7 +286,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @type {?Date|String} */ - startDate: null, + //startDate: null, /** * The view that the datepicker should show when it is opened; accepts @@ -356,7 +348,6 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa dateSelected: Ember.observer( 'selectedDate', function() { - console.log( '(selectedDate) format: ', this.get( 'format' ) ); this.updateValue(); //this.$( '> input' ).focus(); //this.set( 'hasFocus', false ); @@ -423,6 +414,11 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa let value = this.get( 'value' ); const format = this.get( 'format' ); const parseFormats = this.get( 'parseFormats' ); + const selectConstraint = this.get( 'selectConstraint' ); + + if ( !value ) { + return; + } //console.log( 'from value observer: ', this.get( 'value' ) ); @@ -431,9 +427,23 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa const date = window.moment( value, parseFormats, this.get( 'locale' ), true ); //console.log( 'date entered: ', date.format( format ) ); //return; - if ( date.isValid() ) { - this.set( 'selectedDate', date ); + if ( selectConstraint.start ) { + if ( date.isBefore( selectConstraint.start ) ) { + return; + } + } + + if ( selectConstraint.end ) { + if ( date.isAfter( selectConstraint.end ) ) { + return; + } + } + + if ( !date.isValid() ) { + return; } + + this.set( 'selectedDate', date ); }, parseFormats: Ember.computed( @@ -490,9 +500,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa updateValue() { const date = this.get( 'selectedDate' ); - const format = this.get( 'format' ); - - console.log( 'updateValue', format ); + const format = this.get( 'formatString' ); if ( date === null ) { return; diff --git a/addon/components/sl-date-range-picker.js b/addon/components/sl-date-range-picker.js index f9b47adc..34fb87aa 100755 --- a/addon/components/sl-date-range-picker.js +++ b/addon/components/sl-date-range-picker.js @@ -31,6 +31,22 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { // ------------------------------------------------------------------------- // Events + init() { + this._super( ...arguments ); + + // wish this didn't need to be here.... it's copied from calendar + // currently this needs to exist here as well + const selectConstraint = this.get( 'selectConstraint' ); + + for ( let i in selectConstraint ) { + selectConstraint[ i ] = window.moment( selectConstraint[i] ); + if ( !selectConstraint[ i ].isValid ) { + // throw an error or warning here + } + } + this.set( 'selectConstraint', selectConstraint ); + }, + /** * didInsertElement event hook * @@ -51,10 +67,6 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { //this.unregisterEvents(); },*/ - init() { - this._super( ...arguments ); - }, - // ------------------------------------------------------------------------- // Properties @@ -77,14 +89,14 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { * * @type {?Date|String} */ - maxDate: null, + //maxDate: null, /** * The earliest date selectable in the range * * @type {?Date|String} */ - minDate: null, + //minDate: null, /** * The value for the startDate input @@ -93,23 +105,50 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { */ startDateValue: null, + startDate: null, + + endDate: null, + selectConstraint: { start: null, end: null }, + locale: 'en', + // ------------------------------------------------------------------------- // Observers - fubar: Ember.observer( - 'format', + // ------------------------------------------------------------------------- + // Methods + + endSelectConstraint: Ember.computed( + 'endDate', + 'selectConstraint', function() { - console.log( '(RANGE obs) format: ', this.get( 'format' ) ); + const endDate = this.get( 'endDate' ); + const selectConstraint = this.get( 'selectConstraint' ); + + return { + start: selectConstraint.start, + end: endDate ? endDate : selectConstraint.end + }; } ), - // ------------------------------------------------------------------------- - // Methods + startSelectConstraint: Ember.computed( + 'startDate', + 'selectConstraint', + function() { + const startDate = this.get( 'startDate' ); + const selectConstraint = this.get( 'selectConstraint' ); + + return { + start: startDate ? startDate : selectConstraint.start, + end: selectConstraint.end + }; + } + ), /** * The earliest selectable endDate, based on minDate and diff --git a/addon/templates/components/sl-date-range-picker.hbs b/addon/templates/components/sl-date-range-picker.hbs index 672b435b..3d926587 100755 --- a/addon/templates/components/sl-date-range-picker.hbs +++ b/addon/templates/components/sl-date-range-picker.hbs @@ -5,14 +5,24 @@
{{sl-date-picker class="sl-daterange-start-date col-md-6" - endDate=latestStartDate placeholder=startDatePlaceholder - startDate=minDate value=startDateValue inputId=inputId + format=format + selectConstraint=endSelectConstraint + selectedDate=startDate }} + {{sl-date-picker + class="sl-daterange-end-date col-md-6" + placeholder=endDatePlaceholder + value=endDateValue + + format=format + selectConstraint=startSelectConstraint + selectedDate=endDate + }}
{{#if helpText}} diff --git a/tests/dummy/app/controllers/demos/sl-date-picker.js b/tests/dummy/app/controllers/demos/sl-date-picker.js new file mode 100644 index 00000000..0f488135 --- /dev/null +++ b/tests/dummy/app/controllers/demos/sl-date-picker.js @@ -0,0 +1,16 @@ +import Ember from 'ember'; + +export default Ember.Controller.extend({ + actions: { + logLabel( date, data ) { + window.console.log( 'logLabel: ', date, data ); + } + }, + + selectConstraint: { + start: '01/05/2016', + end: '02/05/2016' + }, + + tempValue: '01/11/2016' +}); diff --git a/tests/dummy/app/controllers/demos/sl-date-range-picker.js b/tests/dummy/app/controllers/demos/sl-date-range-picker.js new file mode 100644 index 00000000..976cd11f --- /dev/null +++ b/tests/dummy/app/controllers/demos/sl-date-range-picker.js @@ -0,0 +1,17 @@ +import Ember from 'ember'; + +export default Ember.Controller.extend({ + actions: { + logLabel( date, data ) { + window.console.log( 'logLabel: ', date, data ); + } + }, + + selectConstraint: { + start: '01/05/2016', + end: '02/05/2016' + }, + + startDate: '01/07/2016', + endDate: '01/28/2016' +}); diff --git a/tests/dummy/app/templates/demos/sl-date-picker.hbs b/tests/dummy/app/templates/demos/sl-date-picker.hbs index fd32c267..47855f79 100755 --- a/tests/dummy/app/templates/demos/sl-date-picker.hbs +++ b/tests/dummy/app/templates/demos/sl-date-picker.hbs @@ -13,7 +13,7 @@
Rendered Component
- {{sl-date-picker label="Date picker"}} + {{sl-date-picker label="Date picker" value=tempValue}}
diff --git a/tests/dummy/app/templates/demos/sl-date-range-picker.hbs b/tests/dummy/app/templates/demos/sl-date-range-picker.hbs index c76707fc..d6a43a32 100755 --- a/tests/dummy/app/templates/demos/sl-date-range-picker.hbs +++ b/tests/dummy/app/templates/demos/sl-date-range-picker.hbs @@ -19,8 +19,11 @@
Rendered Component
{{sl-date-range-picker label="Select date range" + selectConstraint=selectConstraint startDatePlaceholder="Select start date" endDatePlaceholder="Select end date" + startDateValue=startDate + endDateValue=endDate }} From 109a54ec233131f711c79149b923180c3ebf39ef Mon Sep 17 00:00:00 2001 From: J Corley Date: Mon, 25 Jan 2016 16:39:13 -0600 Subject: [PATCH 10/25] Clean up and optimization. Seeded values should now be done via selectedDate properties. selectedDate properties no longer try to parse string. ** CALENDAR ** Moved viewMode to an Enum. Reworked changeDecade action to drop use of showingYear. Rephrased docblocks. Removed commented code blocks. Removed console debug code. Optimized render of days view by adding two observers to update properties on the days themselves instead of rebuilding when selectedDate or viewingDate changed. Added a single function for generating calendar titles for each view. Removed decadeEnd and decadeStart; replacing them with viewingDate. Added tabIndex=-1 to controls. Changed template to use sl-calendar-day block form. ** CALENDAR DAY ** Removed the need for a layout/template by using block format. Moved application of focus to an observer. ** DATE PICKER ** Commented several unused properties. Removed unneeded events. Removed commented code blocks. Changed value property to a computed based on selected. ** DATE RANGE PICKER ** Removed temporary init() event. Removed commented code blocks. Commented out end and start date value properties. --- addon/components/sl-calendar-day.js | 23 +- addon/components/sl-calendar.js | 303 ++++++++---------- addon/components/sl-date-picker.js | 154 ++------- addon/components/sl-date-range-picker.js | 119 +------ addon/templates/components/sl-calendar.hbs | 27 +- .../components/sl-date-range-picker.hbs | 2 - .../app/controllers/demos/sl-date-picker.js | 2 +- .../controllers/demos/sl-date-range-picker.js | 4 +- .../dummy/app/templates/demos/sl-calendar.hbs | 8 - .../app/templates/demos/sl-date-picker.hbs | 2 +- .../templates/demos/sl-date-range-picker.hbs | 4 +- 11 files changed, 198 insertions(+), 450 deletions(-) diff --git a/addon/components/sl-calendar-day.js b/addon/components/sl-calendar-day.js index 2649be59..2b3bb57e 100644 --- a/addon/components/sl-calendar-day.js +++ b/addon/components/sl-calendar-day.js @@ -1,5 +1,5 @@ import Ember from 'ember'; -import layout from '../templates/components/sl-calendar-day'; +//import layout from '../templates/components/sl-calendar-day'; /** * @module @@ -33,7 +33,7 @@ export default Ember.Component.extend({ ], /** @type {Object} */ - layout, + //layout, /** @type {String} */ tagName: 'td', @@ -62,7 +62,7 @@ export default Ember.Component.extend({ didInsertElement() { this._super( ...arguments ); - this.applyFocus(); + this.focus(); }, // ------------------------------------------------------------------------- @@ -110,15 +110,20 @@ export default Ember.Component.extend({ // ------------------------------------------------------------------------- // Observers + focus: Ember.observer( + 'tabIndex', + function() { + if ( this.get( 'focused' ) ) { + Ember.run.scheduleOnce( 'afterRender', this, function() { + this.$().get( 0 ).focus(); + }); + } + } + ), + // ------------------------------------------------------------------------- // Methods - applyFocus() { - if ( this.get( 'focused' ) ) { - this.$().get( 0 ).focus(); - } - }, - ariaSelected: Ember.computed( 'active', function() { diff --git a/addon/components/sl-calendar.js b/addon/components/sl-calendar.js index 2df54a16..c4d51672 100755 --- a/addon/components/sl-calendar.js +++ b/addon/components/sl-calendar.js @@ -1,6 +1,21 @@ import Ember from 'ember'; import layout from '../templates/components/sl-calendar'; +/** + * Valid view types for the sl-calendar component + * + * @memberof module:addon/components/sl-calendar + * @enum {String} + * @property {String} DAYS 'days', + * @property {String} MONTHS 'months', + * @property {String} YEARS 'years' + */ +export const View = Object.freeze({ + DAYS: 'days', + MONTHS: 'months', + YEARS: 'years' +}); + /** * @module * @augments ember/Component @@ -39,82 +54,59 @@ export default Ember.Component.extend({ /** * Change the currently-viewed decade by incrementing or decrementing - * the decadeStart year number + * the viewedDate by ten years at a time * * @function actions:changeDecade - * @param {Number} decadeMod - A number to adjust the decadeStart by + * @param {Number} decadeMod - A number to adjust the viewedDate year by * (positive to increment, negative to decrement) * @returns {undefined} */ changeDecade( decadeMod ) { - if ( this.get( 'locked' ) ) { - return; - } - - this.incrementProperty( 'showingYear', 10 * decadeMod ); + const newYear = this.get( 'viewingDate' ).year() + ( 10 * decadeMod ); + this.setYear( newYear ); }, /** * Change the currently-viewed month by incrementing or decrementing - * the showingMonth (and showingYear if needed) + * the viewedDate by one month at a time * * @function actions:changeMonth - * @param {Number} monthMod - A number to adjust the showingMonth by - * (positive to increment, negative to decrement). The - * showingYear is adjusted as needed. + * @param {Number} monthMod - A number to adjust the viewedDate month by + * (positive to increment, negative to decrement). * @returns {undefined} */ changeMonth( monthMod ) { const newMonth = ( this.get( 'viewingDate' ).month() + 1 ) + monthMod; - this.setMonth( newMonth );/* - if ( this.get( 'locked' ) ) { - return; - } - - const viewingDate = this.get( 'viewingDate' ); - - this.set( 'viewingDate', window.moment( viewingDate ).add( monthMod, 'months' ) );*/ + this.setMonth( newMonth ); }, /** - * Change the currently-viewed year by increment or decrementing the - * showingYear + * Change the currently-viewed year by incrementing or decrementing + * the viewedDate by one year at a time * * @function actions:changeYear - * @param {Number} yearMod - A number to adjust the showingYear by + * @param {Number} yearMod - A number to adjust the viewedDate year by * (positive to increment, negative to decrement) * @returns {undefined} */ changeYear( yearMod ) { const newYear = this.get( 'viewingDate' ).year() + yearMod; - this.setYear( newYear );/* - - if ( this.get( 'locked' ) ) { - return; - } - - const viewingDate = this.get( 'viewingDate' ); - - this.set( 'viewingDate', window.moment( viewingDate ).add( yearMod, 'years' ) );*/ + this.setYear( newYear ); }, /** * Action to trigger component's bound action and pass back content - * values with dates occurring on the clicked date + * associated with the clicked date * - * @function actions:sendDateContent - * @param {Array} dateContent - Collection of content objects with - * date values of the clicked date + * @function actions:selectDate + * @param {Object} date - Moment date object representing the clicked + * date + * @param {Array} data - Collection of content objects with date + * values of the clicked date * @returns {undefined} */ - sendDateContent( dateContent ) { - if ( dateContent ) { - this.sendAction( 'action', dateContent ); - } - }, - selectDate( date, data ) { const isValid = this.setDate( date ); @@ -139,7 +131,7 @@ export default Ember.Component.extend({ * Set the current year and change the view mode to that year * * @function actions:selectYear - * @param {Number} year - The year to set to the current value + * @param {Number} year - The year to change the view to * @returns {undefined} */ selectYear( year ) { @@ -171,14 +163,12 @@ export default Ember.Component.extend({ focusIn() { this._super( ...arguments ); - console.log( 'calendar focus in' ); this.set( 'hasFocus', true ); }, focusOut() { this._super( ...arguments ); - console.log( 'calendar focus out' ); this.set( 'hasFocus', false ); }, @@ -245,7 +235,6 @@ export default Ember.Component.extend({ case 32: // space case 13: // enter - //this.set( 'selectedDate', viewingDate ); this.setDate( viewingDate ); break; @@ -274,24 +263,13 @@ export default Ember.Component.extend({ this.set( 'viewingDate', today ); } - for ( let i in selectConstraint ) { - selectConstraint[ i ] = window.moment( selectConstraint[i] ); - if ( !selectConstraint[ i ].isValid ) { + for ( let constraint in selectConstraint ) { + selectConstraint[ constraint ] = window.moment( selectConstraint[ constraint ] ); + if ( !selectConstraint[ constraint ].isValid ) { // throw an error or warning here } } this.set( 'selectConstraint', selectConstraint ); - console.log( selectConstraint ); -/* - const viewingDate = this.get( 'viewingDate' ); - - if ( !this.get( 'showingMonth' ) ) { - this.set( 'showingMonth', viewingDate.month() + 1 ); - } - - if ( !this.get( 'showingYear' ) ) { - this.set( 'showingYear', viewingDate.year() ); - }*/ }, // ------------------------------------------------------------------------- @@ -304,20 +282,6 @@ export default Ember.Component.extend({ */ content: [], - /** - * The currently selected/viewed month (1-12) - * - * @type {?Number} - */ - //showingMonth: null, - - /** - * The currently selected/viewed year - * - * @type {?Number} - */ - //showingYear: null, - /** * String lookup for the date value on the content objects * @@ -340,43 +304,94 @@ export default Ember.Component.extend({ */ locked: false, + // today: represented by moment object today: null, + // if true, always shows 6 weeks fixedWeekCount: true, + // currently viewed date: represented by moment object viewingDate: null, + // currently selected date: represented by moment object selectedDate: null, + // boolean: whether calendar is focusable for keyboard navigation focusable: true, + // whether or not the calendar currently has focus hasFocus: false, + // constrain selectable dates selectConstraint: { start: null, end: null }, + // the currently shown month + // used as a computed trigger for building list of weeks in month + showingMonth: null, + /** * The current view mode for the calendar * * @type {String} */ - viewMode: 'days', + viewMode: View.DAYS, // ------------------------------------------------------------------------- // Observers - fubar: Ember.observer( + activeDateChange: Ember.observer( + 'selectedDate', + function() { + const selectedDate = this.get( 'selectedDate' ); + const weeksInMonthView = this.get( 'weeksInMonthView' ); + + for ( let week = 0; week < weeksInMonthView.length; week++ ) { + for ( let day = 0; day < weeksInMonthView[ week ].length; day++ ) { + if ( Ember.get( weeksInMonthView[ week ][ day ], 'active' ) ) { + Ember.set( weeksInMonthView[ week ][ day ], 'active', false ) + } + + if ( selectedDate.isSame( Ember.get( weeksInMonthView[ week ][ day ], 'date' ), 'day' ) ) { + Ember.set( weeksInMonthView[ week ][ day ], 'active', true ); + } + } + } + } + ), + + focusedDateChange: Ember.observer( 'viewingDate', function() { - console.log( this.get('viewingDate') ); + const viewingDate = this.get( 'viewingDate' ); + const weeksInMonthView = this.get( 'weeksInMonthView' ); + + for ( let week = 0; week < weeksInMonthView.length; week++ ) { + for ( let day = 0; day < weeksInMonthView[ week ].length; day++ ) { + if ( Ember.get( weeksInMonthView[ week ][ day ], 'focused' ) ) { + Ember.set( weeksInMonthView[ week ][ day ], 'focused', false ) + } + + if ( viewingDate.isSame( Ember.get( weeksInMonthView[ week ][ day ], 'date' ), 'day' ) ) { + Ember.set( weeksInMonthView[ week ][ day ], 'focused', true ); + } + } + } } ), // ------------------------------------------------------------------------- // Methods + updateShowingMonth: Ember.observer( + 'viewingDate', + function() { + this.set( 'showingMonth', this.get( 'viewingDate' ).month() ); + } + ), + setDate( date ) { const selectConstraint = this.get( 'selectConstraint' ); @@ -401,8 +416,6 @@ export default Ember.Component.extend({ return; } - console.log( 'setmonth', month ); - const viewingDate = this.get( 'viewingDate' ); this.set( 'viewingDate', window.moment( viewingDate ).month( month - 1 ) ); @@ -418,20 +431,6 @@ export default Ember.Component.extend({ this.set( 'viewingDate', window.moment( viewingDate ).year( year ) ); }, - showingMonth: Ember.computed( - 'viewingDate', - function() { - return this.get( 'viewingDate' ).month() + 1; - } - ), - - showingYear: Ember.computed( - 'viewingDate', - function() { - return this.get( 'viewingDate' ).year(); - } - ), - tabIndex: Ember.computed( 'focusable', function() { @@ -482,64 +481,35 @@ export default Ember.Component.extend({ ), /** - * Name of the currently selected/viewed month + * Locale and viewMode based string title for the calendar * * @function * @returns {String} */ - showingMonthString: Ember.computed( - 'showingMonth', + calendarTitle: Ember.computed( + 'viewingDate', 'locale', + 'viewMode', function() { - return window.moment([ - 2015, - this.get( 'showingMonth' ) - 1 - ]).locale( this.get( 'locale' ) ).format( 'MMMM' ); - } - ), - - /** - * The number of days in the current month - * - * @function - * @returns {Number} - */ - daysInMonth: Ember.computed( - 'showingMonth', - 'showingYear', - function() { - return window.moment([ - this.get( 'showingYear' ), - this.get( 'showingMonth' ) - 1 - ]).daysInMonth(); - } - ), - - /** - * The last year in the currently selected/viewed decade - * - * @function - * @returns {Number} - */ - decadeEnd: Ember.computed( - 'decadeStart', - function() { - return this.get( 'decadeStart' ) + 9; - } - ), - - /** - * The first year in the currently selected/viewed decade - * - * @function - * @returns {Number} - */ - decadeStart: Ember.computed( - 'showingYear', - function() { - const showingYear = this.get( 'showingYear' ); - - return showingYear - ( showingYear % 10 ); + const viewMode = this.get( 'viewMode' ); + const locale = this.get( 'locale' ); + const viewingDate = this.get( 'viewingDate' ).locale( locale ); + let title = ''; + + switch( viewMode ) { + case View.DAYS: + title = viewingDate.format( 'MMMM YYYY' ); + break; + case View.MONTHS: + title = viewingDate.format( 'YYYY' ); + break; + case View.YEARS: + let decadeMod = viewingDate.year() % 10; + title = viewingDate.subtract( decadeMod, 'years' ).format( 'YYYY' ); + title += ' - ' + viewingDate.add( 9, 'years' ).format( 'YYYY' ); + break; + } + return title; } ), @@ -554,13 +524,15 @@ export default Ember.Component.extend({ * @returns {Object[]} */ monthsInYearView: Ember.computed( - 'showingYear', + 'viewingDate', 'selectedDate', 'locale', function() { - const showingYear = this.get( 'showingYear' ); + const showingYear = this.get( 'viewingDate' ).year(); const selectedDate = this.get( 'selectedDate' ); - const m = window.moment().locale( this.get( 'locale' ) ); + + window.moment().locale( this.get( 'locale' ) ); + const monthNames = window.moment.monthsShort(); const months = Ember.A(); let monthCount = 1; @@ -620,7 +592,7 @@ export default Ember.Component.extend({ viewingDays: Ember.computed( 'viewMode', function() { - return 'days' === this.get( 'viewMode' ); + return View.DAYS === this.get( 'viewMode' ); } ), @@ -633,7 +605,7 @@ export default Ember.Component.extend({ viewingMonths: Ember.computed( 'viewMode', function() { - return 'months' === this.get( 'viewMode' ); + return View.MONTHS === this.get( 'viewMode' ); } ), @@ -646,7 +618,7 @@ export default Ember.Component.extend({ viewingYears: Ember.computed( 'viewMode', function() { - return 'years' === this.get( 'viewMode' ); + return View.YEARS === this.get( 'viewMode' ); } ), @@ -664,23 +636,24 @@ export default Ember.Component.extend({ * @returns {ember.Array} */ weeksInMonthView: Ember.computed( - 'contentDates', + //'contentDates', + //'showingYear', + //'selectedDate', + 'viewingDays', 'showingMonth', - 'showingYear', - 'selectedDate', 'fixedWeekCount', 'locale', - 'viewingDate', 'selectConstraint', function() { const weeks = Ember.A(); - const showingMonth = this.get( 'showingMonth' ); const selectedDate = this.get( 'selectedDate' ); const viewingDate = this.get( 'viewingDate' ); + const showingMonth = viewingDate.month() + 1; + const showingYear = viewingDate.year(); const selectConstraint = this.get( 'selectConstraint' ); - let firstOfMonth = window.moment( '01-' + showingMonth + '-' + this.get( 'showingYear' ), 'DD-MM-YYYY' ).locale( this.get( 'locale' ) ); + let firstOfMonth = window.moment( '01-' + showingMonth + '-' + showingYear, 'DD-MM-YYYY' ).locale( this.get( 'locale' ) ); let firstDayOfWeek = firstOfMonth.localeData().firstDayOfWeek(); let nextDayToShow = window.moment( firstOfMonth ).subtract( firstOfMonth.day(), 'days' ); @@ -703,14 +676,10 @@ export default Ember.Component.extend({ for ( let k = 0; k < 7; k++ ) { let isActive = false; - let inNextMonth = nextDayToShow.isAfter( viewingDate, 'month' );//month() === showingMonth; - let inPrevMonth = nextDayToShow.isBefore( viewingDate, 'month' );//.month() === showingMonth - 2; + let inNextMonth = nextDayToShow.isAfter( viewingDate, 'month' ); + let inPrevMonth = nextDayToShow.isBefore( viewingDate, 'month' ); let isRestricted = false; - /*if ( showingMonth === 1 && nextDayToShow.month() === 11 ) { - inPrevMonth = true; - }*/ - if ( selectedDate ) { isActive = nextDayToShow.isSame( selectedDate, 'day' ); } @@ -729,7 +698,7 @@ export default Ember.Component.extend({ const day = { date: window.moment( nextDayToShow ), - day: nextDayToShow.date(), + dayName: nextDayToShow.date(), old: inPrevMonth, new: inNextMonth, focused: nextDayToShow.isSame( viewingDate, 'day' ) && this.get( 'hasFocus' ), @@ -760,12 +729,12 @@ export default Ember.Component.extend({ * @returns {Object[]} */ yearsInDecadeView: Ember.computed( - 'decadeEnd', - 'decadeStart', + 'viewingDate', 'selectedDate', function() { - const decadeStart = this.get( 'decadeStart' ); - const decadeEnd = this.get( 'decadeEnd' ); + const viewingDate = this.get( 'viewingDate' ); + const decadeStart = viewingDate.year() - ( viewingDate.year() % 10 ); + const decadeEnd = decadeStart + 9; const selectedDate = this.get( 'selectedDate' ); const years = Ember.A(); let yearCount = decadeStart - 1; diff --git a/addon/components/sl-date-picker.js b/addon/components/sl-date-picker.js index 9e685b47..2a232f7d 100755 --- a/addon/components/sl-date-picker.js +++ b/addon/components/sl-date-picker.js @@ -37,7 +37,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa inputBlurred() { this.trigger( 'focusOut' ); - this.updateValue(); + //this.updateValue(); }, inputFocused() { @@ -62,17 +62,6 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa // ------------------------------------------------------------------------- // Events - /** - * didInsertElement event hook - * - * @returns {undefined} - */ - didInsertElement() { - this._super( ...arguments ); - this.setupDatepicker(); - this.checkInput(); - }, - focusIn( event ) { this._super( ...arguments ); @@ -106,19 +95,9 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa this.set( 'losingFocus', runNext ); }, - keyPress() { + /*keyPress() { console.log( 'date picker: keypress' ); - }, - - /** - * willClearRender event hook - * - * @returns {undefined} - */ - willClearRender() { - this._super( ...arguments ); - //this.unregisterEvents(); - }, + },*/ // ------------------------------------------------------------------------- // Properties @@ -129,14 +108,14 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @type {Boolean} */ - autoclose: true, + //autoclose: true, /** * Whether or not to show week numbers to the left of week rows * * @type {Boolean} */ - calendarWeeks: false, + //calendarWeeks: false, /** * When true, displays a "Clear" button at the bottom of the datepicker @@ -146,7 +125,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @type {Boolean} */ - clearBtn: false, + //clearBtn: false, /** * Days of the week that should be disabled @@ -219,14 +198,14 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @type {?Array} */ - inputs: null, + //inputs: null, /** * Whether or not to allow date navigation by arrow keys * * @type {Boolean} */ - keyboardNavigation: true, + //keyboardNavigation: true, /** * The label text above the datepicker's input field @@ -240,14 +219,14 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @type {String} */ - language: 'en', + //language: 'en', /** * Set a limit for the view mode; accepts "days", "months", or "years" * * @type {String} */ - minViewMode: 'days', + //minViewMode: 'days', /** * Enable multidate picking @@ -261,7 +240,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @type {Boolean|Number} */ - multidate: false, + //multidate: false, /** * A space-separated string for the popup's anchor position @@ -271,7 +250,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @type {String} */ - orientation: 'auto', + //orientation: 'auto', /** * The placeholder text that the datepicker should show @@ -319,7 +298,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @type {?String} */ - value: null, + //value: null, /** * Day of the week to start on; 0 (Sunday) to 6 (Saturday) @@ -344,75 +323,12 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa // ------------------------------------------------------------------------- // Observers - // close calendar and set value with formatting - dateSelected: Ember.observer( - 'selectedDate', - function() { - this.updateValue(); - //this.$( '> input' ).focus(); - //this.set( 'hasFocus', false ); - } - ), - - /** - * Datepicker plugin options - * - * @function - * @returns {Object} - */ - options: Ember.computed( - function() { - return { - /*autoclose: this.get( 'autoclose' ), - calendarWeeks: this.get( 'calendarWeeks' ), - clearBtn: this.get( 'clearBtn' ), - daysOfWeekDisabled: this.get( 'daysOfWeekDisabled' ), - endDate: this.get( 'endDate' ), - forceParse: this.get( 'forceParse' ), - format: this.get( 'format' ), - inputs: this.get( 'inputs' ), - keyboardNavigation: this.get( 'keyboardNavigation' ), - language: this.get( 'language' ), - minViewMode: this.get( 'minViewMode' ), - multidate: this.get( 'multidate' ), - orientation: this.get( 'orientation' ), - startDate: this.get( 'startDate' ), - startView: this.get( 'startView' ), - todayBtn: this.get( 'todayBtn' ), - todayHighlight: this.get( 'todayHighlight' ), - weekStart: this.get( 'weekStart' )*/ - }; - } - ), - - /** - * Dynamically update the startDate and endDate values for the datepicker - * - * @function - * @returns {undefined} - */ - updateDateRange: Ember.observer( - 'endDate', - 'startDate', - function() { - /*const input = this.$( 'input.date-picker' ); - const datepicker = input.data( 'datepicker' ); - - datepicker.setStartDate( this.get( 'startDate' ) ); - datepicker.setEndDate( this.get( 'endDate' ) ); - - if ( 'Invalid Date' === datepicker.getDate().toString() ) { - input.val( '' ); - }*/ - } - ), - // ------------------------------------------------------------------------- // Methods checkInput() { let value = this.get( 'value' ); - const format = this.get( 'format' ); + //const format = this.get( 'format' ); const parseFormats = this.get( 'parseFormats' ); const selectConstraint = this.get( 'selectConstraint' ); @@ -473,39 +389,19 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa this.set( 'selectedDate', date ); }, - /** - * Setup the bootstrap-datepicker plugin and events - * - * @private - * @returns {undefined} - */ - setupDatepicker() { - /*const datepicker = this.$( 'input.date-picker' ) - .datepicker( this.get( 'options' ) ); - - datepicker.on( this.namespaceEvent( 'changeDate' ), () => { - this.sendAction(); - });*/ - }, - - /** - * Remove events - * - * @private - * @returns {undefined} - */ - unregisterEvents() { - //this.$( 'input.date-picker' ).off( this.namespaceEvent( 'changeDate' ) ); - }, + value: Ember.computed( + 'selectedDate', + 'formatString', + function() { + const selectedDate = this.get( 'selectedDate' ); + const format = this.get( 'formatString' ); - updateValue() { - const date = this.get( 'selectedDate' ); - const format = this.get( 'formatString' ); + if ( selectedDate === null ) { + return; + } - if ( date === null ) { - return; + return selectedDate.format( format ); } + ) - this.set( 'value', date.format( format ) ); - } }); diff --git a/addon/components/sl-date-range-picker.js b/addon/components/sl-date-range-picker.js index 34fb87aa..ca42027c 100755 --- a/addon/components/sl-date-range-picker.js +++ b/addon/components/sl-date-range-picker.js @@ -31,42 +31,6 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { // ------------------------------------------------------------------------- // Events - init() { - this._super( ...arguments ); - - // wish this didn't need to be here.... it's copied from calendar - // currently this needs to exist here as well - const selectConstraint = this.get( 'selectConstraint' ); - - for ( let i in selectConstraint ) { - selectConstraint[ i ] = window.moment( selectConstraint[i] ); - if ( !selectConstraint[ i ].isValid ) { - // throw an error or warning here - } - } - this.set( 'selectConstraint', selectConstraint ); - }, - - /** - * didInsertElement event hook - * - * @returns {undefined} - */ - /* didInsertElement() { - this._super( ...arguments ); - //this.setupFocusTransition(); - },*/ - - /** - * willClearRender event hook - * - * @returns {undefined} - */ - /*willClearRender() { - this._super( ...arguments ); - //this.unregisterEvents(); - },*/ - // ------------------------------------------------------------------------- // Properties @@ -75,7 +39,7 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { * * @type {?String} */ - endDateValue: null, + //endDateValue: null, /** * The string format for date values @@ -103,7 +67,7 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { * * @type {?String} */ - startDateValue: null, + //startDateValue: null, startDate: null, @@ -148,83 +112,6 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { end: selectConstraint.end }; } - ), - - /** - * The earliest selectable endDate, based on minDate and - * current startDateValue - * - * @function - * @returns {?Date|String} Defaults to null - */ - earliestEndDate: Ember.computed( - 'minDate', - 'startDateValue', - function() { - /*const minDate = this.get( 'minDate' ); - const startDateValue = this.get( 'startDateValue' ); - - if ( startDateValue ) { - return startDateValue; - } - - if ( minDate ) { - return minDate; - } - - return null;*/ - } - ), - - /** - * The latest selectable startDate, based on maxDate and - * current endDateValue - * - * @function - * @returns {Date|String} Defaults to null - */ - latestStartDate: Ember.computed( - 'endDateValue', - 'maxDate', - function() { - /*const endDateValue = this.get( 'endDateValue' ); - const maxDate = this.get( 'maxDate' ); - - if ( endDateValue ) { - return endDateValue; - } - - if ( maxDate ) { - return maxDate; - } - - return null;*/ - } - ), - - /** - * Set up a transition that moves focus to the endDate input when the - * startDate input is changed - * - * @private - * @returns {undefined} - */ - setupFocusTransition() { - /*this.set( 'startDateInput', this.$( '.sl-daterange-start-date input' ) ); - this.set( 'endDateInput', this.$( '.sl-daterange-end-date input' ) ); - this.get( 'startDateInput' ).on( this.namespaceEvent( 'changeDate' ), () => { - this.get( 'endDateInput' ).trigger( 'focus' ); - });*/ - }, - - /** - * Remove events - * - * @private - * @returns {undefined} - */ - unregisterEvents() { - //this.get( 'startDateInput' ).off( this.namespaceEvent( 'changeDate' ) ); - } + ) }); diff --git a/addon/templates/components/sl-calendar.hbs b/addon/templates/components/sl-calendar.hbs index 8d636caf..5714b53e 100644 --- a/addon/templates/components/sl-calendar.hbs +++ b/addon/templates/components/sl-calendar.hbs @@ -4,17 +4,17 @@ @@ -33,17 +33,18 @@ {{#each weeksInMonthView as |weekDays|}} {{#each weekDays as |day|}} - {{sl-calendar-day + {{#sl-calendar-day action="selectDate" active=day.active content=day.content - day=day.day new=day.new old=day.old date=day.date focused=day.focused restricted=day.restricted }} + {{day.dayName}} + {{/sl-calendar-day}} {{/each}} {{/each}} @@ -58,17 +59,17 @@
- - - {{showingMonthString}} {{showingYear}} + + {{calendarTitle}} -
@@ -102,17 +103,17 @@
- - - {{showingYear}} + + {{calendarTitle}} -
diff --git a/addon/templates/components/sl-date-range-picker.hbs b/addon/templates/components/sl-date-range-picker.hbs index 3d926587..d02d15e4 100755 --- a/addon/templates/components/sl-date-range-picker.hbs +++ b/addon/templates/components/sl-date-range-picker.hbs @@ -6,7 +6,6 @@ {{sl-date-picker class="sl-daterange-start-date col-md-6" placeholder=startDatePlaceholder - value=startDateValue inputId=inputId format=format @@ -17,7 +16,6 @@ {{sl-date-picker class="sl-daterange-end-date col-md-6" placeholder=endDatePlaceholder - value=endDateValue format=format selectConstraint=startSelectConstraint diff --git a/tests/dummy/app/controllers/demos/sl-date-picker.js b/tests/dummy/app/controllers/demos/sl-date-picker.js index 0f488135..86564ec0 100644 --- a/tests/dummy/app/controllers/demos/sl-date-picker.js +++ b/tests/dummy/app/controllers/demos/sl-date-picker.js @@ -12,5 +12,5 @@ export default Ember.Controller.extend({ end: '02/05/2016' }, - tempValue: '01/11/2016' + selectedDate: window.moment( '01/11/2016', 'MM/DD/YYYY' ) }); diff --git a/tests/dummy/app/controllers/demos/sl-date-range-picker.js b/tests/dummy/app/controllers/demos/sl-date-range-picker.js index 976cd11f..d8767acc 100644 --- a/tests/dummy/app/controllers/demos/sl-date-range-picker.js +++ b/tests/dummy/app/controllers/demos/sl-date-range-picker.js @@ -12,6 +12,6 @@ export default Ember.Controller.extend({ end: '02/05/2016' }, - startDate: '01/07/2016', - endDate: '01/28/2016' + startDate: window.moment( '01/07/2016', 'MM/DD/YYYY' ), + endDate: window.moment( '01/28/2016', 'MM/DD/YYYY' ) }); diff --git a/tests/dummy/app/templates/demos/sl-calendar.hbs b/tests/dummy/app/templates/demos/sl-calendar.hbs index cc5d7f41..f7c807a0 100755 --- a/tests/dummy/app/templates/demos/sl-calendar.hbs +++ b/tests/dummy/app/templates/demos/sl-calendar.hbs @@ -38,14 +38,6 @@ Bound array of objects with date values, looked up using the dateValuePath property. {{/property-text}} - {{#property-text name="currentMonth" type="Number" default="current month"}} - The month number to display (1-12). - {{/property-text}} - - {{#property-text name="currentYear" type="Number" default="current year"}} - The year to display. - {{/property-text}} - {{#property-text name="dateValuePath" type="String" default="\"date\""}} Path to the content objects' date value. {{/property-text}} diff --git a/tests/dummy/app/templates/demos/sl-date-picker.hbs b/tests/dummy/app/templates/demos/sl-date-picker.hbs index 47855f79..68ba97d0 100755 --- a/tests/dummy/app/templates/demos/sl-date-picker.hbs +++ b/tests/dummy/app/templates/demos/sl-date-picker.hbs @@ -13,7 +13,7 @@
Rendered Component
- {{sl-date-picker label="Date picker" value=tempValue}} + {{sl-date-picker label="Date picker" selectedDate=selectedDate}}
diff --git a/tests/dummy/app/templates/demos/sl-date-range-picker.hbs b/tests/dummy/app/templates/demos/sl-date-range-picker.hbs index d6a43a32..c702f8ea 100755 --- a/tests/dummy/app/templates/demos/sl-date-range-picker.hbs +++ b/tests/dummy/app/templates/demos/sl-date-range-picker.hbs @@ -22,8 +22,8 @@ selectConstraint=selectConstraint startDatePlaceholder="Select start date" endDatePlaceholder="Select end date" - startDateValue=startDate - endDateValue=endDate + startDate=startDate + endDate=endDate }} From c3e362dc01a38ee7d5111f7be6ab6bc49ce9293a Mon Sep 17 00:00:00 2001 From: J Corley Date: Tue, 26 Jan 2016 16:09:03 -0600 Subject: [PATCH 11/25] First pass at test cleanup. ** CALENDAR ** Reorganized file to conform with alphabetic order. Changed "controls" class to "calendar-controls". Changed "datepicker-days" class to "calendar-days" for each viewMode. ** CALENDAR YEAR ** Added "year" class name. --- addon/components/sl-calendar-year.js | 5 + addon/components/sl-calendar.js | 119 +-- addon/templates/components/sl-calendar.hbs | 29 +- app/styles/sl-calendar.less | 6 +- .../components/sl-calendar-test.js | 688 ++++++------------ tests/unit/components/sl-calendar-day-test.js | 18 +- .../unit/components/sl-calendar-month-test.js | 43 +- tests/unit/components/sl-calendar-test.js | 254 ++++--- 8 files changed, 460 insertions(+), 702 deletions(-) diff --git a/addon/components/sl-calendar-year.js b/addon/components/sl-calendar-year.js index d429f720..1492ff18 100644 --- a/addon/components/sl-calendar-year.js +++ b/addon/components/sl-calendar-year.js @@ -20,6 +20,11 @@ export default Ember.Component.extend({ 'old' ], + /** @type {String[]} */ + classNames: [ + 'year' + ], + /** @type {Object} */ layout, diff --git a/addon/components/sl-calendar.js b/addon/components/sl-calendar.js index c4d51672..95e62565 100755 --- a/addon/components/sl-calendar.js +++ b/addon/components/sl-calendar.js @@ -289,6 +289,15 @@ export default Ember.Component.extend({ */ dateValuePath: 'date', + // if true, always shows 6 weeks + fixedWeekCount: true, + + // boolean: whether calendar is focusable for keyboard navigation + focusable: true, + + // whether or not the calendar currently has focus + hasFocus: false, + /** * The locale string to use for moment date values * @@ -304,34 +313,25 @@ export default Ember.Component.extend({ */ locked: false, - // today: represented by moment object - today: null, - - // if true, always shows 6 weeks - fixedWeekCount: true, - - // currently viewed date: represented by moment object - viewingDate: null, - - // currently selected date: represented by moment object - selectedDate: null, - - // boolean: whether calendar is focusable for keyboard navigation - focusable: true, - - // whether or not the calendar currently has focus - hasFocus: false, - // constrain selectable dates selectConstraint: { start: null, end: null }, + // currently selected date: represented by moment object + selectedDate: null, + // the currently shown month // used as a computed trigger for building list of weeks in month showingMonth: null, + // today: represented by moment object + today: null, + + // currently viewed date: represented by moment object + viewingDate: null, + /** * The current view mode for the calendar * @@ -382,9 +382,6 @@ export default Ember.Component.extend({ } ), - // ------------------------------------------------------------------------- - // Methods - updateShowingMonth: Ember.observer( 'viewingDate', function() { @@ -392,6 +389,9 @@ export default Ember.Component.extend({ } ), + // ------------------------------------------------------------------------- + // Methods + setDate( date ) { const selectConstraint = this.get( 'selectConstraint' ); @@ -409,6 +409,7 @@ export default Ember.Component.extend({ this.set( 'selectedDate', window.moment( date ) ); this.set( 'viewingDate', window.moment( date ) ); + return true; }, setMonth( month ) { @@ -431,10 +432,36 @@ export default Ember.Component.extend({ this.set( 'viewingDate', window.moment( viewingDate ).year( year ) ); }, - tabIndex: Ember.computed( - 'focusable', + /** + * Locale and viewMode based string title for the calendar + * + * @function + * @returns {String} + */ + calendarTitle: Ember.computed( + 'viewingDate', + 'locale', + 'viewMode', function() { - return this.get( 'focusable' ) ? 0 : -1; + const viewMode = this.get( 'viewMode' ); + const locale = this.get( 'locale' ); + const viewingDate = this.get( 'viewingDate' ).locale( locale ); + let title = ''; + + switch( viewMode ) { + case View.DAYS: + title = viewingDate.format( 'MMMM YYYY' ); + break; + case View.MONTHS: + title = viewingDate.format( 'YYYY' ); + break; + case View.YEARS: + let decadeMod = viewingDate.year() % 10; + title = viewingDate.subtract( decadeMod, 'years' ).format( 'YYYY' ); + title += ' - ' + viewingDate.add( 9, 'years' ).format( 'YYYY' ); + break; + } + return title; } ), @@ -480,39 +507,6 @@ export default Ember.Component.extend({ } ), - /** - * Locale and viewMode based string title for the calendar - * - * @function - * @returns {String} - */ - calendarTitle: Ember.computed( - 'viewingDate', - 'locale', - 'viewMode', - function() { - const viewMode = this.get( 'viewMode' ); - const locale = this.get( 'locale' ); - const viewingDate = this.get( 'viewingDate' ).locale( locale ); - let title = ''; - - switch( viewMode ) { - case View.DAYS: - title = viewingDate.format( 'MMMM YYYY' ); - break; - case View.MONTHS: - title = viewingDate.format( 'YYYY' ); - break; - case View.YEARS: - let decadeMod = viewingDate.year() % 10; - title = viewingDate.subtract( decadeMod, 'years' ).format( 'YYYY' ); - title += ' - ' + viewingDate.add( 9, 'years' ).format( 'YYYY' ); - break; - } - return title; - } - ), - /** * Get an array of objects representing months in the year view * @@ -583,6 +577,13 @@ export default Ember.Component.extend({ } ), + tabIndex: Ember.computed( + 'focusable', + function() { + return this.get( 'focusable' ) ? 0 : -1; + } + ), + /** * Whether the current view is "days" * @@ -639,11 +640,11 @@ export default Ember.Component.extend({ //'contentDates', //'showingYear', //'selectedDate', - 'viewingDays', - 'showingMonth', 'fixedWeekCount', 'locale', 'selectConstraint', + 'showingMonth', + 'viewingDays', function() { const weeks = Ember.A(); diff --git a/addon/templates/components/sl-calendar.hbs b/addon/templates/components/sl-calendar.hbs index 5714b53e..1ae5d27e 100644 --- a/addon/templates/components/sl-calendar.hbs +++ b/addon/templates/components/sl-calendar.hbs @@ -1,7 +1,7 @@ -{{#if viewingDays}} -
+
-
- - {{decadeStart}}-{{decadeEnd}} + {{calendarTitle}} -
+ {{#if viewingDays}} +
- -{{/if}} + {{/if}} -{{#if viewingMonths}} -
- - + {{#if viewingMonths}} +
-
-{{/if}} - -{{#if viewingYears}} -
+ {{/if}} - + {{#if viewingYears}} +
-
-{{/if}} + {{/if}} + + diff --git a/app/styles/sl-calendar.less b/app/styles/sl-calendar.less index 8d0d8590..cde2c909 100644 --- a/app/styles/sl-calendar.less +++ b/app/styles/sl-calendar.less @@ -13,7 +13,7 @@ display: inline-block; - table.controls { + table.calendar-controls { width: 100%; margin-bottom: @table-condensed-cell-padding; @@ -86,11 +86,11 @@ } -.datepicker-days td { +.calendar-days td { width: 2.2em; height: 2.2em; } -.datepicker-months td, .datepicker-years td { +.calendar-months td, .calendar-years td { width: 3.875em; height: 4.25em; } diff --git a/tests/integration/components/sl-calendar-test.js b/tests/integration/components/sl-calendar-test.js index 83b8344d..f53faf77 100755 --- a/tests/integration/components/sl-calendar-test.js +++ b/tests/integration/components/sl-calendar-test.js @@ -50,18 +50,13 @@ test( 'Default rendered state', function( assert ) { ); assert.ok( - this.$( '>:first-child' ).find( '> div:first-child' ).hasClass( 'datepicker' ), - 'First child of component has class "datepicker"' + this.$( '>:first-child' ).find( '> div:first-child' ).hasClass( 'calendar-days' ), + 'First child of component has class "calendar-days"' ); assert.ok( - this.$( '>:first-child' ).find( '> div:first-child' ).hasClass( 'datepicker-inline' ), - 'First child of component has class "datepicker-inline"' - ); - - assert.ok( - this.$( '>:first-child' ).find( '> .datepicker > div:first-child' ).hasClass( 'datepicker-days' ), - 'Day view is visible' + this.$( '>:first-child' ).find( '.calendar-days > table:first-child' ).hasClass( 'calendar-controls' ), + 'Controls are visible' ); }); @@ -70,49 +65,97 @@ test( 'Next and Previous buttons have appropriate classes', function( assert ) { {{sl-calendar}} ` ); + const hasButtonClasses = function( button ) { + let hasClasses = true; + + if ( !button.hasClass( 'btn' ) ) { + hasClasses = false; + } + + if ( !button.hasClass( 'btn-xs' ) ) { + hasClasses = false; + } + + if ( !button.hasClass( 'btn-default' ) ) { + hasClasses = false; + } + + return hasClasses; + }; + + assert.ok( + hasButtonClasses( this.$( '.calendar-controls button' ).first() ), + 'day view previous button has "btn", "btn-xs", and "btn-default" classes' + ); + + assert.ok( + this.$( '.calendar-controls button' ).first().find( 'span' ).hasClass( 'sl-icon-previous' ), + 'day view previous button has span with "sl-icon-previous" class' + ); + assert.ok( - this.$( '.table-condensed > thead > tr > th:first-child span' ).hasClass( 'sl-icon-previous' ), - 'day view has previous button class' + hasButtonClasses( this.$( '.calendar-controls button' ).last() ), + 'day view next button has "btn", "btn-xs", and "btn-default" classes' ); assert.ok( - this.$( '.table-condensed > thead > tr > th:last-child span' ).hasClass( 'sl-icon-next' ), - 'day view has next button class' + this.$( '.calendar-controls button' ).last().find( 'span' ).hasClass( 'sl-icon-next' ), + 'day view previous button has span with "sl-icon-next" class' ); - this.$( '.datepicker-switch' ).click(); + this.$( '.calendar-controls a' ).click(); + + assert.ok( + hasButtonClasses( this.$( '.calendar-controls button' ).first() ), + 'month view previous button has "btn", "btn-xs", and "btn-default" classes' + ); + + assert.ok( + this.$( '.calendar-controls button' ).first().find( 'span' ).hasClass( 'sl-icon-previous' ), + 'month view previous button has span with "sl-icon-previous" class' + ); + + assert.ok( + hasButtonClasses( this.$( '.calendar-controls button' ).last() ), + 'month view next button has "btn", "btn-xs", and "btn-default" classes' + ); assert.ok( - this.$( '.table-condensed > thead > tr > th:first-child span' ).hasClass( 'sl-icon-previous' ), - 'month view has previous button class' + this.$( '.calendar-controls button' ).last().find( 'span' ).hasClass( 'sl-icon-next' ), + 'month view previous button has span with "sl-icon-next" class' ); + this.$( '.calendar-controls a' ).click(); + assert.ok( - this.$( '.table-condensed > thead > tr > th:last-child span' ).hasClass( 'sl-icon-next' ), - 'month view has next button class' + hasButtonClasses( this.$( '.calendar-controls button' ).first() ), + 'year view previous button has "btn", "btn-xs", and "btn-default" classes' ); - this.$( '.datepicker-switch' ).click(); + assert.ok( + this.$( '.calendar-controls button' ).first().find( 'span' ).hasClass( 'sl-icon-previous' ), + 'year view previous button has span with "sl-icon-previous" class' + ); assert.ok( - this.$( '.table-condensed > thead > tr > th:first-child span' ).hasClass( 'sl-icon-previous' ), - 'year view has previous button class' + hasButtonClasses( this.$( '.calendar-controls button' ).last() ), + 'year view next button has "btn", "btn-xs", and "btn-default" classes' ); assert.ok( - this.$( '.table-condensed > thead > tr > th:last-child span' ).hasClass( 'sl-icon-next' ), - 'year view has next button class' + this.$( '.calendar-controls button' ).last().find( 'span' ).hasClass( 'sl-icon-next' ), + 'year view previous button has span with "sl-icon-next" class' ); }); test( 'Check for classes set on items outside of range in picker', function( assert ) { - this.set( 'currentYear', 2015 ); - this.set( 'currentMonth', 1 ); + this.set( 'viewingDate', window.moment( [2015, 1, 1] ) ); + this.set( 'viewMode', 'days' ); this.render( hbs` {{sl-calendar - currentYear=currentYear - currentMonth=currentMonth + viewingDate=viewingDate + viewMode=viewMode }} ` ); @@ -121,7 +164,7 @@ test( 'Check for classes set on items outside of range in picker', function( ass // test the days - const days = this.$( '>:first-child' ).find( '.datepicker-days .day' ); + const days = this.$( '>:first-child' ).find( '.calendar-days .day' ); let firstReached = false; let lastReached = false; @@ -162,11 +205,12 @@ test( 'Check for classes set on items outside of range in picker', function( ass // test the years - this.$( '>:first-child' ).find( '.datepicker-switch' ).trigger( 'click' ); // open month picker - this.$( '>:first-child' ).find( '.datepicker-switch' ).trigger( 'click' ); // open year picker - const yearSpan = this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim().split( '-' ); + this.set( 'viewMode', 'years' ); + + const startYear = 2010; + const endYear = 2019; - const years = this.$( '>:first-child' ).find( '.datepicker-years > table > tbody > tr > td > *' ); + const years = this.$( '>:first-child' ).find( 'td.year' ); missingOld = false; missingNew = false; @@ -174,13 +218,13 @@ test( 'Check for classes set on items outside of range in picker', function( ass years.each( function() { const testYear = parseInt( $( this ).text() ); - if ( testYear > parseInt( yearSpan[1] ) ) { + if ( testYear > endYear ) { if ( !$( this ).hasClass( 'new' ) ) { missingNew = true; } } - if ( testYear < parseInt( yearSpan[0] ) ) { + if ( testYear < startYear ) { if ( !$( this ).hasClass( 'old' ) ) { missingOld = true; } @@ -198,23 +242,16 @@ test( 'Check for classes set on items outside of range in picker', function( ass ); }); -test( 'Setting currentYear and currentMonth modifies the view correctly', function( assert ) { - - const currentYear = 2025; - this.set( 'currentYear', currentYear ); - - this.set( 'currentMonth', 1 ); +test( 'Setting viewingDate modifies the view correctly', function( assert ) { + this.set( 'viewingDate', window.moment( [2025, 3, 1] ) ); this.render( hbs` - {{sl-calendar - currentYear=currentYear - currentMonth=currentMonth - }} + {{sl-calendar viewingDate=viewingDate}} ` ); assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - 'January ' + currentYear, + this.$( '>:first-child' ).find( '.calendar-controls a' ).text().trim(), + 'April 2025', 'Current month and year are set correctly in the view' ); }); @@ -250,114 +287,59 @@ skip( 'Setting dateValuePath modifies the view correctly', function( assert ) { ); }); -skip( 'Active day is set correctly', function( assert ) { - - this.set( 'currentYear', 2022 ); - - this.set( 'currentMonth', 9 ); - - this.set( 'content', Ember.A() ); +test( 'selectedDate is set correctly', function( assert ) { + this.set( 'selectedDate', window.moment( [2015, 1, 15] ) ); + this.set( 'viewingDate', window.moment( [2015, 1, 1] ) ); this.render( hbs` {{sl-calendar - content=content + viewingDate=viewingDate }} ` ); - assert.strictEqual( - this.$( '>:first-child' ).find( '.active' ).text().trim(), - '', - 'No active day is set' - ); - - this.set( 'content', testContent ); - - this.render( hbs` - {{sl-calendar - content=content - currentYear=currentYear - currentMonth=currentMonth - }} - ` ); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.active' ).text().trim(), - 17, - 'Active day is set correctly' + assert.notOk( + this.$( '>:first-child' ).find( 'td.selected' ).length, + 'No days are set as selected' ); - this.set( 'content', multipleTestContent ); - this.render( hbs` {{sl-calendar - content=content - currentYear=currentYear - currentMonth=currentMonth + viewingDate=viewingDate + selectedDate=selectedDate }} ` ); - const active = this.$( '>:first-child' ).find( '.active' ); - - assert.strictEqual( - active.length, - 2, - 'There are two unique dates assigned the .active class' - ); - - assert.strictEqual( - active[ 0 ].innerHTML, - '17', - 'First unique date instance is correct' - ); - assert.strictEqual( - active[ 1 ].innerHTML, - '20', - 'Second unique date instance is correct' + this.$( '>:first-child' ).find( 'td.selected' ).text().trim(), + "15", + 'Proper date is set as selected' ); }); test( 'Setting locale to Spanish modifies the view correctly', function( assert ) { - - const currentYear = 2022; - this.set( 'currentYear', currentYear ); - - this.set( 'currentMonth', 9 ); + this.set( 'viewingDate', window.moment( [2022, 8, 1] ) ); this.render( hbs` {{sl-calendar locale="es" - currentYear=currentYear - currentMonth=currentMonth + viewingDate=viewingDate }} ` ); assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - 'Septiembre ' + currentYear, + this.$( '>:first-child' ).find( '.calendar-controls a' ).text().trim(), + 'Septiembre 2022', 'Current month in Spanish is set correctly in the view' ); }); test( 'Action fires when day is clicked', function( assert ) { - assert.expect( 1 ); const done = assert.async(); - this.set( 'currentYear', 2022 ); - - this.set( 'currentMonth', 9 ); - - this.set( 'content', testContent ); - this.render( hbs` - {{sl-calendar - action="testAction" - content=content - currentYear=currentYear - currentMonth=currentMonth - }} + {{sl-calendar action="testAction"}} ` ); this.on( 'testAction', () => { @@ -369,7 +351,7 @@ test( 'Action fires when day is clicked', function( assert ) { done(); }); - this.$( '>:first-child' ).find( '.active' ).click(); + this.$( '>:first-child' ).find( '.today' ).click(); }); skip( 'Action passes through expected objects in content array', function( assert ) { @@ -453,278 +435,167 @@ skip( 'Action passes through expected objects in content array', function( asser this.$( '>:first-child' ).find( '.active' ).click(); }); -skip( 'Setting viewMode modifies the view correctly', function( assert ) { - - const currentYear = 2022; - this.set( 'currentYear', currentYear ); - - this.set( 'currentMonth', 9 ); - - this.set( 'content', testContent ); +test( 'Setting viewMode modifies the view correctly', function( assert ) { + this.set( 'selectedDate', window.moment( [2015, 1, 15] ) ); + this.set( 'viewingDate', window.moment( [2015, 1, 1] ) ); + this.set( 'viewMode', 'days' ); this.render( hbs` {{sl-calendar - content=content + selectedDate=selectedDate + viewingDate=viewingDate + viewMode=viewMode }} ` ); - assert.ok( - this.$( '>:first-child' ), + assert.strictEqual( + this.$( '>:first-child' ).find( '.selected' ).text().trim(), + "15", '"viewMode" of days renders' ); - this.render( hbs` - {{sl-calendar - content=content - viewMode="months" - }} - ` ); + this.set( 'viewMode', 'months' ); - assert.ok( - this.$( '>:first-child' ), + assert.strictEqual( + this.$( '>:first-child' ).find( '.selected' ).text().trim(), + "Feb", '"viewMode" of months renders' ); - this.render( hbs` - {{sl-calendar - content=content - viewMode="years" - }} - ` ); - - assert.ok( - this.$( '>:first-child' ), - '"viewMode" of years renders' - ); - - this.render( hbs` - {{sl-calendar - content=content - currentYear=currentYear - currentMonth=currentMonth - }} - ` ); + this.set( 'viewMode', 'years' ); assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - 'September ' + currentYear, - 'The current month and year are set correctly' + this.$( '>:first-child' ).find( '.selected' ).text().trim(), + "2015", + '"viewMode" of years renders' ); +}); - assert.strictEqual( - this.$( '>:first-child' ).find( '.active' ).text().trim(), - 17, - 'The current day is set correctly' - ); +test( 'Navigating Forward and Backward by Month', function( assert ) { + this.set( 'viewingDate', window.moment( [2015, 8, 1] ) ); this.render( hbs` {{sl-calendar - content=content - viewMode="months" - currentYear=currentYear - currentMonth=currentMonth + viewingDate=viewingDate }} ` ); assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - currentYear.toString(), - 'The current year is set correctly' - ); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.active' ).text().trim(), - 'Sep', + this.$( '>:first-child' ).find( '.calendar-controls a' ).text().trim(), + 'September 2015', 'The current month is set correctly' ); - this.render( hbs` - {{sl-calendar - content=content - viewMode="years" - currentYear=currentYear - currentMonth=currentMonth - }} - ` ); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - '2020-2029', - 'The year range is set correctly' - ); + this.$( '>:first-child' ).find( '.sl-icon-next' ).trigger( 'click' ); assert.strictEqual( - this.$( '>:first-child' ).find( '.active' ).text().trim(), - currentYear.toString(), - 'The current year is set correctly' + this.$( '>:first-child' ).find( '.calendar-controls a' ).text().trim(), + 'October 2015', + 'The next month is set correctly' ); -}); -test( 'Navigating Forward by Month', function( assert ) { - - const currentYear = 2022; - this.set( 'currentYear', currentYear ); - - this.set( 'currentMonth', 9 ); - - this.render( hbs` - {{sl-calendar - currentYear=currentYear - currentMonth=currentMonth - }} - ` ); + this.$( '>:first-child' ).find( '.sl-icon-previous' ).trigger( 'click' ).trigger( 'click' ); assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - 'September ' + currentYear, - 'The current month is set correctly' + this.$( '>:first-child' ).find( '.calendar-controls a' ).text().trim(), + 'August 2015', + 'The previous month is set correctly' ); - this.$( '>:first-child' ).find( '.sl-icon-next' ).click(); + this.set( 'viewingDate', window.moment( [2015, 11, 1] ) ); assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - 'October ' + currentYear, - 'The next month is set correctly' + this.$( '>:first-child' ).find( '.calendar-controls a' ).text().trim(), + 'December 2015', + 'The month is set correctly' ); -}); -test( 'Navigating Backward by Month', function( assert ) { - - const currentYear = 2022; - this.set( 'currentYear', currentYear ); - - this.set( 'currentMonth', 9 ); - - this.render( hbs` - {{sl-calendar - currentYear=currentYear - currentMonth=currentMonth - }} - ` ); + this.$( '>:first-child' ).find( '.sl-icon-next' ).trigger( 'click' ); assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - 'September ' + currentYear, - 'The current month is set correctly' + this.$( '>:first-child' ).find( '.calendar-controls a' ).text().trim(), + 'January 2016', + 'The month and year are set correctly' ); - this.$( '>:first-child' ).find( '.sl-icon-previous' ).click(); + this.$( '>:first-child' ).find( '.sl-icon-previous' ).trigger( 'click' ); assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - 'August ' + currentYear, - 'The previous month is set correctly' + this.$( '>:first-child' ).find( '.calendar-controls a' ).text().trim(), + 'December 2015', + 'The month and year are set correctly' ); }); -test( 'Navigating Forward by Year', function( assert ) { - - const currentYear = 2022; - this.set( 'currentYear', currentYear ); +test( 'Navigating Forward and Backward by Year', function( assert ) { + this.set( 'viewingDate', window.moment( [2015, 8, 1] ) ); + this.set( 'viewMode', 'months' ); this.render( hbs` {{sl-calendar - currentYear=currentYear - viewMode="months" + viewingDate=viewingDate + viewMode=viewMode }} ` ); assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - currentYear.toString(), + this.$( '>:first-child' ).find( '.calendar-controls a' ).text().trim(), + '2015', 'The current year is set correctly' ); - this.$( '>:first-child' ).find( '.sl-icon-next' ).click(); + this.$( '>:first-child' ).find( '.sl-icon-next' ).trigger( 'click' ); assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - ( currentYear + 1 ).toString(), + this.$( '>:first-child' ).find( '.calendar-controls a' ).text().trim(), + '2016', 'The next year is set correctly' ); -}); - -test( 'Navigating Backward by Year', function( assert ) { - - const currentYear = 2022; - this.set( 'currentYear', currentYear ); - - this.render( hbs` - {{sl-calendar - currentYear=currentYear - viewMode="months" - }} - ` ); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - currentYear.toString(), - 'The current year is set correctly' - ); - this.$( '>:first-child' ).find( '.sl-icon-previous' ).click(); + this.$( '>:first-child' ).find( '.sl-icon-previous' ).trigger( 'click' ).trigger( 'click' ); assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - ( currentYear - 1 ).toString(), + this.$( '>:first-child' ).find( '.calendar-controls a' ).text().trim(), + '2014', 'The previous year is set correctly' ); }); -test( 'Navigating Forward by Decade', function( assert ) { - - this.set( 'currentYear', 2022 ); +test( 'Navigating Forward and Backward by Decade', function( assert ) { + this.set( 'viewingDate', window.moment( [2015, 8, 1] ) ); + this.set( 'viewMode', 'years' ); this.render( hbs` {{sl-calendar - currentYear=currentYear - viewMode="years" + viewingDate=viewingDate + viewMode=viewMode }} ` ); assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - '2020-2029', - 'The current Decade is set correctly' + this.$( '>:first-child' ).find( '.calendar-controls th:first-child + th' ).text().trim(), + '2010 - 2019', + 'The current decade is set correctly' ); - this.$( '>:first-child' ).find( '.sl-icon-next' ).click(); + this.$( '>:first-child' ).find( '.sl-icon-next' ).trigger( 'click' ); assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - '2030-2039', - 'The next Decade is set correctly' + this.$( '>:first-child' ).find( '.calendar-controls th:first-child + th' ).text().trim(), + '2020 - 2029', + 'The next decade is set correctly' ); -}); - -test( 'Navigating Backward by Decade', function( assert ) { - this.set( 'currentYear', 2022 ); - - this.render( hbs` - {{sl-calendar - currentYear=currentYear - viewMode="years" - }} - ` ); + this.$( '>:first-child' ).find( '.sl-icon-previous' ).trigger( 'click' ).trigger( 'click' ); assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - '2020-2029', - 'The current Decade is set correctly' - ); - - this.$( '>:first-child' ).find( '.sl-icon-previous' ).click(); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - '2010-2019', - 'The previous Decade is set correctly' + this.$( '>:first-child' ).find( '.calendar-controls th:first-child + th' ).text().trim(), + '2000 - 2009', + 'The previous decade is set correctly' ); }); -test( 'When Locked, interacting with the view is not Possible', function( assert ) { +skip( 'When Locked, interacting with the view is not Possible', function( assert ) { const currentYear = 2022; this.set( 'currentYear', currentYear ); @@ -785,197 +656,93 @@ test( 'When Locked, interacting with the view is not Possible', function( assert ); }); -test( 'Navigating from Month to Year', function( assert ) { - - const currentYear = 2022; - this.set( 'currentYear', currentYear ); - - this.set( 'currentMonth', 9 ); +test( 'Changing viewMode by View Switcher', function( assert ) { + this.set( 'viewingDate', window.moment( [2015, 8, 1] ) ); + this.set( 'viewMode', 'days' ); this.render( hbs` {{sl-calendar - currentYear=currentYear - currentMonth=currentMonth - }} - ` ); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - 'September ' + currentYear, - 'The current month is set correctly' - ); - - this.$( '>:first-child' ).find( '.datepicker-switch' ).click(); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - currentYear.toString(), - 'The current year is set correctly' - ); -}); - -test( 'Navigating from Year to Month', function( assert ) { - - const currentYear = 2022; - this.set( 'currentYear', currentYear ); - - this.set( 'currentMonth', 9 ); - - this.set( 'content', testContent ); - - this.render( hbs` - {{sl-calendar - content=content - currentYear=currentYear - currentMonth=currentMonth - viewMode="months" + viewingDate=viewingDate + viewMode=viewMode }} ` ); assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - currentYear.toString(), - 'The current year is set correctly' + this.get( 'viewMode' ), + 'days', + 'The current viewMode is "days"' ); - this.$( '>:first-child' ).find( '.active' ).click(); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - 'September ' + currentYear, - 'The current month is set correctly' - ); -}); - -test( 'Navigating from Year to Decade', function( assert ) { - - const currentYear = 2022; - this.set( 'currentYear', currentYear ); - - this.render( hbs` - {{sl-calendar - currentYear=currentYear - viewMode="months" - }} - ` ); + this.$( '>:first-child' ).find( '.calendar-controls a' ).trigger( 'click' ); assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - currentYear.toString(), - 'The current year is set correctly' + this.get( 'viewMode' ), + 'months', + 'The current viewMode is "months"' ); - this.$( '>:first-child' ).find( '.datepicker-switch' ).click(); + this.$( '>:first-child' ).find( '.calendar-controls a' ).trigger( 'click' ); assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - '2020-2029', - 'The current decade is set correctly' + this.get( 'viewMode' ), + 'years', + 'The current viewMode is "years"' ); }); -test( 'Navigating from Decade to Year', function( assert ) { - - const currentYear = 2022; - this.set( 'currentYear', currentYear ); - - this.set( 'content', testContent ); +test( 'Changing viewMode by Selection', function( assert ) { + this.set( 'viewingDate', window.moment( [2015, 8, 1] ) ); + this.set( 'selectedDate', window.moment( [2015, 8, 1] ) ); + this.set( 'viewMode', 'years' ); this.render( hbs` {{sl-calendar - content=content - currentYear=currentYear - viewMode="years" + viewingDate=viewingDate + selectedDate=selectedDate + viewMode=viewMode }} ` ); assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - '2020-2029', - 'The current decade is set correctly' + this.get( 'viewMode' ), + 'years', + 'The current viewMode is "years"' ); - this.$( '>:first-child' ).find( '.active' ).click(); + this.$( '>:first-child' ).find( 'td.selected' ).trigger( 'click' ); assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - currentYear.toString(), - 'The current year is set correctly' + this.get( 'viewMode' ), + 'months', + 'The current viewMode is "months"' ); -}); -test( 'Navigating Forward by Month Crosses to Next Year', function( assert ) { - - const currentYear = 2022; - this.set( 'currentYear', currentYear ); - - this.set( 'currentMonth', 12 ); - - this.render( hbs` - {{sl-calendar - currentYear=currentYear - currentMonth=currentMonth - }} - ` ); + this.$( '>:first-child' ).find( 'td.selected' ).trigger( 'click' ); assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - 'December ' + currentYear, - 'The current month is set correctly' - ); - - this.$( '>:first-child' ).find( '.sl-icon-next' ).click(); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - 'January ' + ( currentYear + 1 ), - 'The next month is in the next year' + this.get( 'viewMode' ), + 'days', + 'The current viewMode is "days"' ); }); -test( 'Navigating Backward by Month Crosses to Previous Year', function( assert ) { - - const currentYear = 2022; - this.set( 'currentYear', currentYear ); - - this.set( 'currentMonth', 1 ); +test( 'All Days are Displayed in Order', function( assert ) { + this.set( 'viewingDate', window.moment( [2015, 0, 1] ) ); this.render( hbs` {{sl-calendar - currentYear=currentYear - currentMonth=currentMonth + viewingDate=viewingDate }} ` ); - assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - 'January ' + currentYear, - 'The current month is set correctly' - ); + let daysString = ""; - this.$( '>:first-child' ).find( '.sl-icon-previous' ).click(); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - 'December ' + ( currentYear - 1 ), - 'The previous month is in the previous year' - ); -}); - -test( 'All Days are Displayed in Order', function( assert ) { - this.set( 'currentYear', 2015 ); - this.set( 'currentMonth', 1 ); - - this.render( hbs` - {{sl-calendar - viewMode="days" - currentYear=currentYear - currentMonth=currentMonth - }} - ` ); + this.$( '>:first-child' ).find( 'td.day' ).each( function() { + daysString += $( this ).text().trim(); + }); assert.strictEqual( - this.$( '>:first-child' ).find( '.day' ).text().trim(), + daysString, '28293031123456789101112131415161718192021222324252627282930311234567', 'All days listed in order for specified month as expected' ); @@ -989,26 +756,37 @@ test( 'All Twelve Months are Displayed in Order', function( assert ) { }} ` ); + let monthsString = ""; + + this.$( '>:first-child' ).find( 'td.month' ).each( function() { + monthsString += $( this ).text().trim(); + }); + assert.strictEqual( - this.$( '>:first-child' ).find( 'tbody span' ).text().trim(), + monthsString, 'JanFebMarAprMayJunJulAugSepOctNovDec', 'Twelve months are listed in order' ); }); test( 'Twelve Years are Displayed in Order', function( assert ) { - - this.set( 'currentYear', 2022 ); + this.set( 'viewingDate', window.moment( [2022, 0, 1] ) ); this.render( hbs` {{sl-calendar viewMode="years" - currentYear=currentYear + viewingDate=viewingDate }} ` ); + let yearsString = ""; + + this.$( '>:first-child' ).find( 'td.year' ).each( function() { + yearsString += $( this ).text().trim(); + }); + assert.strictEqual( - this.$( '>:first-child' ).find( 'tbody span' ).text().trim(), + yearsString, '201920202021202220232024202520262027202820292030', 'Twelve years are listed in order' ); diff --git a/tests/unit/components/sl-calendar-day-test.js b/tests/unit/components/sl-calendar-day-test.js index 7c2316e0..ea3608b6 100644 --- a/tests/unit/components/sl-calendar-day-test.js +++ b/tests/unit/components/sl-calendar-day-test.js @@ -15,9 +15,9 @@ test( 'Default state of calendar-day is not active, new or old', function( asser ); assert.strictEqual( - this.$().hasClass( 'active' ), + this.$().hasClass( 'selected' ), false, - 'Default component does not have "active" class' + 'Default component does not have "selected" class' ); assert.strictEqual( @@ -54,8 +54,8 @@ test( 'Active state is applied correctly', function( assert ) { ); assert.ok( - this.$().hasClass( 'active' ), - 'Component element has class "active"' + this.$().hasClass( 'selected' ), + 'Component element has class "selected"' ); }); @@ -87,16 +87,6 @@ test( 'Old state is applied correctly', function( assert ) { ); }); -test( 'Property "day" populates component content', function( assert ) { - this.subject({ day: 42 }); - - assert.strictEqual( - Ember.$.trim( this.$().text() ), - '42', - '"day" value is set to element content' - ); -}); - test( 'Action bindings sends action with expected day content', function( assert ) { assert.expect( 1 ); diff --git a/tests/unit/components/sl-calendar-month-test.js b/tests/unit/components/sl-calendar-month-test.js index 5efde1f2..48da715b 100644 --- a/tests/unit/components/sl-calendar-month-test.js +++ b/tests/unit/components/sl-calendar-month-test.js @@ -17,9 +17,9 @@ test( 'Default state is inactive', function( assert ) { ); assert.strictEqual( - this.$().hasClass( 'active' ), + this.$().hasClass( 'selected' ), false, - 'Component does not have "active" class' + 'Component does not have "selected" class' ); }); @@ -39,8 +39,8 @@ test( 'Active state is set correctly', function( assert ) { ); assert.ok( - this.$().hasClass( 'active' ), - '"active" class is present' + this.$().hasClass( 'selected' ), + '"selected" class is present' ); }); @@ -63,38 +63,3 @@ test( 'Action binding sends action with month', function( assert ) { this.$().trigger( 'click' ); }); - -test( 'Short name property is invalid without month', function( assert ) { - const component = this.subject(); - - assert.strictEqual( - component.get( 'shortName' ), - 'Invalid date', - 'Invalid month results in invalid shortName' - ); -}); - -test( 'Short name property is defined with valid month', function( assert ) { - const component = this.subject({ month: 1 }); - - assert.strictEqual( - component.get( 'shortName' ), - 'Jan', - 'Valid shortName with valid month' - ); -}); - -test( 'Dependent keys are correct', function( assert ) { - const component = this.subject(); - - const shortNameDependentKeys = [ - 'month' - ]; - - assert.deepEqual( - component.shortName._dependentKeys, - shortNameDependentKeys, - 'Dependent keys are correct for shortName()' - ); -}); - diff --git a/tests/unit/components/sl-calendar-test.js b/tests/unit/components/sl-calendar-test.js index 2bbe6721..a6be8acc 100755 --- a/tests/unit/components/sl-calendar-test.js +++ b/tests/unit/components/sl-calendar-test.js @@ -22,27 +22,25 @@ test( 'Default property values are set correctly', function( assert ) { 'content: []' ); - const today = new Date(); - const month = today.getMonth() + 1; - assert.strictEqual( - component.get( 'currentMonth' ), - month, - `currentMonth: ${month}` + component.get( 'dateValuePath' ), + 'date', + 'dateValuePath: "date"' ); - const year = today.getFullYear(); + assert.ok( + component.get( 'fixedWeekCount' ), + 'fixedWeekCount: true' + ); - assert.strictEqual( - component.get( 'currentYear' ), - year, - `currentYear: ${year}` + assert.ok( + component.get( 'focusable' ), + 'focusable: true' ); - assert.strictEqual( - component.get( 'dateValuePath' ), - 'date', - 'dateValuePath: "date"' + assert.notOk( + component.get( 'hasFocus' ), + 'hasFocus: false' ); assert.strictEqual( @@ -57,6 +55,36 @@ test( 'Default property values are set correctly', function( assert ) { 'locked: false' ); + assert.strictEqual( + component.get( 'selectConstraint' ), + true, + 'selectConstraint: ?' + ); + + assert.strictEqual( + component.get( 'selectedDate' ), + null, + 'selectedDate: null' + ); + + assert.strictEqual( + component.get( 'showingMonth' ), + null, + 'showingMonth: null' + ); + + assert.strictEqual( + component.get( 'today' ), + null, + 'today: null' + ); + + assert.strictEqual( + component.get( 'viewingDate' ), + null, + 'viewingDate: null' + ); + assert.strictEqual( component.get( 'viewMode' ), 'days', @@ -64,7 +92,7 @@ test( 'Default property values are set correctly', function( assert ) { ); }); -test( 'Lock mode prevents changing state', function( assert ) { +skip( 'Lock mode prevents changing state', function( assert ) { const component = this.subject({ locked: true }); const initialDecadeStart = component.get( 'decadeStart' ); @@ -133,82 +161,56 @@ skip( 'setMonth - currentMonth and viewMode set correctly', function() { }); test( 'changeDecade action works', function( assert ) { - const component = this.subject({ currentYear: 2015 }); - - assert.strictEqual( - component.get( 'decadeStart' ), - 2010, - 'Initial decadeStart is expected value' - ); - - assert.strictEqual( - component.get( 'decadeEnd' ), - 2019, - 'Initial decadeEnd is expected value' - ); + const component = this.subject({ + viewingDate: window.moment( [ 2015, 0, 1 ] ) + }); Ember.run( () => { component.send( 'changeDecade', 1 ); }); assert.strictEqual( - component.get( 'decadeStart' ), - 2020, - 'Altered decadeStart is expected value' - ); - - assert.strictEqual( - component.get( 'decadeEnd' ), - 2029, - 'Altered decadeEnd is expected value' + component.get( 'viewingDate' ).year(), + 2025, + 'Altered viewingDate is expected value' ); }); test( 'changeMonth action works', function( assert ) { - const component = this.subject({ currentMonth: 1 }); - - assert.strictEqual( - component.get( 'currentMonth' ), - 1, - 'Initial currentMonth is expected value' - ); + const component = this.subject({ + viewingDate: window.moment( [ 2015, 0, 1 ] ) + }); Ember.run( () => { component.send( 'changeMonth', 1 ); }); assert.strictEqual( - component.get( 'currentMonth' ), - 2, - 'Altered currentMonth is expected value' + component.get( 'viewingDate' ).month(), + 1, + 'Altered viewingDate is expected value' ); }); test( 'changeYear action works', function( assert ) { - const component = this.subject({ currentYear: 2015 }); - - assert.strictEqual( - component.get( 'currentYear' ), - 2015, - 'Initial currentYear is expected value' - ); + const component = this.subject({ + viewingDate: window.moment( [ 2015, 0, 1 ] ) + }); Ember.run( () => { component.send( 'changeYear', 1 ); }); assert.strictEqual( - component.get( 'currentYear' ), + component.get( 'viewingDate' ).year(), 2016, - 'Altered currentYear is expected value' + 'Altered viewingDate is expected value' ); }); - test( 'Decrementing month from January causes year to decrement', function( assert ) { const component = this.subject({ - currentMonth: 1, - currentYear: 2015 + viewingDate: window.moment( [ 2015, 0, 1 ] ) }); Ember.run( () => { @@ -216,16 +218,15 @@ test( 'Decrementing month from January causes year to decrement', function( asse }); assert.strictEqual( - component.get( 'currentYear' ), + component.get( 'viewingDate' ).year(), 2014, - 'currentYear is decremented' + 'viewingDate is the appropriate year' ); }); test( 'Incrementing month from December causes year to increment', function( assert ) { const component = this.subject({ - currentMonth: 12, - currentYear: 2015 + viewingDate: window.moment( [ 2015, 11, 1 ] ) }); Ember.run( () => { @@ -233,9 +234,9 @@ test( 'Incrementing month from December causes year to increment', function( ass }); assert.strictEqual( - component.get( 'currentYear' ), + component.get( 'viewingDate' ).year(), 2016, - 'currentYear is incremented' + 'viewingDate is the appropriate year' ); }); @@ -710,49 +711,84 @@ skip( 'shortWeekDayNames - returns array of day names in short name format (Su, test( 'Years for decade view are assembled correctly', function( assert ) { const component = this.subject(); + const allYears = component.get( 'yearsInDecadeView' ); + const flattenedYears = []; + + for ( let yearGroup = 0; yearGroup < allYears.length; yearGroup++ ) { + for ( let year = 0; year < allYears[ yearGroup ].length; year++ ) { + flattenedYears.push( allYears[ yearGroup ][ year ] ); + } + } + assert.strictEqual( - component.get( 'yearsInDecadeView' ).length, + flattenedYears.length, 12, 'Twelve years were generated for the decade view' ); }); -test( 'Dependent keys are correct', function( assert ) { +test( 'Observer keys are correct', function( assert ) { const component = this.subject(); - const contentDatesDependentKeys = [ - 'content', - 'dateValuePath' + const activeDateChangeKeys = [ + 'selectedDate' ]; - const currentMonthStringDependentKeys = [ - 'currentMonth', - 'currentYear', - 'locale' + const focusedDateChangeKeys = [ + 'viewingDate' ]; - const daysInMonthDependentKeys = [ - 'currentMonth', - 'currentYear' + const updateShowingMonthKeys = [ + 'viewingDate' ]; - const decadeEndDependentKeys = [ - 'decadeStart' + assert.deepEqual( + component.activeDateChange.__ember_observes__, + activeDateChangeKeys, + 'Observer keys are correct for activeDateChange()' + ); + + assert.deepEqual( + component.focusedDateChange.__ember_observes__, + focusedDateChangeKeys, + 'Observer keys are correct for focusedDateChange()' + ); + + assert.deepEqual( + component.updateShowingMonth.__ember_observes__, + updateShowingMonthKeys, + 'Observer keys are correct for updateShowingMonth()' + ); +}); + +test( 'Dependent keys are correct', function( assert ) { + const component = this.subject(); + + const calendarTitleDependentKeys = [ + 'viewingDate', + 'locale', + 'viewMode' ]; - const decadeStartDependentKeys = [ - 'currentYear' + const contentDatesDependentKeys = [ + 'content', + 'dateValuePath' ]; const monthsInYearViewDependentKeys = [ - 'contentDates', - 'currentYear' + 'viewingDate', + 'selectedDate', + 'locale' ]; const shortWeekDayNamesDependentKeys = [ 'locale' ]; + const tabIndexDependentKeys = [ + 'focusable' + ]; + const viewingDaysDependentKeys = [ 'viewMode' ]; @@ -766,46 +802,28 @@ test( 'Dependent keys are correct', function( assert ) { ]; const weeksInMonthViewDependentKeys = [ - 'contentDates', - 'currentMonth', - 'currentYear', - 'daysInMonth' + 'fixedWeekCount', + 'locale', + 'selectConstraint', + 'showingMonth', + 'viewingDays' ]; const yearsInDecadeViewDependentKeys = [ - 'contentDates', - 'decadeEnd', - 'decadeStart' + 'viewingDate', + 'selectedDate' ]; assert.deepEqual( - component.contentDates._dependentKeys, - contentDatesDependentKeys, - 'Dependent keys are correct for contentDates()' - ); - - assert.deepEqual( - component.currentMonthString._dependentKeys, - currentMonthStringDependentKeys, - 'Dependent keys are correct for currentMonthString()' - ); - - assert.deepEqual( - component.daysInMonth._dependentKeys, - daysInMonthDependentKeys, - 'Dependent keys are correct for daysInMonth()' - ); - - assert.deepEqual( - component.decadeEnd._dependentKeys, - decadeEndDependentKeys, - 'Dependent keys are correct for decadeEnd()' + component.calendarTitle._dependentKeys, + calendarTitleDependentKeys, + 'Dependent keys are correct for calendarTitle()' ); assert.deepEqual( - component.decadeStart._dependentKeys, - decadeStartDependentKeys, - 'Dependent keys are correct for decadeStart()' + component.contentDates._dependentKeys, + contentDatesDependentKeys, + 'Dependent keys are correct for contentDates()' ); assert.deepEqual( @@ -820,6 +838,12 @@ test( 'Dependent keys are correct', function( assert ) { 'Dependent keys are correct for shortWeekDayNames()' ); + assert.deepEqual( + component.tabIndex._dependentKeys, + tabIndexDependentKeys, + 'Dependent keys are correct for tabIndex()' + ); + assert.deepEqual( component.viewingDays._dependentKeys, viewingDaysDependentKeys, From fbad2b6aa71ba70b4fb950380bd58c2bda74e058 Mon Sep 17 00:00:00 2001 From: J Corley Date: Wed, 27 Jan 2016 16:51:39 -0600 Subject: [PATCH 12/25] Test cleanup. ** DATE PICKER ** Re-added missed sendAction. Commented more unneeded properties. Alphabetized methods. Temporarily added action to demo for testing. Integration tests. ** DATE RANGE PICKER ** Commented unneeded properties. Added defined three missing properties. Integration tests. Unit tests. --- addon/components/sl-date-picker.js | 24 +- addon/components/sl-date-range-picker.js | 20 +- .../app/templates/demos/sl-date-picker.hbs | 2 +- .../components/sl-date-picker-test.js | 166 ++++++------ .../components/sl-date-range-picker-test.js | 243 ++++++++++------- .../components/sl-date-range-picker-test.js | 244 +++++------------- 6 files changed, 313 insertions(+), 386 deletions(-) diff --git a/addon/components/sl-date-picker.js b/addon/components/sl-date-picker.js index 2a232f7d..388befde 100755 --- a/addon/components/sl-date-picker.js +++ b/addon/components/sl-date-picker.js @@ -55,6 +55,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa selectDate( date ) { this.selectDate( date ); + this.sendAction( 'action', date ); } }, @@ -273,7 +274,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @type {String} */ - startView: 'month', + //startView: 'month', /** * When true or "linked", displays a "Today" button at the bottom of the @@ -284,14 +285,14 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @type {Boolean|String} */ - todayBtn: false, + //todayBtn: false, /** * Whether to highlight the current date or not * * @type {Boolean} */ - todayHighlight: false, + //todayHighlight: false, /** * The date either selected by the datepicker or entered by the user @@ -305,7 +306,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @type {Number} */ - weekStart: 0, + //weekStart: 0, locale: 'en', @@ -378,13 +379,6 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa } ), - viewingDate: Ember.computed( - 'selectedDate', - function() { - return this.get( 'selectedDate' ); - } - ), - selectDate( date ) { this.set( 'selectedDate', date ); }, @@ -402,6 +396,12 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa return selectedDate.format( format ); } - ) + ), + viewingDate: Ember.computed( + 'selectedDate', + function() { + return this.get( 'selectedDate' ); + } + ) }); diff --git a/addon/components/sl-date-range-picker.js b/addon/components/sl-date-range-picker.js index ca42027c..3d595bb0 100755 --- a/addon/components/sl-date-range-picker.js +++ b/addon/components/sl-date-range-picker.js @@ -48,20 +48,6 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { */ format: null, - /** - * The last valid date for the date range - * - * @type {?Date|String} - */ - //maxDate: null, - - /** - * The earliest date selectable in the range - * - * @type {?Date|String} - */ - //minDate: null, - /** * The value for the startDate input * @@ -69,6 +55,8 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { */ //startDateValue: null, + label: null, + startDate: null, endDate: null, @@ -80,6 +68,10 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { locale: 'en', + startDatePlaceholder: null, + + endDatePlaceholder: null, + // ------------------------------------------------------------------------- // Observers diff --git a/tests/dummy/app/templates/demos/sl-date-picker.hbs b/tests/dummy/app/templates/demos/sl-date-picker.hbs index 68ba97d0..f3e256f5 100755 --- a/tests/dummy/app/templates/demos/sl-date-picker.hbs +++ b/tests/dummy/app/templates/demos/sl-date-picker.hbs @@ -13,7 +13,7 @@
Rendered Component
- {{sl-date-picker label="Date picker" selectedDate=selectedDate}} + {{sl-date-picker action="logLabel" label="Date picker" selectedDate=selectedDate}}
diff --git a/tests/integration/components/sl-date-picker-test.js b/tests/integration/components/sl-date-picker-test.js index ed7ac0f7..1475c73f 100644 --- a/tests/integration/components/sl-date-picker-test.js +++ b/tests/integration/components/sl-date-picker-test.js @@ -1,18 +1,14 @@ import { moduleForComponent, test } from 'ember-qunit'; import Ember from 'ember'; import hbs from 'htmlbars-inline-precompile'; -import sinon from 'sinon'; +import { skip } from 'qunit'; const defaultTemplate = hbs` {{sl-date-picker}} `; moduleForComponent( 'sl-date-picker', 'Integration | Component | sl date picker', { - integration: true, - - afterEach() { - Ember.$( '.datepicker' ).remove(); - } + integration: true }); test( 'Default rendered state', function( assert ) { @@ -91,7 +87,8 @@ test( 'helpText is accepted as a parameter', function( assert ) { ); }); -test( 'value is accepted as a parameter', function( assert ) { +// not proper way to seed value +skip( 'value is accepted as a parameter', function( assert ) { this.render( defaultTemplate ); let input = this.$( '>:first-child' ).find( 'input' ); @@ -176,118 +173,113 @@ test( 'placeholder is accepted as a parameter', function( assert ) { ); }); -test( 'action is fired when date changes on datepicker', function( assert ) { - assert.expect( 1 ); +test( 'properties are properly passed to sl-calendar', function( assert ) { + const mockCalendarTemplate = hbs` + {{testAttrs}} + `; - const done = assert.async(); + this.registry.register( 'template:sl-calendar', mockCalendarTemplate ); - this.on( 'action', function() { - assert.ok( - 'Action was fired' - ); + this.registry.register( 'component:sl-calendar', + Ember.Component.extend({ + layoutName: 'sl-calendar', - done(); - }); + testAttrs: null, - this.render( hbs` - {{sl-date-picker action="action"}} - ` ); + init() { + this._super( ...arguments ); - this.$( '>:first-child' ) - .find( 'input.date-picker' ) - .triggerHandler( 'focus' ); + const attrs = this.get( 'attrs' ); - Ember.$( '.day:first' ).click(); -}); + this.set( 'testAttrs', JSON.stringify( attrs ) ); + } + }) + ); -test( 'updateDateRange() - clears input date when outside of startDate range', function( assert ) { - this.set( 'startDate' ); + const locale = 'fr'; + const selectedDate = window.moment( [ 2015, 0, 1 ] ); + const viewingDate = window.moment( [ 2015, 0, 1 ] ); + const selectConstraint = { + start: window.moment( [ 2015, 0, 1 ] ), + end: window.moment( [ 2015, 0, 5 ] ) + }; + + this.set( 'locale', locale ); + this.set( 'selectedDate', selectedDate ); + this.set( 'viewingDate', viewingDate ); + this.set( 'selectConstraint', selectConstraint ); this.render( hbs` - {{sl-date-picker startDate=startDate }} + {{sl-date-picker + locale=locale + selectedDate=selectedDate + viewingDate=viewingDate + selectConstraint=selectConstraint + hasFocus=true + }} ` ); - const input = this.$( '>:first-child' ).find( 'input.date-picker' ); - - input.triggerHandler( 'focus' ); + const testAttrs = { + locale: locale, + selectedDate: selectedDate, + viewingDate: viewingDate, + selectConstraint: selectConstraint + }; - Ember.$( '.day:first' ).click(); + const assertAttrs = JSON.parse( JSON.stringify( testAttrs ) ); - this.set( 'startDate', window.moment().add( 30, 'days' ).toDate() ); + const attrs = JSON.parse( this.$( '>:first-child' ).find( 'span.testAttrs' ).text() ); assert.strictEqual( - input.datepicker().val(), - '', - 'The datepicker input value was cleared successfully' + attrs.fixedWeekCount, + true, + 'fixedWeekCount is passed through to calendar' ); -}); - -test( 'updateDateRange() - clears input date when outside of endDate range', function( assert ) { - this.set( 'endDate' ); - - this.render( hbs` - {{sl-date-picker endDate=endDate}} - ` ); - - const input = this.$( '>:first-child' ).find( 'input.date-picker' ); - - input.triggerHandler( 'focus' ); - - Ember.$( '.day:first' ).click(); - - this.set( 'endDate', window.moment().subtract( 60, 'days' ).toDate() ); assert.strictEqual( - input.datepicker().val(), - '', - 'The datepicker input value was cleared successfully' + attrs.locale.value, + assertAttrs.locale, + 'locale is passed through to calendar' ); -}); - -test( 'End date is set on datepicker when endDate property is updated', function( assert ) { - const endDate = window.moment( '2016-01-01' ).toDate(); - const endDateTwo = window.moment( '2016-02-02' ).toDate(); - this.set( 'endDate', endDate ); - - this.render( hbs` - {{sl-date-picker endDate=endDate}} - ` ); - - const input = this.$( '>:first-child' ).find( 'input.date-picker' ); - const datePicker = input.data( 'datepicker' ); - const spy = sinon.spy( Object.getPrototypeOf( datePicker ), 'setEndDate' ); - - this.set( 'endDate', endDateTwo ); + assert.strictEqual( + attrs.selectedDate.value, + assertAttrs.selectedDate, + 'selectedDate is passed through to calendar' + ); - assert.ok( - spy.calledWith( endDateTwo ) + assert.strictEqual( + attrs.viewingDate.value, + assertAttrs.viewingDate, + 'viewingDate is passed through to calendar' ); - datePicker.setEndDate.restore(); + assert.deepEqual( + attrs.selectConstraint.value, + assertAttrs.selectConstraint, + 'selectConstraint is passed through to calendar' + ); }); -test( 'Start date is set on datepicker when startDate property is updated', function( assert ) { - const startDate = window.moment( '2016-01-01' ).toDate(); - const startDateTwo = window.moment( '2016-02-02' ).toDate(); +test( 'action is fired when date changes on datepicker', function( assert ) { + assert.expect( 1 ); - this.set( 'startDate', startDate ); + const done = assert.async(); this.render( hbs` - {{sl-date-picker startDate=startDate}} + {{sl-date-picker action="testAction" hasFocus=true}} ` ); - const input = this.$( '>:first-child' ).find( 'input.date-picker' ); - const datePicker = input.data( 'datepicker' ); - const spy = sinon.spy( Object.getPrototypeOf( datePicker ), 'setStartDate' ); - - this.set( 'startDate', startDateTwo ); + this.on( 'testAction', function() { + assert.ok( + true, + 'Action was fired' + ); - assert.ok( - spy.calledWith( startDateTwo ) - ); + done(); + }); - datePicker.setStartDate.restore(); + this.$( 'td.day:first' ).click(); }); test( 'Tooltip properties are set correctly when title parameter is set', function( assert ) { diff --git a/tests/integration/components/sl-date-range-picker-test.js b/tests/integration/components/sl-date-range-picker-test.js index 09de3049..5b90a09c 100644 --- a/tests/integration/components/sl-date-range-picker-test.js +++ b/tests/integration/components/sl-date-range-picker-test.js @@ -22,76 +22,186 @@ test( 'Default rendered state', function( assert ) { ); }); -test( 'placeholders are accepted', function( assert ) { +test( 'properties are properly passed to first sl-date-picker', function( assert ) { + const mockDatePickerTemplate = hbs` + {{testAttrs}} + `; + + this.registry.register( 'template:sl-date-picker', mockDatePickerTemplate ); + + this.registry.register( 'component:sl-date-picker', + Ember.Component.extend({ + layoutName: 'sl-date-picker', + + testAttrs: null, + + init() { + this._super( ...arguments ); + + const attrs = this.get( 'attrs' ); + + this.set( 'testAttrs', JSON.stringify( attrs ) ); + } + }) + ); + + const placeholder = '__startPlaceholder__'; + const format = 'YYYY+MM-DD'; + const selectConstraint = { + start: window.moment( [ 2015, 0, 1 ] ), + end: window.moment( [ 2015, 0, 5 ] ) + }; + const selectedDate = window.moment( [ 2015, 0, 1 ] ); + + this.set( 'placeholder', placeholder ); + this.set( 'format', format ); + this.set( 'selectConstraint', selectConstraint ); + this.set( 'selectedDate', selectedDate ); + this.render( hbs` {{sl-date-range-picker - label="Select date range" - startDatePlaceholder="__StartPlaceholder__" - endDatePlaceholder="__EndPlaceholder__" + startDatePlaceholder=placeholder + format=format + selectConstraint=selectConstraint + startDate=selectedDate }} ` ); + const testAttrs = { + placeholder: placeholder, + format: format, + selectConstraint: selectConstraint, + selectedDate: selectedDate + }; + + const assertAttrs = JSON.parse( JSON.stringify( testAttrs ) ); + + const attrs = JSON.parse( this.$( '>:first-child' ).find( 'span.testAttrs' ).first().text() ); + assert.strictEqual( - this.$( '>:first-child' ).find( '.sl-daterange-start-date' ).find( 'input' ).prop( 'placeholder' ), - '__StartPlaceholder__', - 'Start date input placeholder is set' + attrs.placeholder.value, + assertAttrs.placeholder, + 'placeholder is passed through to date-picker' ); assert.strictEqual( - this.$( '>:first-child' ).find( '.sl-daterange-end-date' ).find( 'input' ).prop( 'placeholder' ), - '__EndPlaceholder__', - 'End date input placeholder is set' + attrs.format.value, + assertAttrs.format, + 'format is passed through to date-picker' + ); + + assert.deepEqual( + attrs.selectConstraint.value, + assertAttrs.selectConstraint, + 'selectConstraint is passed through to date-picker' + ); + + assert.strictEqual( + attrs.selectedDate.value, + assertAttrs.selectedDate, + 'selectedDate is passed through to date-picker' ); }); -test( 'label is accepted as a parameter', function( assert ) { +test( 'properties are properly passed to second sl-date-picker', function( assert ) { + const mockDatePickerTemplate = hbs` + {{testAttrs}} + `; + + this.registry.register( 'template:sl-date-picker', mockDatePickerTemplate ); + + this.registry.register( 'component:sl-date-picker', + Ember.Component.extend({ + layoutName: 'sl-date-picker', + + testAttrs: null, + + init() { + this._super( ...arguments ); + + const attrs = this.get( 'attrs' ); + + this.set( 'testAttrs', JSON.stringify( attrs ) ); + } + }) + ); + + const placeholder = '__endPlaceholder__'; + const format = 'YYYY+MM-DD'; + const selectConstraint = { + start: window.moment( [ 2015, 0, 1 ] ), + end: window.moment( [ 2015, 0, 5 ] ) + }; + const selectedDate = window.moment( [ 2015, 0, 1 ] ); + + this.set( 'placeholder', placeholder ); + this.set( 'format', format ); + this.set( 'selectConstraint', selectConstraint ); + this.set( 'selectedDate', selectedDate ); this.render( hbs` {{sl-date-range-picker - label="lorem ipsum" + endDatePlaceholder=placeholder + format=format + selectConstraint=selectConstraint + endDate=selectedDate }} ` ); + const testAttrs = { + placeholder: placeholder, + format: format, + selectConstraint: selectConstraint, + selectedDate: selectedDate + }; + + const assertAttrs = JSON.parse( JSON.stringify( testAttrs ) ); + + const attrs = JSON.parse( this.$( '>:first-child' ).find( 'span.testAttrs' ).last().text() ); + assert.strictEqual( - this.$( '>:first-child' ).find( 'label' ).html(), - 'lorem ipsum', - 'The "label" property text was set' + attrs.placeholder.value, + assertAttrs.placeholder, + 'placeholder is passed through to date-picker' ); assert.strictEqual( - this.$( '>:first-child' ).find( 'label' ).prop( 'for' ), - this.$( '>:first-child' ).find( '.sl-daterange-start-date' ).find( 'input' ).prop( 'id' ), - '"label for" property has the correct value' + attrs.format.value, + assertAttrs.format, + 'format is passed through to date-picker' ); -}); - -test( 'endDatePlaceholder is accepted as a parameter', function( assert ) { - this.render( hbs` - {{sl-date-range-picker - endDatePlaceholder="Select end date" - }} - ` ); + assert.deepEqual( + attrs.selectConstraint.value, + assertAttrs.selectConstraint, + 'selectConstraint is passed through to date-picker' + ); assert.strictEqual( - this.$( '>:first-child' ).find( '.sl-daterange-end-date' ).find( 'input' ).attr( 'placeholder' ), - 'Select end date', - 'The "endDatePlaceholder" property text was set' + attrs.selectedDate.value, + assertAttrs.selectedDate, + 'selectedDate is passed through to date-picker' ); }); -test( 'startDatePlaceholder is accepted as a parameter', function( assert ) { +test( 'label is accepted as a parameter', function( assert ) { this.render( hbs` {{sl-date-range-picker - startDatePlaceholder="Select start date" + label="lorem ipsum" }} ` ); assert.strictEqual( - this.$( '>:first-child' ).find( '.sl-daterange-start-date' ).find( 'input' ).attr( 'placeholder' ), - 'Select start date', - 'The "startDatePlaceholder" property text was set' + this.$( '>:first-child' ).find( 'label' ).html(), + 'lorem ipsum', + 'The "label" property text was set' + ); + + assert.strictEqual( + this.$( '>:first-child' ).find( 'label' ).prop( 'for' ), + this.$( '>:first-child' ).find( '.sl-daterange-start-date' ).find( 'input' ).prop( 'id' ), + '"label for" property has the correct value' ); }); @@ -110,7 +220,8 @@ test( 'helpText is accepted as a parameter', function( assert ) { ); }); -test( 'startDateValue is accepted as a parameter', function( assert ) { +// removing value seeding +skip( 'startDateValue is accepted as a parameter', function( assert ) { this.render( hbs` {{sl-date-range-picker @@ -125,7 +236,8 @@ test( 'startDateValue is accepted as a parameter', function( assert ) { ); }); -test( 'endDateValue is accepted as a parameter', function( assert ) { +// removing value seeding +skip( 'endDateValue is accepted as a parameter', function( assert ) { this.render( hbs` {{sl-date-range-picker @@ -140,63 +252,7 @@ test( 'endDateValue is accepted as a parameter', function( assert ) { ); }); -test( 'format is accepted as a parameter', function( assert ) { - - this.render( hbs` - {{sl-date-range-picker - format="m/d/yyyy" - startDateValue="09/25/2015" - }} - ` ); - - const input = this.$( '>:first-child' ).find( '.sl-daterange-start-date' ).find( 'input' ); - input.triggerHandler( 'focus' ); - - Ember.$( '.datepicker' ).last().find( '.datepicker-days' ).find( 'td' ).not( '.old' ).first().trigger( 'click' ); - - assert.strictEqual( - input.val(), - '9/1/2015', - 'The selected date was formatted based on the "format" property' - ); -}); - -test( 'minDate is accepted as a parameter', function( assert ) { - - this.render( hbs` - {{sl-date-range-picker - minDate="09/15/2015" - startDateValue="09/25/2015" - }} - ` ); - - this.$( '>:first-child' ).find( '.sl-daterange-start-date' ).find( 'input' ).triggerHandler( 'focus' ); - - assert.strictEqual( - Ember.$( '.datepicker' ).last().find( '.datepicker-days' ).find( 'td' ).not( '.disabled' ).first().text(), - '15', - 'The "minDate" was set correctly' - ); -}); - -test( 'maxDate is accepted as a parameter', function( assert ) { - - this.render( hbs` - {{sl-date-range-picker - maxDate="09/28/2015" - endDateValue="09/25/2015" - }} - ` ); - - this.$( '>:first-child' ).find( '.sl-daterange-end-date' ).find( 'input' ).triggerHandler( 'focus' ); - - assert.strictEqual( - Ember.$( '.datepicker' ).last().find( '.datepicker-days' ).find( 'td' ).not( '.disabled' ).last().text(), - '28', - 'The "maxDate" was set correctly' - ); -}); - +// verify this is in date-picker test( 'Selected day is set in the start date input field', function( assert ) { this.render( hbs` @@ -217,6 +273,7 @@ test( 'Selected day is set in the start date input field', function( assert ) { ); }); +// verify this is in date-picker test( 'Selected day is set in the end date input field', function( assert ) { this.render( hbs` {{sl-date-range-picker diff --git a/tests/unit/components/sl-date-range-picker-test.js b/tests/unit/components/sl-date-range-picker-test.js index 89a1c4df..a70be8d0 100755 --- a/tests/unit/components/sl-date-range-picker-test.js +++ b/tests/unit/components/sl-date-range-picker-test.js @@ -27,33 +27,51 @@ test( 'Default property values are set correctly', function( assert ) { const component = this.subject(); assert.strictEqual( - component.get( 'endDateValue' ), + component.get( 'endDate' ), null, - 'endDateValue: null' + 'endDate: null' + ); + + assert.strictEqual( + component.get( 'endDatePlaceholder' ), + null, + 'endDatePlaceholder: null' ); assert.strictEqual( component.get( 'format' ), - 'mm/dd/yyyy', - 'format: "mm/dd/yyyy"' + null, + 'format: null' ); assert.strictEqual( - component.get( 'maxDate' ), + component.get( 'label' ), null, - 'maxDate: null' + 'label: null' + ); + + assert.strictEqual( + component.get( 'locale' ), + 'en', + 'locale: "en"' + ); + + assert.strictEqual( + component.get( 'selectConstraint' ), + true, + 'selectConstraint: ?' ); assert.strictEqual( - component.get( 'minDate' ), + component.get( 'startDate' ), null, - 'minDate: null' + 'startDate: null' ); assert.strictEqual( - component.get( 'startDateValue' ), + component.get( 'startDatePlaceholder' ), null, - 'startDateValue: null' + 'startDatePlaceholder: null' ); }); @@ -75,119 +93,67 @@ test( 'Change focus to end date input upon start date change', function( assert daterangeEndDate.trigger.restore(); }); -test( 'Earliest end date is the based on min date and start date', function( assert ) { +test( 'Earliest end date is based on selectConstraint and startDate', function( assert ) { const component = this.subject(); - assert.strictEqual( - component.get( 'earliestEndDate' ), - null - ); - - Ember.run( () => { - component.set( 'minDate', '01/01/2001' ); - }); - - assert.equal( - component.get( 'earliestEndDate' ), - '01/01/2001' - ); - - Ember.run( () => { - component.set( 'startDateValue', '01/01/2015' ); - }); - - assert.equal( - component.get( 'earliestEndDate' ), - '01/01/2015' - ); -}); - -test( 'Latest start date is the based on max date and end date', function( assert ) { - const component = this.subject(); + const startConstraint = window.moment( [ 2015, 0, 1 ] ); + const startDate = window.moment( [ 2015, 1, 1 ] ); assert.strictEqual( - component.get( 'latestStartDate' ), - null + component.get( 'startSelectConstraint' ).start, + null, + 'Earliest end date is null by default' ); - Ember.run( () => { - component.set( 'maxDate', '01/01/2029' ); - }); + component.set( 'selectConstraint', { + start: startConstraint, + end: null + } ); - assert.equal( - component.get( 'latestStartDate' ), - '01/01/2029' + assert.strictEqual( + component.get( 'startSelectConstraint' ).start, + startConstraint, + 'Earliest end date is selectConstraint.start if there is one' ); - Ember.run( () => { - component.set( 'endDateValue', '01/01/2015' ); - }); + component.set( 'startDate', startDate ); - assert.equal( - component.get( 'latestStartDate' ), - '01/01/2015' + assert.strictEqual( + component.get( 'startSelectConstraint' ).start, + startDate, + 'Earliest end date is startDate if there is one' ); }); -test( 'Events from start date input are removed upon willClearRender', function( assert ) { - const spyOn = sinon.spy( Ember.$.fn, 'on' ); - const spyOff = sinon.spy( Ember.$.fn, 'off' ); - +test( 'Latest start date is based on selectConstraint and endDate', function( assert ) { const component = this.subject(); - this.render(); - - spyOn.reset(); + const endConstraint = window.moment( [ 2015, 1, 1 ] ); + const endDate = window.moment( [ 2015, 0, 1 ] ); - component.trigger( 'didInsertElement' ); - - assert.ok( - spyOn.calledWith( component.namespaceEvent( 'changeDate' ) ), - 'changeDate bootstrap date picker event bound' - ); - - assert.ok( - spyOn.alwaysCalledOn( component.get( 'startDateInput' ) ), - 'changeDate bind was called on startDateInput' - ); - - spyOff.reset(); - - component.trigger( 'willClearRender' ); - - assert.ok( - spyOff.calledWith( component.namespaceEvent( 'changeDate' ) ), - 'changeDate bootstrap date picker event unbound' - ); - - assert.ok( - spyOff.alwaysCalledOn( component.get( 'startDateInput' ) ), - 'changeDate unbind was called on startDateInput' + assert.strictEqual( + component.get( 'endSelectConstraint' ).end, + null, + 'Latest start date is null by default' ); - Ember.$.fn.on.restore(); - Ember.$.fn.off.restore(); -}); - -test( 'label, startDatePlaceholder, and endDatePlaceholder are undefined by default', function( assert ) { - const component = this.subject(); + component.set( 'selectConstraint', { + start: null, + end: endConstraint + } ); assert.strictEqual( - component.get( 'label' ), - undefined, - 'label is undefined by default' + component.get( 'endSelectConstraint' ).end, + endConstraint, + 'Latest start date is selectConstraint.end if there is one' ); - assert.strictEqual( - component.get( 'startDatePlaceholder' ), - undefined, - 'startDatePlaceholder is undefined by default' - ); + component.set( 'endDate', endDate ); assert.strictEqual( - component.get( 'endDatePlaceholder' ), - undefined, - 'endDatePlaceholder is undefined by default' + component.get( 'endSelectConstraint' ).end, + endDate, + 'Latest start date is endDate if there is one' ); }); @@ -213,83 +179,3 @@ test( 'label is accepted as a parameter', function( assert ) { 'label is used for start date input' ); }); - -test( 'Default format gets passed to child date pickers', function( assert ) { - const component = this.subject(); - - assert.equal( - this.$( '.sl-daterange-start-date input.date-picker' ).data().datepicker.o.format, - component.get( 'format' ), - 'Default format gets passed to start date picker' - ); - - assert.equal( - this.$( '.sl-daterange-end-date input.date-picker' ).data().datepicker.o.format, - component.get( 'format' ), - 'Default format gets passed to end date picker' - ); -}); - -test( 'Format parameter gets passed to child date pickers', function( assert ) { - const format = 'yyyy/mm/dd'; - - this.subject({ format: format }); - - assert.equal( - this.$( '.sl-daterange-start-date input.date-picker' ).data().datepicker.o.format, - format, - 'Format parameter gets passed to start date picker' - ); - - assert.equal( - this.$( '.sl-daterange-end-date input.date-picker' ).data().datepicker.o.format, - format, - 'Format parameter gets passed to end date picker' - ); -}); - -// @todo This needs to be updated when upgrading to 1.13 to spy on the child -// sl-date-pickers rather than directly accessing bootstrap-datepicker values -test( 'Date pickers have unbound start and end dates by default', function( assert ) { - this.subject(); - - assert.equal( - this.$( '.sl-daterange-start-date input.date-picker' ).data().datepicker.o.startDate, - -Infinity, - 'Start date picker start date is unboundt' - ); - - assert.equal( - this.$( '.sl-daterange-start-date input.date-picker' ).data().datepicker.o.endDate, - Infinity, - 'Start date picker end date is unbound' - ); - - assert.equal( - this.$( '.sl-daterange-end-date input.date-picker' ).data().datepicker.o.startDate, - -Infinity, - 'End date picker start date is unbound' - ); - - assert.equal( - this.$( '.sl-daterange-end-date input.date-picker' ).data().datepicker.o.endDate, - Infinity, - 'End date picker end date is unbound' - ); -}); - -skip( 'Date pickers respects minDate', function() { - // waiting for 1.13 for a way to mock and spy on child components -}); - -skip( 'Date pickers respects maxDate', function() { - // waiting for 1.13 for a way to mock and spy on child components -}); - -skip( 'End date picker respects startDateValue over minDate due to earliestEndDate', function() { - // waiting for 1.13 for a way to mock and spy on child components -}); - -skip( 'Start date picker respects endDateValue over maxDate due to latestStartDate', function() { - // waiting for 1.13 for a way to mock and spy on child components -}); From 3608872a4849dc6d77e8790518d9eb774f89cfe1 Mon Sep 17 00:00:00 2001 From: J Corley Date: Thu, 28 Jan 2016 10:27:50 -0600 Subject: [PATCH 13/25] lint clean up --- addon/components/sl-calendar-day.js | 10 +--- addon/components/sl-calendar-month.js | 25 +------- addon/components/sl-calendar.js | 31 +++++----- addon/components/sl-date-picker.js | 58 +++++++++---------- addon/components/sl-date-range-picker.js | 4 +- .../templates/components/sl-calendar-day.hbs | 1 - .../components/sl-calendar-month.hbs | 1 - .../components/sl-calendar-test.js | 46 +++++++-------- 8 files changed, 74 insertions(+), 102 deletions(-) delete mode 100644 addon/templates/components/sl-calendar-day.hbs delete mode 100644 addon/templates/components/sl-calendar-month.hbs diff --git a/addon/components/sl-calendar-day.js b/addon/components/sl-calendar-day.js index 2b3bb57e..ab86f26b 100644 --- a/addon/components/sl-calendar-day.js +++ b/addon/components/sl-calendar-day.js @@ -1,5 +1,4 @@ import Ember from 'ember'; -//import layout from '../templates/components/sl-calendar-day'; /** * @module @@ -32,9 +31,6 @@ export default Ember.Component.extend({ 'day' ], - /** @type {Object} */ - //layout, - /** @type {String} */ tagName: 'td', @@ -52,11 +48,7 @@ export default Ember.Component.extend({ const content = this.get( 'content' ); const date = this.get( 'date' ); - //if ( content ) { - //if ( !this.get( 'restricted' ) ) { - this.sendAction( 'action', date, content ); - //} - //} + this.sendAction( 'action', date, content ); }, didInsertElement() { diff --git a/addon/components/sl-calendar-month.js b/addon/components/sl-calendar-month.js index 83da3ff7..6c0d9ef1 100755 --- a/addon/components/sl-calendar-month.js +++ b/addon/components/sl-calendar-month.js @@ -1,5 +1,4 @@ import Ember from 'ember'; -//import layout from '../templates/components/sl-calendar-month'; /** * @module @@ -51,19 +50,12 @@ export default Ember.Component.extend({ */ active: false, - /** - * The locale string to use for moment dates - * - * @type {String} - */ - //locale: 'en', - /** * The number of the month (1-12) * * @type {?Number} */ - month: null//, + month: null // ------------------------------------------------------------------------- // Observers @@ -71,19 +63,4 @@ export default Ember.Component.extend({ // ------------------------------------------------------------------------- // Methods - /** - * The short string name of the represented month - * - * @function - * @returns {String} - */ - /*shortName: Ember.computed( - 'month', - function() { - return window.moment([ 1, this.get( 'month' ) - 1 ]) - .locale( this.get( 'locale' ) ) - .format( 'MMM' ); - } - )*/ - }); diff --git a/addon/components/sl-calendar.js b/addon/components/sl-calendar.js index 95e62565..0700f4d6 100755 --- a/addon/components/sl-calendar.js +++ b/addon/components/sl-calendar.js @@ -351,7 +351,7 @@ export default Ember.Component.extend({ for ( let week = 0; week < weeksInMonthView.length; week++ ) { for ( let day = 0; day < weeksInMonthView[ week ].length; day++ ) { if ( Ember.get( weeksInMonthView[ week ][ day ], 'active' ) ) { - Ember.set( weeksInMonthView[ week ][ day ], 'active', false ) + Ember.set( weeksInMonthView[ week ][ day ], 'active', false ); } if ( selectedDate.isSame( Ember.get( weeksInMonthView[ week ][ day ], 'date' ), 'day' ) ) { @@ -371,7 +371,7 @@ export default Ember.Component.extend({ for ( let week = 0; week < weeksInMonthView.length; week++ ) { for ( let day = 0; day < weeksInMonthView[ week ].length; day++ ) { if ( Ember.get( weeksInMonthView[ week ][ day ], 'focused' ) ) { - Ember.set( weeksInMonthView[ week ][ day ], 'focused', false ) + Ember.set( weeksInMonthView[ week ][ day ], 'focused', false ); } if ( viewingDate.isSame( Ember.get( weeksInMonthView[ week ][ day ], 'date' ), 'day' ) ) { @@ -456,7 +456,7 @@ export default Ember.Component.extend({ title = viewingDate.format( 'YYYY' ); break; case View.YEARS: - let decadeMod = viewingDate.year() % 10; + const decadeMod = viewingDate.year() % 10; title = viewingDate.subtract( decadeMod, 'years' ).format( 'YYYY' ); title += ' - ' + viewingDate.add( 9, 'years' ).format( 'YYYY' ); break; @@ -567,7 +567,7 @@ export default Ember.Component.extend({ function() { const m = window.moment().locale( this.get( 'locale' ) ); - let weekdays = window.moment.weekdaysMin(); + const weekdays = window.moment.weekdaysMin(); for ( let i = m.localeData().firstDayOfWeek(); i > 0; i-- ) { weekdays.push( weekdays.shift() ); @@ -637,9 +637,9 @@ export default Ember.Component.extend({ * @returns {ember.Array} */ weeksInMonthView: Ember.computed( - //'contentDates', - //'showingYear', - //'selectedDate', + // 'contentDates', + // 'showingYear', + // 'selectedDate', 'fixedWeekCount', 'locale', 'selectConstraint', @@ -654,9 +654,11 @@ export default Ember.Component.extend({ const showingYear = viewingDate.year(); const selectConstraint = this.get( 'selectConstraint' ); - let firstOfMonth = window.moment( '01-' + showingMonth + '-' + showingYear, 'DD-MM-YYYY' ).locale( this.get( 'locale' ) ); - let firstDayOfWeek = firstOfMonth.localeData().firstDayOfWeek(); - let nextDayToShow = window.moment( firstOfMonth ).subtract( firstOfMonth.day(), 'days' ); + const firstOfMonth = window.moment( '01-' + showingMonth + '-' + showingYear, 'DD-MM-YYYY' ).locale( + this.get( 'locale' ) + ); + const firstDayOfWeek = firstOfMonth.localeData().firstDayOfWeek(); + const nextDayToShow = window.moment( firstOfMonth ).subtract( firstOfMonth.day(), 'days' ); // support firstDayOfWeek via locale nextDayToShow.add( firstDayOfWeek, 'days' ); @@ -669,7 +671,10 @@ export default Ember.Component.extend({ let weeksToShow = 6; if ( !this.get( 'fixedWeekCount' ) ) { - weeksToShow = window.moment( firstOfMonth ).add( 1, 'months' ).subtract( 1, 'days' ).diff( nextDayToShow, 'weeks' ) + 1; + weeksToShow = window.moment( firstOfMonth ).add( + 1, + 'months' + ).subtract( 1, 'days' ).diff( nextDayToShow, 'weeks' ) + 1; } for ( let i = 1; i <= weeksToShow; i++ ) { @@ -677,8 +682,8 @@ export default Ember.Component.extend({ for ( let k = 0; k < 7; k++ ) { let isActive = false; - let inNextMonth = nextDayToShow.isAfter( viewingDate, 'month' ); - let inPrevMonth = nextDayToShow.isBefore( viewingDate, 'month' ); + const inNextMonth = nextDayToShow.isAfter( viewingDate, 'month' ); + const inPrevMonth = nextDayToShow.isBefore( viewingDate, 'month' ); let isRestricted = false; if ( selectedDate ) { diff --git a/addon/components/sl-date-picker.js b/addon/components/sl-date-picker.js index 388befde..a9be6400 100755 --- a/addon/components/sl-date-picker.js +++ b/addon/components/sl-date-picker.js @@ -37,7 +37,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa inputBlurred() { this.trigger( 'focusOut' ); - //this.updateValue(); + // this.updateValue(); }, inputFocused() { @@ -67,7 +67,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa this._super( ...arguments ); this.set( 'hasFocus', true ); - //this.set( 'isOpen', true ); + // this.set( 'isOpen', true ); const losingFocus = this.get( 'losingFocus' ); Ember.run.cancel( losingFocus ); @@ -109,14 +109,14 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @type {Boolean} */ - //autoclose: true, + // autoclose: true, /** * Whether or not to show week numbers to the left of week rows * * @type {Boolean} */ - //calendarWeeks: false, + // calendarWeeks: false, /** * When true, displays a "Clear" button at the bottom of the datepicker @@ -126,7 +126,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @type {Boolean} */ - //clearBtn: false, + // clearBtn: false, /** * Days of the week that should be disabled @@ -150,7 +150,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @type {?Date|String} */ - //endDate: null, + // endDate: null, /** * Whether or not to force parsing of the input value when the picker is @@ -162,7 +162,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @type {Boolean} */ - //forceParse: true, + // forceParse: true, /** * The date format @@ -180,7 +180,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa formatString: Ember.computed( function() { - return this.get( 'format' ) || window.moment().localeData().longDateFormat( 'L' ); + return this.get( 'format' ) || window.moment().localeData().longDateFormat( 'L' ); } ), @@ -199,14 +199,14 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @type {?Array} */ - //inputs: null, + // inputs: null, /** * Whether or not to allow date navigation by arrow keys * * @type {Boolean} */ - //keyboardNavigation: true, + // keyboardNavigation: true, /** * The label text above the datepicker's input field @@ -220,14 +220,14 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @type {String} */ - //language: 'en', + // language: 'en', /** * Set a limit for the view mode; accepts "days", "months", or "years" * * @type {String} */ - //minViewMode: 'days', + // minViewMode: 'days', /** * Enable multidate picking @@ -241,7 +241,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @type {Boolean|Number} */ - //multidate: false, + // multidate: false, /** * A space-separated string for the popup's anchor position @@ -251,7 +251,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @type {String} */ - //orientation: 'auto', + // orientation: 'auto', /** * The placeholder text that the datepicker should show @@ -266,7 +266,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @type {?Date|String} */ - //startDate: null, + // startDate: null, /** * The view that the datepicker should show when it is opened; accepts @@ -274,7 +274,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @type {String} */ - //startView: 'month', + // startView: 'month', /** * When true or "linked", displays a "Today" button at the bottom of the @@ -285,28 +285,28 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @type {Boolean|String} */ - //todayBtn: false, + // todayBtn: false, /** * Whether to highlight the current date or not * * @type {Boolean} */ - //todayHighlight: false, + // todayHighlight: false, /** * The date either selected by the datepicker or entered by the user * * @type {?String} */ - //value: null, + // value: null, /** * Day of the week to start on; 0 (Sunday) to 6 (Saturday) * * @type {Number} */ - //weekStart: 0, + // weekStart: 0, locale: 'en', @@ -329,7 +329,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa checkInput() { let value = this.get( 'value' ); - //const format = this.get( 'format' ); + // const format = this.get( 'format' ); const parseFormats = this.get( 'parseFormats' ); const selectConstraint = this.get( 'selectConstraint' ); @@ -337,13 +337,13 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa return; } - //console.log( 'from value observer: ', this.get( 'value' ) ); + // console.log( 'from value observer: ', this.get( 'value' ) ); - value = value.replace(/\W+/g, "-"); + value = value.replace( /\W+/g, "-" ); const date = window.moment( value, parseFormats, this.get( 'locale' ), true ); - //console.log( 'date entered: ', date.format( format ) ); - //return; + // console.log( 'date entered: ', date.format( format ) ); + // return; if ( selectConstraint.start ) { if ( date.isBefore( selectConstraint.start ) ) { return; @@ -370,9 +370,9 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa const localeData = window.moment().localeData(); formats.push( - localeData.longDateFormat('L').replace(/\W+/g, "-"), - localeData.longDateFormat('LL').replace(/\W+/g, "-"), - localeData.longDateFormat('L').replace('DD', 'D').replace('MM', 'M').replace(/\W+/g, "-") + localeData.longDateFormat( 'L' ).replace( /\W+/g, "-" ), + localeData.longDateFormat( 'LL' ).replace( /\W+/g, "-" ), + localeData.longDateFormat( 'L' ).replace( 'DD', 'D' ).replace( 'MM', 'M' ).replace( /\W+/g, "-" ) ); return formats; @@ -390,7 +390,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa const selectedDate = this.get( 'selectedDate' ); const format = this.get( 'formatString' ); - if ( selectedDate === null ) { + if ( null === selectedDate ) { return; } diff --git a/addon/components/sl-date-range-picker.js b/addon/components/sl-date-range-picker.js index 3d595bb0..8c03b591 100755 --- a/addon/components/sl-date-range-picker.js +++ b/addon/components/sl-date-range-picker.js @@ -39,7 +39,7 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { * * @type {?String} */ - //endDateValue: null, + // endDateValue: null, /** * The string format for date values @@ -53,7 +53,7 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { * * @type {?String} */ - //startDateValue: null, + // startDateValue: null, label: null, diff --git a/addon/templates/components/sl-calendar-day.hbs b/addon/templates/components/sl-calendar-day.hbs deleted file mode 100644 index 9737f608..00000000 --- a/addon/templates/components/sl-calendar-day.hbs +++ /dev/null @@ -1 +0,0 @@ -{{day}} \ No newline at end of file diff --git a/addon/templates/components/sl-calendar-month.hbs b/addon/templates/components/sl-calendar-month.hbs deleted file mode 100644 index d4e68439..00000000 --- a/addon/templates/components/sl-calendar-month.hbs +++ /dev/null @@ -1 +0,0 @@ -{{shortName}} \ No newline at end of file diff --git a/tests/integration/components/sl-calendar-test.js b/tests/integration/components/sl-calendar-test.js index f53faf77..2cc2467e 100755 --- a/tests/integration/components/sl-calendar-test.js +++ b/tests/integration/components/sl-calendar-test.js @@ -149,7 +149,7 @@ test( 'Next and Previous buttons have appropriate classes', function( assert ) { }); test( 'Check for classes set on items outside of range in picker', function( assert ) { - this.set( 'viewingDate', window.moment( [2015, 1, 1] ) ); + this.set( 'viewingDate', window.moment( [ 2015, 1, 1 ] ) ); this.set( 'viewMode', 'days' ); this.render( hbs` @@ -243,7 +243,7 @@ test( 'Check for classes set on items outside of range in picker', function( ass }); test( 'Setting viewingDate modifies the view correctly', function( assert ) { - this.set( 'viewingDate', window.moment( [2025, 3, 1] ) ); + this.set( 'viewingDate', window.moment( [ 2025, 3, 1 ] ) ); this.render( hbs` {{sl-calendar viewingDate=viewingDate}} @@ -288,8 +288,8 @@ skip( 'Setting dateValuePath modifies the view correctly', function( assert ) { }); test( 'selectedDate is set correctly', function( assert ) { - this.set( 'selectedDate', window.moment( [2015, 1, 15] ) ); - this.set( 'viewingDate', window.moment( [2015, 1, 1] ) ); + this.set( 'selectedDate', window.moment( [ 2015, 1, 15 ] ) ); + this.set( 'viewingDate', window.moment( [ 2015, 1, 1 ] ) ); this.render( hbs` {{sl-calendar @@ -311,13 +311,13 @@ test( 'selectedDate is set correctly', function( assert ) { assert.strictEqual( this.$( '>:first-child' ).find( 'td.selected' ).text().trim(), - "15", + '15', 'Proper date is set as selected' ); }); test( 'Setting locale to Spanish modifies the view correctly', function( assert ) { - this.set( 'viewingDate', window.moment( [2022, 8, 1] ) ); + this.set( 'viewingDate', window.moment( [ 2022, 8, 1 ] ) ); this.render( hbs` {{sl-calendar @@ -436,8 +436,8 @@ skip( 'Action passes through expected objects in content array', function( asser }); test( 'Setting viewMode modifies the view correctly', function( assert ) { - this.set( 'selectedDate', window.moment( [2015, 1, 15] ) ); - this.set( 'viewingDate', window.moment( [2015, 1, 1] ) ); + this.set( 'selectedDate', window.moment( [ 2015, 1, 15 ] ) ); + this.set( 'viewingDate', window.moment( [ 2015, 1, 1 ] ) ); this.set( 'viewMode', 'days' ); this.render( hbs` @@ -450,7 +450,7 @@ test( 'Setting viewMode modifies the view correctly', function( assert ) { assert.strictEqual( this.$( '>:first-child' ).find( '.selected' ).text().trim(), - "15", + '15', '"viewMode" of days renders' ); @@ -458,7 +458,7 @@ test( 'Setting viewMode modifies the view correctly', function( assert ) { assert.strictEqual( this.$( '>:first-child' ).find( '.selected' ).text().trim(), - "Feb", + 'Feb', '"viewMode" of months renders' ); @@ -466,13 +466,13 @@ test( 'Setting viewMode modifies the view correctly', function( assert ) { assert.strictEqual( this.$( '>:first-child' ).find( '.selected' ).text().trim(), - "2015", + '2015', '"viewMode" of years renders' ); }); test( 'Navigating Forward and Backward by Month', function( assert ) { - this.set( 'viewingDate', window.moment( [2015, 8, 1] ) ); + this.set( 'viewingDate', window.moment( [ 2015, 8, 1 ] ) ); this.render( hbs` {{sl-calendar @@ -502,7 +502,7 @@ test( 'Navigating Forward and Backward by Month', function( assert ) { 'The previous month is set correctly' ); - this.set( 'viewingDate', window.moment( [2015, 11, 1] ) ); + this.set( 'viewingDate', window.moment( [ 2015, 11, 1 ] ) ); assert.strictEqual( this.$( '>:first-child' ).find( '.calendar-controls a' ).text().trim(), @@ -528,7 +528,7 @@ test( 'Navigating Forward and Backward by Month', function( assert ) { }); test( 'Navigating Forward and Backward by Year', function( assert ) { - this.set( 'viewingDate', window.moment( [2015, 8, 1] ) ); + this.set( 'viewingDate', window.moment( [ 2015, 8, 1 ] ) ); this.set( 'viewMode', 'months' ); this.render( hbs` @@ -562,7 +562,7 @@ test( 'Navigating Forward and Backward by Year', function( assert ) { }); test( 'Navigating Forward and Backward by Decade', function( assert ) { - this.set( 'viewingDate', window.moment( [2015, 8, 1] ) ); + this.set( 'viewingDate', window.moment( [ 2015, 8, 1 ] ) ); this.set( 'viewMode', 'years' ); this.render( hbs` @@ -657,7 +657,7 @@ skip( 'When Locked, interacting with the view is not Possible', function( assert }); test( 'Changing viewMode by View Switcher', function( assert ) { - this.set( 'viewingDate', window.moment( [2015, 8, 1] ) ); + this.set( 'viewingDate', window.moment( [ 2015, 8, 1 ] ) ); this.set( 'viewMode', 'days' ); this.render( hbs` @@ -691,8 +691,8 @@ test( 'Changing viewMode by View Switcher', function( assert ) { }); test( 'Changing viewMode by Selection', function( assert ) { - this.set( 'viewingDate', window.moment( [2015, 8, 1] ) ); - this.set( 'selectedDate', window.moment( [2015, 8, 1] ) ); + this.set( 'viewingDate', window.moment( [ 2015, 8, 1 ] ) ); + this.set( 'selectedDate', window.moment( [ 2015, 8, 1 ] ) ); this.set( 'viewMode', 'years' ); this.render( hbs` @@ -727,7 +727,7 @@ test( 'Changing viewMode by Selection', function( assert ) { }); test( 'All Days are Displayed in Order', function( assert ) { - this.set( 'viewingDate', window.moment( [2015, 0, 1] ) ); + this.set( 'viewingDate', window.moment( [ 2015, 0, 1 ] ) ); this.render( hbs` {{sl-calendar @@ -735,7 +735,7 @@ test( 'All Days are Displayed in Order', function( assert ) { }} ` ); - let daysString = ""; + let daysString = ''; this.$( '>:first-child' ).find( 'td.day' ).each( function() { daysString += $( this ).text().trim(); @@ -756,7 +756,7 @@ test( 'All Twelve Months are Displayed in Order', function( assert ) { }} ` ); - let monthsString = ""; + let monthsString = ''; this.$( '>:first-child' ).find( 'td.month' ).each( function() { monthsString += $( this ).text().trim(); @@ -770,7 +770,7 @@ test( 'All Twelve Months are Displayed in Order', function( assert ) { }); test( 'Twelve Years are Displayed in Order', function( assert ) { - this.set( 'viewingDate', window.moment( [2022, 0, 1] ) ); + this.set( 'viewingDate', window.moment( [ 2022, 0, 1 ] ) ); this.render( hbs` {{sl-calendar @@ -779,7 +779,7 @@ test( 'Twelve Years are Displayed in Order', function( assert ) { }} ` ); - let yearsString = ""; + let yearsString = ''; this.$( '>:first-child' ).find( 'td.year' ).each( function() { yearsString += $( this ).text().trim(); From 8f161a3fe3d5aed231d0b127619dab247ad7f70a Mon Sep 17 00:00:00 2001 From: J Corley Date: Fri, 29 Jan 2016 09:50:56 -0600 Subject: [PATCH 14/25] Added integration test for sl-calendar-day. Added integration test for sl-calendar-month. Added integration test for sl-calendar-year. Cleaned up unit test for sl-calendar-day. Cleaned up unit test for sl-calendar-month. Cleaned up unit test for sl-calendar-year. ** CALENDAR DAY ** Alphabetically organized properties. ** DATE PICKER ** Added autoClose property. Changed startView to viewMode and hooked it up. Removed commented properties (unused). Alphabetically organized properties. --- addon/components/sl-calendar-day.js | 14 +- addon/components/sl-date-picker.js | 180 ++----- addon/templates/components/sl-date-picker.hbs | 1 + .../components/sl-calendar-day-test.js | 110 ++++ .../components/sl-calendar-month-test.js | 48 ++ .../components/sl-calendar-year-test.js | 70 +++ tests/unit/components/sl-calendar-day-test.js | 123 +++-- .../unit/components/sl-calendar-month-test.js | 32 +- tests/unit/components/sl-calendar-test.js | 26 +- .../unit/components/sl-calendar-year-test.js | 27 +- tests/unit/components/sl-date-picker-test.js | 480 ++---------------- .../components/sl-date-range-picker-test.js | 42 +- 12 files changed, 448 insertions(+), 705 deletions(-) create mode 100644 tests/integration/components/sl-calendar-day-test.js create mode 100644 tests/integration/components/sl-calendar-month-test.js create mode 100644 tests/integration/components/sl-calendar-year-test.js diff --git a/addon/components/sl-calendar-day.js b/addon/components/sl-calendar-day.js index ab86f26b..5c299615 100644 --- a/addon/components/sl-calendar-day.js +++ b/addon/components/sl-calendar-day.js @@ -54,7 +54,7 @@ export default Ember.Component.extend({ didInsertElement() { this._super( ...arguments ); - this.focus(); + //this.focus(); }, // ------------------------------------------------------------------------- @@ -67,6 +67,8 @@ export default Ember.Component.extend({ */ active: false, + ariaRole: 'gridcell', + /** * The various data representing the day (created and passed in through * sl-calendar) @@ -75,6 +77,10 @@ export default Ember.Component.extend({ */ content: null, + date: null, + + focused: false, + /** * Whether the calendar day this cell represents is part of the next month * in the primary calendar view @@ -91,12 +97,6 @@ export default Ember.Component.extend({ */ old: false, - date: null, - - focused: false, - - ariaRole: 'gridcell', - restricted: false, // ------------------------------------------------------------------------- diff --git a/addon/components/sl-date-picker.js b/addon/components/sl-date-picker.js index a9be6400..2d69399f 100755 --- a/addon/components/sl-date-picker.js +++ b/addon/components/sl-date-picker.js @@ -3,6 +3,9 @@ import ComponentInputId from '../mixins/sl-component-input-id'; import TooltipEnabled from '../mixins/sl-tooltip-enabled'; import Namespace from '../mixins/sl-namespace'; import layout from '../templates/components/sl-date-picker'; +import { + View as View +} from './sl-calendar'; /** * @module @@ -55,6 +58,11 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa selectDate( date ) { this.selectDate( date ); + + if ( this.get( 'autoClose' ) ) { + this.set( 'hasFocus', false ); + } + this.sendAction( 'action', date ); } @@ -109,34 +117,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @type {Boolean} */ - // autoclose: true, - - /** - * Whether or not to show week numbers to the left of week rows - * - * @type {Boolean} - */ - // calendarWeeks: false, - - /** - * When true, displays a "Clear" button at the bottom of the datepicker - * - * If "autoclose" is also set to true, this button will also close - * the datepicker. - * - * @type {Boolean} - */ - // clearBtn: false, - - /** - * Days of the week that should be disabled - * - * Values are 0 (Sunday) to 6 (Saturday). Multiple values should be - * comma-separated. - * - * @type {Array|String} - */ - daysOfWeekDisabled: [], + autoClose: true, /** * When true, the input field is disabled and the datepicker will never display @@ -145,13 +126,6 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa */ disabled: false, - /** - * The latest date that may be selected; all later dates will be disabled - * - * @type {?Date|String} - */ - // endDate: null, - /** * Whether or not to force parsing of the input value when the picker is * closed @@ -178,148 +152,46 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa */ format: null, - formatString: Ember.computed( - function() { - return this.get( 'format' ) || window.moment().localeData().longDateFormat( 'L' ); - } - ), + hasFocus: false, /** * The help text below the datepicker * - * @type {String} + * @type {?String} */ helpText: null, - /** - * A list of inputs to be used in a range picker - * - * The inputs will be attached to the selected element. Allows for - * explicitly creating a range picker on a non-standard element. - * - * @type {?Array} - */ - // inputs: null, - - /** - * Whether or not to allow date navigation by arrow keys - * - * @type {Boolean} - */ - // keyboardNavigation: true, - /** * The label text above the datepicker's input field * - * @type {String} + * @type {?String} */ label: null, - /** - * The IETF code of the language to use for month and day names - * - * @type {String} - */ - // language: 'en', - - /** - * Set a limit for the view mode; accepts "days", "months", or "years" - * - * @type {String} - */ - // minViewMode: 'days', - - /** - * Enable multidate picking - * - * Each date in month view acts as a toggle button, keeping track of which - * dates the user has selected in order. If a number is given, the picker - * will limit how many dates can be selected to that number, dropping the - * oldest dates from the list when the number is exceeded. true equates to - * no limit. The input’s value (if present) is set to a string generated by - * joining the dates, formatted, with multidateSeparator. - * - * @type {Boolean|Number} - */ - // multidate: false, + locale: 'en', - /** - * A space-separated string for the popup's anchor position - * - * Consists of one or two of "left" or "right", "top" or "bottom", - * and "auto" (may be omitted). - * - * @type {String} - */ - // orientation: 'auto', + losingFocus: false, /** - * The placeholder text that the datepicker should show + * The placeholder text that the datepicker input should show * * @type {?String} */ placeholder: null, - /** - * The earliest date that may be selected; all earlier dates will - * be disabled - * - * @type {?Date|String} - */ - // startDate: null, - - /** - * The view that the datepicker should show when it is opened; accepts - * "month", "year", or "decade" - * - * @type {String} - */ - // startView: 'month', - - /** - * When true or "linked", displays a "Today" button at the bottom of the - * datepicker to select the current date - * - * If true, the "Today" button will only move the current date into view. - * If "linked", the current date will also be selected. - * - * @type {Boolean|String} - */ - // todayBtn: false, - - /** - * Whether to highlight the current date or not - * - * @type {Boolean} - */ - // todayHighlight: false, + selectConstraint: { + start: null, + end: null + }, - /** - * The date either selected by the datepicker or entered by the user - * - * @type {?String} - */ - // value: null, + selectedDate: null, /** - * Day of the week to start on; 0 (Sunday) to 6 (Saturday) + * The calendar view when open * - * @type {Number} + * @type {String} */ - // weekStart: 0, - - locale: 'en', - - selectedDate: null, - - hasFocus: false, - - losingFocus: false, - - selectConstraint: { - start: null, - end: null - }, + viewMode: View.DAYS, // ------------------------------------------------------------------------- // Observers @@ -363,6 +235,12 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa this.set( 'selectedDate', date ); }, + formatString: Ember.computed( + function() { + return this.get( 'format' ) || window.moment().localeData().longDateFormat( 'L' ); + } + ), + parseFormats: Ember.computed( 'locale', function() { diff --git a/addon/templates/components/sl-date-picker.hbs b/addon/templates/components/sl-date-picker.hbs index f944d994..59478e74 100644 --- a/addon/templates/components/sl-date-picker.hbs +++ b/addon/templates/components/sl-date-picker.hbs @@ -24,6 +24,7 @@ locale=locale selectedDate=selectedDate viewingDate=viewingDate + viewMode=viewMode selectConstraint=selectConstraint }} diff --git a/tests/integration/components/sl-calendar-day-test.js b/tests/integration/components/sl-calendar-day-test.js new file mode 100644 index 00000000..bc4728e7 --- /dev/null +++ b/tests/integration/components/sl-calendar-day-test.js @@ -0,0 +1,110 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('sl-calendar-day', 'Integration | Component | sl calendar day', { + integration: true +}); + +const template = hbs` + {{#sl-calendar-day}} + 5 + {{/sl-calendar-day}} +`; + +test( 'Default rendered state', function( assert ) { + this.render( template ); + + assert.ok( + this.$( '>:first-child' ).hasClass( 'day' ), + 'Has class "day"' + ); +}); + +test( 'Selected class is present when in active state', function( assert ) { + this.render( hbs` + {{sl-calendar-day active=true}} + ` ); + + assert.ok( + this.$( '>:first-child' ).hasClass( 'selected' ), + 'Has class "selected" when active' + ); +}); + +test( 'New class is present when new is true', function( assert ) { + this.render( hbs` + {{sl-calendar-day new=true}} + ` ); + + assert.ok( + this.$( '>:first-child' ).hasClass( 'new' ), + 'Has class "new" when new' + ); +}); + +test( 'Old class is present when old is true', function( assert ) { + this.render( hbs` + {{sl-calendar-day old=true}} + ` ); + + assert.ok( + this.$( '>:first-child' ).hasClass( 'old' ), + 'Has class "old" when old' + ); +}); + +test( 'Today class is present when isToday is true', function( assert ) { + this.render( hbs` + {{sl-calendar-day isToday=true}} + ` ); + + assert.ok( + this.$( '>:first-child' ).hasClass( 'today' ), + 'Has class "today" when isToday' + ); +}); + +test( 'Disabled class is present when in restricted state', function( assert ) { + this.render( hbs` + {{sl-calendar-day restricted=true}} + ` ); + + assert.ok( + this.$( '>:first-child' ).hasClass( 'disabled' ), + 'Has class "disabled" when restricted' + ); +}); + +test( 'Default action is triggered when element is clicked', function( assert ) { + assert.ok( + false + ); +}); + +test( 'ariaRole', function( assert ) { + assert.ok( + false + ); +}); + +test( 'ariaSelected', function( assert ) { + assert.ok( + false + ); +}); + +test( 'tabIndex', function( assert ) { + assert.ok( + false + ); +}); + +test( 'Content is yielded', function( assert ) { + this.render( template ); + + assert.strictEqual( + this.$( '>:first-child' ).text().trim(), + '5', + 'Content yields successfully' + ); +}); diff --git a/tests/integration/components/sl-calendar-month-test.js b/tests/integration/components/sl-calendar-month-test.js new file mode 100644 index 00000000..b333e27f --- /dev/null +++ b/tests/integration/components/sl-calendar-month-test.js @@ -0,0 +1,48 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('sl-calendar-month', 'Integration | Component | sl calendar month', { + integration: true +}); + +const template = hbs` + {{#sl-calendar-month}} + June + {{/sl-calendar-month}} +`; + +test( 'Default rendered state', function( assert ) { + this.render( template ); + + assert.ok( + this.$( '>:first-child' ).hasClass( 'month' ), + 'Has class "month"' + ); +}); + +test( 'Selected class is present when in active state', function( assert ) { + this.render( hbs` + {{sl-calendar-month active=true}} + ` ); + + assert.ok( + this.$( '>:first-child' ).hasClass( 'selected' ), + 'Has class "selected" when active' + ); +}); + +test( 'Default action is triggered when element is clicked', function( assert ) { + assert.ok( + false + ); +}); + +test( 'Content is yielded', function( assert ) { + this.render( template ); + + assert.strictEqual( + this.$( '>:first-child' ).text().trim(), + 'June', + 'Content yields successfully' + ); +}); diff --git a/tests/integration/components/sl-calendar-year-test.js b/tests/integration/components/sl-calendar-year-test.js new file mode 100644 index 00000000..a07e9be1 --- /dev/null +++ b/tests/integration/components/sl-calendar-year-test.js @@ -0,0 +1,70 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('sl-calendar-year', 'Integration | Component | sl calendar year', { + integration: true +}); + +const template = hbs` + {{#sl-calendar-year}} + 1999 + {{/sl-calendar-year}} +`; + +test( 'Default rendered state', function( assert ) { + this.render( template ); + + assert.ok( + this.$( '>:first-child' ).hasClass( 'year' ), + 'Has class "year"' + ); +}); + +test( 'Selected class is present when in active state', function( assert ) { + this.render( hbs` + {{sl-calendar-year active=true}} + ` ); + + assert.ok( + this.$( '>:first-child' ).hasClass( 'selected' ), + 'Has class "selected" when active' + ); +}); + +test( 'New class is present when new is true', function( assert ) { + this.render( hbs` + {{sl-calendar-year new=true}} + ` ); + + assert.ok( + this.$( '>:first-child' ).hasClass( 'new' ), + 'Has class "new" when new' + ); +}); + +test( 'Old class is present when old is true', function( assert ) { + this.render( hbs` + {{sl-calendar-year old=true}} + ` ); + + assert.ok( + this.$( '>:first-child' ).hasClass( 'old' ), + 'Has class "old" when old' + ); +}); + +test( 'Default action is triggered when element is clicked', function( assert ) { + assert.ok( + false + ); +}); + +test( 'Content is yielded', function( assert ) { + this.render( template ); + + assert.strictEqual( + this.$( '>:first-child' ).text().trim(), + '1999', + 'Content yields successfully' + ); +}); diff --git a/tests/unit/components/sl-calendar-day-test.js b/tests/unit/components/sl-calendar-day-test.js index ea3608b6..135a7a48 100644 --- a/tests/unit/components/sl-calendar-day-test.js +++ b/tests/unit/components/sl-calendar-day-test.js @@ -5,88 +5,59 @@ moduleForComponent( 'sl-calendar-day', 'Unit | Component | sl calendar day', { unit: true }); -test( 'Default state of calendar-day is not active, new or old', function( assert ) { +test( 'Default property values', function( assert ) { const component = this.subject(); assert.strictEqual( component.get( 'active' ), false, - 'Default component is not active' + 'active is false by default' ); assert.strictEqual( - this.$().hasClass( 'selected' ), - false, - 'Default component does not have "selected" class' + component.get( 'ariaRole' ), + "gridcell", + 'ariaRole is "gridcell" by default' ); assert.strictEqual( - component.get( 'new' ), - false, - 'Default component is not "new"' + component.get( 'content' ), + null, + 'content is null by default' ); assert.strictEqual( - this.$().hasClass( 'new' ), - false, - 'Default component does not have "new" class' + component.get( 'date' ), + null, + 'date is null by default' ); assert.strictEqual( - component.get( 'old' ), + component.get( 'focused' ), false, - 'Default component is not "old"' + 'focused is false by default' ); assert.strictEqual( - this.$().hasClass( 'old' ), - false, - 'Default component does not have "old" class' - ); -}); - -test( 'Active state is applied correctly', function( assert ) { - const component = this.subject({ active: true }); - - assert.ok( - component.get( 'active' ), - 'Component is set to active state' - ); - - assert.ok( - this.$().hasClass( 'selected' ), - 'Component element has class "selected"' - ); -}); - -test( 'New state is applied correctly', function( assert ) { - const component = this.subject({ 'new': true }); - - assert.ok( component.get( 'new' ), - 'Component is set to new state' - ); - - assert.ok( - this.$().hasClass( 'new' ), - 'Component element has class "new"' + false, + 'new is false by default' ); -}); - -test( 'Old state is applied correctly', function( assert ) { - const component = this.subject({ old: true }); - assert.ok( + assert.strictEqual( component.get( 'old' ), - 'Component is set to old state' + false, + 'old is false by default' ); - assert.ok( - this.$().hasClass( 'old' ), - 'Component element has class "old"' + assert.strictEqual( + component.get( 'restricted' ), + false, + 'restricted is false by default' ); }); +//need to re-visit this one test( 'Action bindings sends action with expected day content', function( assert ) { assert.expect( 1 ); @@ -112,3 +83,51 @@ test( 'Action bindings sends action with expected day content', function( assert this.$().trigger( 'click' ); }); + +test( 'Observer keys are correct', function( assert ) { + const component = this.subject(); + + const focusKeys = [ + 'tabIndex' + ]; + + assert.deepEqual( + component.focus.__ember_observes__, + focusKeys, + 'Observer keys are correct for focus()' + ); +}); + +test( 'Dependent keys are correct', function( assert ) { + const component = this.subject(); + + const ariaSelectedDependentKeys = [ + 'active' + ]; + + const isTodayDependentKeys = [ + 'date' + ]; + + const tabIndexDependentKeys = [ + 'focused' + ]; + + assert.deepEqual( + component.ariaSelected._dependentKeys, + ariaSelectedDependentKeys, + 'Dependent keys are correct for ariaSelected()' + ); + + assert.deepEqual( + component.isToday._dependentKeys, + isTodayDependentKeys, + 'Dependent keys are correct for isToday()' + ); + + assert.deepEqual( + component.tabIndex._dependentKeys, + tabIndexDependentKeys, + 'Dependent keys are correct for tabIndex()' + ); +}); diff --git a/tests/unit/components/sl-calendar-month-test.js b/tests/unit/components/sl-calendar-month-test.js index 48da715b..7c726767 100644 --- a/tests/unit/components/sl-calendar-month-test.js +++ b/tests/unit/components/sl-calendar-month-test.js @@ -7,43 +7,23 @@ moduleForComponent( } ); -test( 'Default state is inactive', function( assert ) { +test( 'Default property values', function( assert ) { const component = this.subject(); assert.strictEqual( component.get( 'active' ), false, - 'Component is not active' + 'active is false by default' ); assert.strictEqual( - this.$().hasClass( 'selected' ), - false, - 'Component does not have "selected" class' - ); -}); - -test( 'Component has "month" class by default', function( assert ) { - assert.ok( - this.$().hasClass( 'month' ), - '"month" class is present' - ); -}); - -test( 'Active state is set correctly', function( assert ) { - const component = this.subject({ active: true }); - - assert.ok( - component.get( 'active' ), - 'Component is active' - ); - - assert.ok( - this.$().hasClass( 'selected' ), - '"selected" class is present' + component.get( 'month' ), + null, + 'month is null by default' ); }); +//need to re-visit this one test( 'Action binding sends action with month', function( assert ) { this.subject({ action: 'test', diff --git a/tests/unit/components/sl-calendar-test.js b/tests/unit/components/sl-calendar-test.js index a6be8acc..2af84556 100755 --- a/tests/unit/components/sl-calendar-test.js +++ b/tests/unit/components/sl-calendar-test.js @@ -19,76 +19,76 @@ test( 'Default property values are set correctly', function( assert ) { assert.deepEqual( component.get( 'content' ), [], - 'content: []' + 'content is [] by default' ); assert.strictEqual( component.get( 'dateValuePath' ), 'date', - 'dateValuePath: "date"' + 'dateValuePath is "date" by default' ); assert.ok( component.get( 'fixedWeekCount' ), - 'fixedWeekCount: true' + 'fixedWeekCount is true by default' ); assert.ok( component.get( 'focusable' ), - 'focusable: true' + 'focusable is true by default' ); assert.notOk( component.get( 'hasFocus' ), - 'hasFocus: false' + 'hasFocus is false by default' ); assert.strictEqual( component.get( 'locale' ), 'en', - 'locale: "en"' + 'locale is "en" by default' ); assert.strictEqual( component.get( 'locked' ), false, - 'locked: false' + 'locked is false by default' ); assert.strictEqual( component.get( 'selectConstraint' ), true, - 'selectConstraint: ?' + 'selectConstraint is ? by default' ); assert.strictEqual( component.get( 'selectedDate' ), null, - 'selectedDate: null' + 'selectedDate is null by default' ); assert.strictEqual( component.get( 'showingMonth' ), null, - 'showingMonth: null' + 'showingMonth is null by default' ); assert.strictEqual( component.get( 'today' ), null, - 'today: null' + 'today is null by default' ); assert.strictEqual( component.get( 'viewingDate' ), null, - 'viewingDate: null' + 'viewingDate is null by default' ); assert.strictEqual( component.get( 'viewMode' ), 'days', - 'viewMode: "days"' + 'viewMode is "days" by default' ); }); diff --git a/tests/unit/components/sl-calendar-year-test.js b/tests/unit/components/sl-calendar-year-test.js index 254947b9..c4272041 100644 --- a/tests/unit/components/sl-calendar-year-test.js +++ b/tests/unit/components/sl-calendar-year-test.js @@ -4,46 +4,29 @@ moduleForComponent( 'sl-calendar-year', 'Unit | Component | sl calendar year', { unit: true }); -test( 'Default state is not active, new, or old', function( assert ) { +test( 'Default property values', function( assert ) { const component = this.subject(); assert.strictEqual( component.get( 'active' ), false, - 'Default component is not active' + 'active is false by default' ); assert.strictEqual( component.get( 'new' ), false, - 'Default component is not in new state' + 'new is false by default' ); assert.strictEqual( component.get( 'old' ), false, - 'Default component is not in old state' - ); - - assert.strictEqual( - this.$().hasClass( 'active' ), - false, - 'Default rendered component does not have class "active"' - ); - - assert.strictEqual( - this.$().hasClass( 'new' ), - false, - 'Default rendered component does not have class "new"' - ); - - assert.strictEqual( - this.$().hasClass( 'old' ), - false, - 'Default rendered component does not have class "old"' + 'old is false by default' ); }); +//need to re-visit this one test( 'Click event sends action with year value', function( assert ) { assert.expect( 1 ); diff --git a/tests/unit/components/sl-date-picker-test.js b/tests/unit/components/sl-date-picker-test.js index c9faab8f..fb64ae65 100755 --- a/tests/unit/components/sl-date-picker-test.js +++ b/tests/unit/components/sl-date-picker-test.js @@ -23,456 +23,64 @@ test( 'Expected Mixins are present', function( assert ) { test( 'Default properties are set correctly', function( assert ) { const component = this.subject(); - assert.equal( - component.get( 'autoclose' ), + assert.strictEqual( + component.get( 'autoClose' ), true, - '"autoclose" default vaue is correct' - ); - - assert.equal( - component.get( 'calendarWeeks' ), - false, - '"calendarWeeks" default value is correct' + 'autoClose is true by default' ); - assert.equal( - component.get( 'clearBtn' ), - false, - '"clearBtn" default value is correct' - ); - - assert.deepEqual( - component.get( 'daysOfWeekDisabled' ), - [], - '"daysOfWeekDisabled" default value is correct' - ); - - assert.equal( + assert.strictEqual( component.get( 'disabled' ), false, - '"disabled" default value is correct' + 'disabled is false by default' ); - assert.equal( - component.get( 'endDate' ), + assert.strictEqual( + component.get( 'format' ), null, - '"endDate" default value is correct' + 'format is null by default' ); - assert.equal( - component.get( 'forceParse' ), - true, - '"forceParse" default value is correct' - ); - - assert.equal( - component.get( 'format' ), - 'mm/dd/yyyy', - '"forceParse" default value is correct' + assert.strictEqual( + component.get( 'hasFocus' ), + false, + 'hasFocus is false by default' ); - assert.equal( + assert.strictEqual( component.get( 'helpText' ), null, - '"helpText" default value is correct' - ); - - assert.equal( - component.get( 'inputs' ), - null, - '"inputs" default value is correct' - ); - - assert.equal( - component.get( 'keyboardNavigation' ), - true, - '"keyboardNavigation" default value is correct' + 'helpText is null by default' ); - assert.equal( + assert.strictEqual( component.get( 'label' ), null, - '"label" default value is correct' + 'label is null by default' ); - assert.equal( - component.get( 'language' ), + assert.strictEqual( + component.get( 'locale' ), 'en', - '"language" default value is correct' + 'locale is "en" by default' ); - assert.equal( - component.get( 'minViewMode' ), - 'days', - '"minViewMode" default value is correct' - ); - - assert.equal( - component.get( 'multidate' ), - false, - '"multidate" default value is correct' - ); - - assert.equal( - component.get( 'orientation' ), - 'auto', - '"orientation" default value is correct' - ); - - assert.equal( + assert.strictEqual( component.get( 'placeholder' ), null, - '"placeholder" default value is correct' - ); - - assert.equal( - component.get( 'startDate' ), - null, - '"startDate" default value is correct' - ); - - assert.equal( - component.get( 'startView' ), - 'month', - '"startView" default value is correct' - ); - - assert.equal( - component.get( 'todayBtn' ), - false, - '"todayBtn" default value is correct' - ); - - assert.equal( - component.get( 'todayHighlight' ), - false, - '"todayHighlight" default value is correct' - ); - - assert.equal( - component.get( 'value' ), - null, - '"value" default value is correct' - ); - - assert.equal( - component.get( 'weekStart' ), - 0, - '"weekStart" default value is correct' - ); -}); - -test( 'Event handlers are registered and unregistered', function( assert ) { - const spyOn = sinon.spy( Ember.$.fn, 'on' ); - const spyOff = sinon.spy( Ember.$.fn, 'off' ); - const component = this.subject(); - const input = this.$( 'input.date-picker' ); - - const matchElement = sinon.match( ( value ) => { - return value.get( 0 ) === input.get( 0 ); - }); - - this.render(); - - spyOn.reset(); - - component.trigger( 'didInsertElement' ); - - assert.ok( - spyOn.calledWith( component.namespaceEvent( 'changeDate' ) ), - 'on() was called with namespaced changeDate event' + 'placeholder is null by default' ); - assert.ok( - spyOn.calledOn( matchElement ), - 'on() was called on expected input' - ); - - spyOff.reset(); - - component.trigger( 'willClearRender' ); - - assert.ok( - spyOff.calledWith( component.namespaceEvent( 'changeDate' ) ), - 'off() was called with namespaced changeDate event' - ); - - assert.ok( - spyOff.calledOn( matchElement ), - 'off() was called on expected input' - ); - - Ember.$.fn.on.restore(); - Ember.$.fn.off.restore(); -}); - -test( 'Changing "autoclose" to non default value works as expected', function( assert ) { - const autoclose = false; - - const component = this.subject({ - autoclose: autoclose - }); - - const options = component.get( 'options' ); - - assert.strictEqual( - options.autoclose, - autoclose - ); -}); - -test( 'Changing "calenderWeeks" to a non default value works as expected', function( assert ) { - const calendarWeeks = true; - - const component = this.subject({ - calendarWeeks: calendarWeeks - }); - - const options = component.get( 'options' ); - - assert.strictEqual( - options.calendarWeeks, - calendarWeeks - ); -}); - -test( 'Changing "clearBtn" to a non default value works as expected', function( assert ) { - const clearBtn = true; - - const component = this.subject({ - clearBtn: clearBtn - }); - - const options = component.get( 'options' ); - - assert.strictEqual( - options.clearBtn, - clearBtn - ); -}); - -test( 'Changing "daysOfWeekDisabled" to a non default value works as expected', function( assert ) { - const daysOfWeek = [ 1, 2, 3 ]; - - const component = this.subject({ - daysOfWeekDisabled: daysOfWeek - }); - - const options = component.get( 'options' ); - - assert.strictEqual( - options.daysOfWeekDisabled, - daysOfWeek - ); -}); - -test( 'Changing "endDate" to a non default value works as expected', function( assert ) { - const endDate = window.moment( '2015-06-08' ); - - const component = this.subject({ - endDate: endDate - }); - - const options = component.get( 'options' ); - assert.strictEqual( - options.endDate, - endDate - ); -}); - -test( 'Changing "forceParse" to a non default value works as expected', function( assert ) { - const forceParse = false; - - const component = this.subject({ - forceParse: forceParse - }); - - const options = component.get( 'options' ); - - assert.strictEqual( - options.forceParse, - forceParse - ); -}); - -test( 'Changing "format" to a non default value works as expected', function( assert ) { - const format = 'dd/mm/yyyy'; - - const component = this.subject({ - format: format - }); - - const options = component.get( 'options' ); - - assert.strictEqual( - options.format, - format - ); -}); - -test( 'Changing "inputs" to a non default value works as expected', function( assert ) { - const inputs = [ Ember.$( '' ), Ember.$( '' ) ]; - - const component = this.subject({ - inputs: inputs - }); - - const options = component.get( 'options' ); - - assert.deepEqual( - options.inputs, - inputs - ); -}); - -test( 'Changing "keyboardNavigation" to a non default value works as expected', function( assert ) { - const keyboardNavigation = false; - - const component = this.subject({ - keyboardNavigation: keyboardNavigation - }); - - const options = component.get( 'options' ); - - assert.strictEqual( - options.keyboardNavigation, - keyboardNavigation - ); -}); - -test( 'Changing "language" to a non default value works as expected', function( assert ) { - const language = 'eu'; - - const component = this.subject({ - language: language - }); - - const options = component.get( 'options' ); - - assert.strictEqual( - options.language, - language - ); -}); - -test( 'Changing "minViewMode" to a non default value works as expected', function( assert ) { - const minViewMode = 'months'; - - const component = this.subject({ - minViewMode: minViewMode - }); - - const options = component.get( 'options' ); - - assert.strictEqual( - options.minViewMode, - minViewMode - ); -}); - -test( 'Changing "multidate" to a non default value works as expected', function( assert ) { - const multidate = false; - - const component = this.subject({ - multidate: multidate - }); - - const options = component.get( 'options' ); - - assert.strictEqual( - options.multidate, - multidate - ); -}); - -test( 'Changing "orientation" to a non default value works as expected', function( assert ) { - const orientation = 'top'; - - const component = this.subject({ - orientation: orientation - }); - - const options = component.get( 'options' ); - - assert.strictEqual( - options.orientation, - orientation - ); -}); - -test( 'Changing "startDate" to a non default value works as expected', function( assert ) { - const startDate = window.moment( '2015-01-01' ); - - const component = this.subject({ - startDate: startDate - }); - - const options = component.get( 'options' ); - - assert.strictEqual( - options.startDate, - startDate - ); -}); - -test( 'Changing "startView" to a non default value works as expected', function( assert ) { - const startView = 'year'; - - const component = this.subject({ - startView: startView - }); - - const options = component.get( 'options' ); - - assert.strictEqual( - options.startView, - startView - ); -}); - -test( 'Changing "todayBtn" to a non default value works as expected', function( assert ) { - const todayBtn = true; - - const component = this.subject({ - todayBtn: todayBtn - }); - - const options = component.get( 'options' ); - - assert.strictEqual( - options.todayBtn, - todayBtn - ); -}); - -test( 'Changing "todayHighlight" to a non default value works as expected', function( assert ) { - const todayHighlight = true; - - const component = this.subject({ - todayHighlight: todayHighlight - }); - - const options = component.get( 'options' ); - - assert.strictEqual( - options.todayHighlight, - todayHighlight + component.get( 'selectConstraint' ), + true, + 'selectConstraint is ? by default' ); -}); - -test( 'Changing "weekStart" to a non default value works as expected', function( assert ) { - const weekStart = 1; - - const component = this.subject({ - weekStart: weekStart - }); - - const options = component.get( 'options' ); assert.strictEqual( - options.weekStart, - weekStart + component.get( 'viewMode' ), + 'days', + 'viewMode is "days" by default' ); }); @@ -502,17 +110,37 @@ test( 'There are no references to Ember.$, $ or jQuery', function( assert ) { Ember.$.restore(); }); -test( 'Observer keys are correct', function( assert ) { +test( 'Dependent keys are correct', function( assert ) { const component = this.subject(); - const updateDateRangeKeys = [ - 'endDate', - 'startDate' + const parseFormatsDependentKeys = [ + 'locale' + ]; + + const valueDependentKeys = [ + 'selectedDate', + 'formatString' + ]; + + const viewingDateDependentKeys = [ + 'selectedDate' ]; assert.deepEqual( - component.updateDateRange.__ember_observes__, - updateDateRangeKeys, - 'Observer keys are correct for updateDateRange()' + component.parseFormats._dependentKeys, + parseFormatsDependentKeys, + 'Dependent keys are correct for parseFormats()' + ); + + assert.deepEqual( + component.value._dependentKeys, + valueDependentKeys, + 'Dependent keys are correct for value()' + ); + + assert.deepEqual( + component.viewingDate._dependentKeys, + viewingDateDependentKeys, + 'Dependent keys are correct for viewingDate()' ); }); diff --git a/tests/unit/components/sl-date-range-picker-test.js b/tests/unit/components/sl-date-range-picker-test.js index a70be8d0..bf964769 100755 --- a/tests/unit/components/sl-date-range-picker-test.js +++ b/tests/unit/components/sl-date-range-picker-test.js @@ -29,49 +29,49 @@ test( 'Default property values are set correctly', function( assert ) { assert.strictEqual( component.get( 'endDate' ), null, - 'endDate: null' + 'endDate is null by default' ); assert.strictEqual( component.get( 'endDatePlaceholder' ), null, - 'endDatePlaceholder: null' + 'endDatePlaceholder is null by default' ); assert.strictEqual( component.get( 'format' ), null, - 'format: null' + 'format is null by default' ); assert.strictEqual( component.get( 'label' ), null, - 'label: null' + 'label is null by default' ); assert.strictEqual( component.get( 'locale' ), 'en', - 'locale: "en"' + 'locale is "en" by default' ); assert.strictEqual( component.get( 'selectConstraint' ), true, - 'selectConstraint: ?' + 'selectConstraint is ? by default' ); assert.strictEqual( component.get( 'startDate' ), null, - 'startDate: null' + 'startDate is null by default' ); assert.strictEqual( component.get( 'startDatePlaceholder' ), null, - 'startDatePlaceholder: null' + 'startDatePlaceholder is null by default' ); }); @@ -179,3 +179,29 @@ test( 'label is accepted as a parameter', function( assert ) { 'label is used for start date input' ); }); + +test( 'Dependent keys are correct', function( assert ) { + const component = this.subject(); + + const endSelectConstraintDependentKeys = [ + 'endDate', + 'selectConstraint' + ]; + + const startSelectConstraintDependentKeys = [ + 'startDate', + 'selectConstraint' + ]; + + assert.deepEqual( + component.endSelectConstraint._dependentKeys, + endSelectConstraintDependentKeys, + 'Dependent keys are correct for endSelectConstraint()' + ); + + assert.deepEqual( + component.startSelectConstraint._dependentKeys, + startSelectConstraintDependentKeys, + 'Dependent keys are correct for startSelectConstraint()' + ); +}); From a861ea1b40ac1512b8023b05ea177ba610f4af34 Mon Sep 17 00:00:00 2001 From: J Corley Date: Fri, 29 Jan 2016 18:55:25 -0600 Subject: [PATCH 15/25] Removed several unnecessary tests. Stubbed out needed tests. Fixed several tests that were failing. Reverted a commented piece of code for focus on day (it is needed). --- addon/components/sl-calendar-day.js | 2 +- addon/components/sl-calendar.js | 2 +- addon/components/sl-date-picker.js | 1 + .../components/sl-calendar-day-test.js | 51 +- .../components/sl-calendar-month-test.js | 21 +- .../components/sl-calendar-test.js | 466 +---------------- .../components/sl-calendar-year-test.js | 27 +- .../components/sl-date-picker-test.js | 35 +- .../components/sl-date-range-picker-test.js | 137 ----- tests/unit/components/sl-calendar-test.js | 484 +++--------------- tests/unit/components/sl-date-picker-test.js | 16 +- .../components/sl-date-range-picker-test.js | 4 +- 12 files changed, 203 insertions(+), 1043 deletions(-) diff --git a/addon/components/sl-calendar-day.js b/addon/components/sl-calendar-day.js index 5c299615..a5913592 100644 --- a/addon/components/sl-calendar-day.js +++ b/addon/components/sl-calendar-day.js @@ -54,7 +54,7 @@ export default Ember.Component.extend({ didInsertElement() { this._super( ...arguments ); - //this.focus(); + this.focus(); }, // ------------------------------------------------------------------------- diff --git a/addon/components/sl-calendar.js b/addon/components/sl-calendar.js index 0700f4d6..838b5313 100755 --- a/addon/components/sl-calendar.js +++ b/addon/components/sl-calendar.js @@ -290,7 +290,7 @@ export default Ember.Component.extend({ dateValuePath: 'date', // if true, always shows 6 weeks - fixedWeekCount: true, + fixedWeekCount: false, // boolean: whether calendar is focusable for keyboard navigation focusable: true, diff --git a/addon/components/sl-date-picker.js b/addon/components/sl-date-picker.js index 2d69399f..aaf9bc89 100755 --- a/addon/components/sl-date-picker.js +++ b/addon/components/sl-date-picker.js @@ -236,6 +236,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa }, formatString: Ember.computed( + 'format', function() { return this.get( 'format' ) || window.moment().localeData().longDateFormat( 'L' ); } diff --git a/tests/integration/components/sl-calendar-day-test.js b/tests/integration/components/sl-calendar-day-test.js index bc4728e7..60ca2ea6 100644 --- a/tests/integration/components/sl-calendar-day-test.js +++ b/tests/integration/components/sl-calendar-day-test.js @@ -18,6 +18,12 @@ test( 'Default rendered state', function( assert ) { this.$( '>:first-child' ).hasClass( 'day' ), 'Has class "day"' ); + + assert.strictEqual( + this.$( '>:first-child' ).attr( 'role' ), + 'gridcell', + 'Has role "gridcell"' + ); }); test( 'Selected class is present when in active state', function( assert ) { @@ -76,26 +82,47 @@ test( 'Disabled class is present when in restricted state', function( assert ) { }); test( 'Default action is triggered when element is clicked', function( assert ) { - assert.ok( - false - ); -}); + assert.expect( 1 ); -test( 'ariaRole', function( assert ) { - assert.ok( - false - ); + const done = assert.async(); + + this.render( hbs` + {{sl-calendar-day action="testAction"}} + ` ); + + this.on( 'testAction', function() { + assert.ok( + true, + 'Action was fired' + ); + + done(); + }); + + this.$( '>:first-child' ).click(); }); test( 'ariaSelected', function( assert ) { - assert.ok( - false + this.render( hbs` + {{sl-calendar-day active=true}} + ` ); + + assert.strictEqual( + this.$( '>:first-child' ).attr( 'aria-selected' ), + 'true', + 'aria-selected is true when calendar-day is active' ); }); test( 'tabIndex', function( assert ) { - assert.ok( - false + this.render( hbs` + {{sl-calendar-day focused=true}} + ` ); + + assert.strictEqual( + this.$( '>:first-child' ).attr( 'tabIndex' ), + '0', + 'tabIndex is set when calendar-day has focus' ); }); diff --git a/tests/integration/components/sl-calendar-month-test.js b/tests/integration/components/sl-calendar-month-test.js index b333e27f..6e2fe9e0 100644 --- a/tests/integration/components/sl-calendar-month-test.js +++ b/tests/integration/components/sl-calendar-month-test.js @@ -32,9 +32,24 @@ test( 'Selected class is present when in active state', function( assert ) { }); test( 'Default action is triggered when element is clicked', function( assert ) { - assert.ok( - false - ); + assert.expect( 1 ); + + const done = assert.async(); + + this.render( hbs` + {{sl-calendar-month action="testAction"}} + ` ); + + this.on( 'testAction', function() { + assert.ok( + true, + 'Action was fired' + ); + + done(); + }); + + this.$( '>:first-child' ).click(); }); test( 'Content is yielded', function( assert ) { diff --git a/tests/integration/components/sl-calendar-test.js b/tests/integration/components/sl-calendar-test.js index 2cc2467e..c948ecf7 100755 --- a/tests/integration/components/sl-calendar-test.js +++ b/tests/integration/components/sl-calendar-test.js @@ -726,6 +726,7 @@ test( 'Changing viewMode by Selection', function( assert ) { ); }); +//add assert for fixedweek test( 'All Days are Displayed in Order', function( assert ) { this.set( 'viewingDate', window.moment( [ 2015, 0, 1 ] ) ); @@ -791,468 +792,3 @@ test( 'Twelve Years are Displayed in Order', function( assert ) { 'Twelve years are listed in order' ); }); - -// ------------------------------------------------------------------------- -// Start of Dual Component Tests - -test( 'Dual instance: Action fires when day is clicked', function( assert ) { - - const testAction1 = sinon.spy(); - const testAction2 = sinon.spy(); - - this.set( 'currentYear1', 2035 ); - this.set( 'currentMonth1', 1 ); - - this.set( 'currentYear2', 2022 ); - this.set( 'currentMonth2', 9 ); - - this.set( 'content', testContent ); - - this.render( hbs` - {{sl-calendar - action="testAction1" - content=content - currentYear=currentYear1 - currentMonth=currentMonth1 - }} - {{sl-calendar - action="testAction2" - content=content - currentYear=currentYear2 - currentMonth=currentMonth2 - }} - ` ); - - this.on( 'testAction1', testAction1 ); - this.on( 'testAction2', testAction2 ); - - this.$( '>:nth-child(2)' ).find( '.active' ).click(); - - assert.notOk( - testAction1.called, - 'Component instance one: did not fire an action' - ); - - assert.ok( - testAction2.called, - 'Component instance two: fired an action' - ); -}); - -test( 'Dual instance: Navigating Forward by Month', function( assert ) { - - const currentYear = 2022; - this.set( 'currentYear1', currentYear ); - this.set( 'currentYear2', currentYear ); - - const currentMonth = 9; - this.set( 'currentMonth1', currentMonth ); - this.set( 'currentMonth2', currentMonth ); - - this.render( hbs` - {{sl-calendar - currentMonth=currentMonth1 - currentYear=currentYear1 - }} - {{sl-calendar - currentMonth=currentMonth2 - currentYear=currentYear2 - }} - ` ); - - this.$( '>:nth-child(2)' ).find( '.sl-icon-next' ).click(); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - 'September ' + currentYear, - 'Component instance one: current month has not changed' - ); - - assert.strictEqual( - this.$( '>:nth-child(2)' ).find( '.datepicker-switch' ).text().trim(), - 'October ' + currentYear, - 'Component instance two: Current month advances one month' - ); -}); - -test( 'Dual instance: Navigating Backward by Month', function( assert ) { - - const currentYear = 2022; - this.set( 'currentYear1', currentYear ); - this.set( 'currentYear2', currentYear ); - - const currentMonth = 9; - this.set( 'currentMonth1', currentMonth ); - this.set( 'currentMonth2', currentMonth ); - - this.render( hbs` - {{sl-calendar - currentMonth=currentMonth1 - currentYear=currentYear1 - }} - {{sl-calendar - currentMonth=currentMonth2 - currentYear=currentYear2 - }} - ` ); - - this.$( '>:nth-child(2)' ).find( '.sl-icon-previous' ).click(); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - 'September ' + currentYear, - 'Component instance one: current month has not changed' - ); - - assert.strictEqual( - this.$( '>:nth-child(2)' ).find( '.datepicker-switch' ).text().trim(), - 'August ' + currentYear, - 'Component instance two: Current month adjusts to previous month' - ); -}); - -test( 'Dual instance: Navigating Forward by Year', function( assert ) { - - const currentYear = 2022; - this.set( 'currentYear1', currentYear ); - this.set( 'currentYear2', currentYear ); - - this.render( hbs` - {{sl-calendar - currentYear=currentYear1 - viewMode="months" - }} - {{sl-calendar - currentYear=currentYear2 - viewMode="months" - }} - ` ); - - this.$( '>:nth-child(2)' ).find( '.sl-icon-next' ).click(); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - currentYear.toString(), - 'Component instance one: year did not change' - ); - - assert.strictEqual( - this.$( '>:nth-child(2)' ).find( '.datepicker-switch' ).text().trim(), - ( currentYear + 1 ).toString(), - 'Component instance two: year advances by one year' - ); -}); - -test( 'Dual instance: Navigating Backward by Year', function( assert ) { - - const currentYear = 2022; - this.set( 'currentYear1', currentYear ); - this.set( 'currentYear2', currentYear ); - - this.render( hbs` - {{sl-calendar - currentYear=currentYear1 - viewMode="months" - }} - {{sl-calendar - currentYear=currentYear2 - viewMode="months" - }} - ` ); - - this.$( '>:nth-child(2)' ).find( '.sl-icon-previous' ).click(); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - currentYear.toString(), - 'Component instance one: year did not change' - ); - - assert.strictEqual( - this.$( '>:nth-child(2)' ).find( '.datepicker-switch' ).text().trim(), - ( currentYear - 1 ).toString(), - 'Component instance two: year adjusts to previous year' - ); -}); - -test( 'Dual instance: Navigating Forward by Decade', function( assert ) { - - const currentYear = 2022; - this.set( 'currentYear1', currentYear ); - this.set( 'currentYear2', currentYear ); - - this.render( hbs` - {{sl-calendar - currentYear=currentYear1 - viewMode="years" - }} - {{sl-calendar - currentYear=currentYear2 - viewMode="years" - }} - ` ); - - this.$( '>:nth-child(2)' ).find( '.sl-icon-next' ).click(); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - '2020-2029', - 'Component instance one: decade did not change' - ); - - assert.strictEqual( - this.$( '>:nth-child(2)' ).find( '.datepicker-switch' ).text().trim(), - '2030-2039', - 'Component instance two: next decade is set correctly' - ); -}); - -test( 'Dual instance: Navigating Backward by Decade', function( assert ) { - - const currentYear = 2022; - this.set( 'currentYear1', currentYear ); - this.set( 'currentYear2', currentYear ); - - this.render( hbs` - {{sl-calendar - currentYear=currentYear1 - viewMode="years" - }} - {{sl-calendar - currentYear=currentYear2 - viewMode="years" - }} - ` ); - - this.$( '>:nth-child(2)' ).find( '.sl-icon-previous' ).click(); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - '2020-2029', - 'Component instance one: decade did not change' - ); - - assert.strictEqual( - this.$( '>:nth-child(2)' ).find( '.datepicker-switch' ).text().trim(), - '2010-2019', - 'Component instance two: decade is set to the previous decade' - ); -}); - -test( 'Dual instance: Navigating from Month to Year', function( assert ) { - - const currentYear = 2022; - this.set( 'currentYear1', currentYear ); - this.set( 'currentYear2', currentYear ); - - const currentMonth = 9; - this.set( 'currentMonth1', currentMonth ); - this.set( 'currentMonth2', currentMonth ); - - this.render( hbs` - {{sl-calendar - currentYear=currentYear1 - currentMonth=currentMonth1 - }} - {{sl-calendar - currentYear=currentYear2 - currentMonth=currentMonth2 - }} - ` ); - - this.$( '>:nth-child(2)' ).find( '.datepicker-switch' ).click(); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - 'September ' + currentYear, - 'Component instance one: current month did not change' - ); - - assert.strictEqual( - this.$( '>:nth-child(2)' ).find( '.datepicker-switch' ).text().trim(), - currentYear.toString(), - 'Component instance two: current year is set correctly' - ); -}); - -test( 'Dual instance: Navigating from Year to Month', function( assert ) { - - const currentYear = 2022; - this.set( 'currentYear1', currentYear ); - this.set( 'currentYear2', currentYear ); - - const currentMonth = 9; - this.set( 'currentMonth1', currentMonth ); - this.set( 'currentMonth2', currentMonth ); - - this.set( 'content', testContent ); - - this.render( hbs` - {{sl-calendar - content=content - currentYear=currentYear1 - currentMonth=currentMonth1 - viewMode="months" - }} - {{sl-calendar - content=content - currentYear=currentYear2 - currentMonth=currentMonth2 - viewMode="months" - }} - ` ); - - this.$( '>:nth-child(2)' ).find( '.active' ).click(); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - currentYear.toString(), - 'Component instance one: current year did not change' - ); - - assert.strictEqual( - this.$( '>:nth-child(2)' ).find( '.datepicker-switch' ).text().trim(), - 'September ' + currentYear, - 'Component instance two: current month is set correctly' - ); -}); - -test( 'Dual instance: Navigating from Year to Decade', function( assert ) { - - const currentYear = 2022; - this.set( 'currentYear1', currentYear ); - this.set( 'currentYear2', currentYear ); - - this.render( hbs` - {{sl-calendar - currentYear=currentYear1 - viewMode="months" - }} - {{sl-calendar - currentYear=currentYear2 - viewMode="months" - }} - ` ); - - this.$( '>:nth-child(2)' ).find( '.datepicker-switch' ).click(); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - currentYear.toString(), - 'Component instance one: current year did not change' - ); - - assert.strictEqual( - this.$( '>:nth-child(2)' ).find( '.datepicker-switch' ).text().trim(), - '2020-2029', - 'Component instance two: current decade is set correctly' - ); -}); - -test( 'Dual instance: Navigating from Decade to Year', function( assert ) { - - const currentYear = 2022; - this.set( 'currentYear1', currentYear ); - this.set( 'currentYear2', currentYear ); - - this.set( 'content', testContent ); - - this.render( hbs` - {{sl-calendar - content=content - currentYear=currentYear1 - viewMode="years" - }} - {{sl-calendar - content=content - currentYear=currentYear2 - viewMode="years" - }} - ` ); - - this.$( '>:nth-child(2)' ).find( '.active' ).click(); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - '2020-2029', - 'Component instance two: current decade did not change' - ); - - assert.strictEqual( - this.$( '>:nth-child(2)' ).find( '.datepicker-switch' ).text().trim(), - currentYear.toString(), - 'Component instance two: current year is set correctly' - ); -}); - -test( 'Dual instance: Navigating Forward by Month Crosses to Next Year', function( assert ) { - - const currentYear = 2022; - this.set( 'currentYear1', currentYear ); - this.set( 'currentYear2', currentYear ); - - const currentMonth = 12; - this.set( 'currentMonth1', currentMonth ); - this.set( 'currentMonth2', currentMonth ); - - this.render( hbs` - {{sl-calendar - currentYear=currentYear1 - currentMonth=currentMonth1 - }} - {{sl-calendar - currentYear=currentYear2 - currentMonth=currentMonth2 - }} - ` ); - - this.$( '>:nth-child(2)' ).find( '.sl-icon-next' ).click(); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - 'December ' + currentYear, - 'Component instance one: current month did not change' - ); - - assert.strictEqual( - this.$( '>:nth-child(2)' ).find( '.datepicker-switch' ).text().trim(), - 'January ' + ( currentYear + 1 ), - 'Component instance two: next month is in the next year' - ); -}); - -test( 'Dual instance: Navigating Backward by Month Crosses to Previous Year', function( assert ) { - - const currentYear = 2022; - this.set( 'currentYear1', currentYear ); - this.set( 'currentYear2', currentYear ); - - const currentMonth = 1; - this.set( 'currentMonth1', currentMonth ); - this.set( 'currentMonth2', currentMonth ); - - this.render( hbs` - {{sl-calendar - currentYear=currentYear1 - currentMonth=currentMonth1 - }} - {{sl-calendar - currentYear=currentYear2 - currentMonth=currentMonth2 - }} - ` ); - - this.$( '>:nth-child(2)' ).find( '.sl-icon-previous' ).click(); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - 'January ' + currentYear, - 'Component instance one: current month did not change' - ); - - assert.strictEqual( - this.$( '>:nth-child(2)' ).find( '.datepicker-switch' ).text().trim(), - 'December ' + ( currentYear - 1 ), - 'Component instance two: previous month is in the previous year' - ); -}); diff --git a/tests/integration/components/sl-calendar-year-test.js b/tests/integration/components/sl-calendar-year-test.js index a07e9be1..e0c6034e 100644 --- a/tests/integration/components/sl-calendar-year-test.js +++ b/tests/integration/components/sl-calendar-year-test.js @@ -54,17 +54,22 @@ test( 'Old class is present when old is true', function( assert ) { }); test( 'Default action is triggered when element is clicked', function( assert ) { - assert.ok( - false - ); -}); + assert.expect( 1 ); -test( 'Content is yielded', function( assert ) { - this.render( template ); + const done = assert.async(); - assert.strictEqual( - this.$( '>:first-child' ).text().trim(), - '1999', - 'Content yields successfully' - ); + this.render( hbs` + {{sl-calendar-year action="testAction"}} + ` ); + + this.on( 'testAction', function() { + assert.ok( + true, + 'Action was fired' + ); + + done(); + }); + + this.$( '>:first-child' ).click(); }); diff --git a/tests/integration/components/sl-date-picker-test.js b/tests/integration/components/sl-date-picker-test.js index 1475c73f..fa26faf4 100644 --- a/tests/integration/components/sl-date-picker-test.js +++ b/tests/integration/components/sl-date-picker-test.js @@ -135,7 +135,7 @@ test( 'label is accepted as a parameter', function( assert ) { const first = this.$( '>:first-child' ); assert.strictEqual( - first.find( 'label' ).html(), + first.find( 'label' ).text().trim(), labeltext, 'label element was created with label parameter text' ); @@ -173,6 +173,39 @@ test( 'placeholder is accepted as a parameter', function( assert ) { ); }); +test( 'Selected day is set in the input field', function( assert ) { + const selectedDate = window.moment( [ 2015, 0, 5 ] ); + const format = "MM/DD/YYYY"; + + this.set( 'selectedDate', selectedDate ); + this.set( 'format', format ); + + this.render( hbs` + {{sl-date-picker + selectedDate=selectedDate + format=format + }} + ` ); + + const input = this.$( '>:first-child' ).find( 'input' ); + + assert.strictEqual( + input.val(), + '01/05/2015', + 'The selected day is set in the input field' + ); + + const newDate = window.moment( selectedDate.add( 5, 'months' ) ); + + this.set( 'selectedDate', newDate ); + + assert.strictEqual( + input.val(), + '06/05/2015', + 'The selected day is updated in the input field' + ); +}); + test( 'properties are properly passed to sl-calendar', function( assert ) { const mockCalendarTemplate = hbs` {{testAttrs}} diff --git a/tests/integration/components/sl-date-range-picker-test.js b/tests/integration/components/sl-date-range-picker-test.js index 5b90a09c..44ec7d2a 100644 --- a/tests/integration/components/sl-date-range-picker-test.js +++ b/tests/integration/components/sl-date-range-picker-test.js @@ -219,140 +219,3 @@ test( 'helpText is accepted as a parameter', function( assert ) { 'The "helpText" property text was set' ); }); - -// removing value seeding -skip( 'startDateValue is accepted as a parameter', function( assert ) { - - this.render( hbs` - {{sl-date-range-picker - startDateValue="09/25/2015" - }} - ` ); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.sl-daterange-start-date' ).find( 'input' ).val(), - '09/25/2015', - 'The "startDateValue" property text was set' - ); -}); - -// removing value seeding -skip( 'endDateValue is accepted as a parameter', function( assert ) { - - this.render( hbs` - {{sl-date-range-picker - endDateValue="12/25/2015" - }} - ` ); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.sl-daterange-end-date' ).find( 'input' ).val(), - '12/25/2015', - 'The "endDateValue" property text was set' - ); -}); - -// verify this is in date-picker -test( 'Selected day is set in the start date input field', function( assert ) { - - this.render( hbs` - {{sl-date-range-picker - startDateValue="09/25/2015" - }} - ` ); - - const input = this.$( '>:first-child' ).find( '.sl-daterange-start-date' ).find( 'input' ); - input.triggerHandler( 'focus' ); - - Ember.$( '.datepicker' ).last().find( '.datepicker-days' ).find( 'td' ).not( '.old' ).first().trigger( 'click' ); - - assert.strictEqual( - input.val(), - '09/01/2015', - 'The selected day is set in the input field' - ); -}); - -// verify this is in date-picker -test( 'Selected day is set in the end date input field', function( assert ) { - this.render( hbs` - {{sl-date-range-picker - endDateValue="09/25/2015" - }} - ` ); - - const input = this.$( '>:first-child' ).find( '.sl-daterange-end-date' ).find( 'input' ); - input.triggerHandler( 'focus' ); - - Ember.$( '.datepicker' ).last().find( '.datepicker-days' ).find( 'td' ).not( '.old' ).first().trigger( 'click' ); - - assert.strictEqual( - input.val(), - '09/01/2015', - 'The selected day is set in the input field' - ); -}); - -skip( '"startDateValue" cannot be less than "minDate"', function( assert ) { - - this.render( hbs` - {{sl-date-range-picker - minDate="09/28/2015" - startDateValue="09/25/2015" - }} - ` ); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.sl-daterange-start-date' ).find( 'input' ).val(), - '09/28/2015', - 'The "startDateValue" is not less than the "minDate"' - ); -}); - -skip( '"endDateValue" cannot be more than "maxDate"', function( assert ) { - - this.render( hbs` - {{sl-date-range-picker - maxDate="09/25/2015" - endDateValue="09/28/2015" - }} - ` ); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.sl-daterange-end-date' ).find( 'input' ).val(), - '09/25/2015', - 'The "endDateValue" is not more than the "maxDate"' - ); -}); - -skip( '"endDateValue" cannot be less than "startDateValue"', function( assert ) { - - this.render( hbs` - {{sl-date-range-picker - startDateValue="09/25/2015" - endDateValue="09/20/2015" - }} - ` ); - - assert.notEqual( - this.$( '>:first-child' ).find( '.sl-daterange-end-date' ).find( 'input' ).val(), - '09/20/2015', - 'The "endDateValue" is not less than the "startDateValue"' - ); -}); - -skip( '"startDateValue" cannot be more than "endDateValue"', function( assert ) { - - this.render( hbs` - {{sl-date-range-picker - startDateValue="09/25/2015" - endDateValue="09/20/2015" - }} - ` ); - - assert.notEqual( - this.$( '>:first-child' ).find( '.sl-daterange-start-date' ).find( 'input' ).val(), - '09/25/2015', - 'The "startDateValue" is not more than the "endDateValue"' - ); -}); diff --git a/tests/unit/components/sl-calendar-test.js b/tests/unit/components/sl-calendar-test.js index 2af84556..795cc302 100755 --- a/tests/unit/components/sl-calendar-test.js +++ b/tests/unit/components/sl-calendar-test.js @@ -28,9 +28,9 @@ test( 'Default property values are set correctly', function( assert ) { 'dateValuePath is "date" by default' ); - assert.ok( + assert.notOk( component.get( 'fixedWeekCount' ), - 'fixedWeekCount is true by default' + 'fixedWeekCount is false by default' ); assert.ok( @@ -55,11 +55,14 @@ test( 'Default property values are set correctly', function( assert ) { 'locked is false by default' ); - assert.strictEqual( + /*assert.strictEqual( component.get( 'selectConstraint' ), - true, + { + start: null, + end: null + }, 'selectConstraint is ? by default' - ); + );*/ assert.strictEqual( component.get( 'selectedDate' ), @@ -143,23 +146,41 @@ skip( 'Lock mode prevents changing state', function( assert ) { }); skip( 'locale - Setting causes default of en (English) to be updated', function() { -}); -skip( 'currentMonthString - current month string formatted as full word (January, November, ...)', function() { }); skip( 'contentDates - Verify dates array', function() { + +}); + +skip( 'setDate method sets the viewingDate and selectedDate', function() { + +}); + +skip( 'setMonth method modifies the viewingDate', function() { + }); -skip( 'setYear - viewMode and currentYear set correctly', function() { +skip( 'setYear method modifies the viewingDate', function() { + }); skip( 'setView - viewMode set correctly', function() { + +}); + +skip( 'calendar title is correctly generated for each viewMode', function() { + }); -skip( 'setMonth - currentMonth and viewMode set correctly', function() { +skip( 'shortWeekDayNames - returns array of day names in short name format (Su, Mo, Tu...)', function() { + }); +//updateShowingMonth? +//focusedDateChange? +//activeDateChange? + test( 'changeDecade action works', function( assert ) { const component = this.subject({ viewingDate: window.moment( [ 2015, 0, 1 ] ) @@ -240,67 +261,6 @@ test( 'Incrementing month from December causes year to increment', function( ass ); }); -test( 'daysInMonth - Number of days in month is set correctly', function( assert ) { - const daysInMonthStub = sinon.stub().returns( 31 ); - - const momentStub = sinon.stub( window, 'moment' ) - .returns( { daysInMonth: daysInMonthStub } ); - - const component = this.subject({ - currentMonth: 12, - currentYear: 2015 - }); - - assert.strictEqual( - component.get( 'daysInMonth' ), - 31, - '"daysInMonth" is set correctly' - ); - - assert.deepEqual( - momentStub.args[ 0 ][ 0 ], - [ - component.get( 'currentYear' ), - component.get( 'currentMonth' ) - 1 - ], - 'Moment called with currentYear and currentMonth' - ); - - window.moment.restore(); -}); - -test( 'Decade range is correctly based on currentYear', function( assert ) { - const component = this.subject({ currentYear: 2023 }); - - assert.strictEqual( - component.get( 'decadeStart' ), - 2020, - 'decadeStart is expected value' - ); - - assert.strictEqual( - component.get( 'decadeEnd' ), - 2029, - 'decadeEnd is expected value' - ); -}); - -test( 'Months for year view are generated validly', function( assert ) { - const component = this.subject(); - - assert.strictEqual( - component.get( 'monthsInYearView' ).length, - 12, - 'Twelve months are created' - ); -}); - -skip( 'monthsInYearView - active month set correctly', function() { - /* Expand 'Months for year view are generated validly' test to also - check that the active month is set correctly. - */ -}); - test( 'View mode is settable to "days"', function( assert ) { const component = this.subject({ viewMode: 'days' }); @@ -358,356 +318,66 @@ test( 'View mode is settable to "years"', function( assert ) { ); }); -test( 'weeksInMonthView - set previousMonth when: currentMonth is anything other than 1', function( assert ) { - const daysInMonthStub = sinon.stub().returns( 31 ); - - const momentStub = sinon.stub( window, 'moment' ) - .returns( { daysInMonth: daysInMonthStub } ); - - const weeksInMonthView = [ - [ - { - 'active': false, - 'content': null, - 'day': 30, - 'new': false, - 'old': true - }, - { - 'active': false, - 'content': null, - 'day': 31, - 'new': false, - 'old': true - }, - { - 'active': false, - 'content': null, - 'day': 1, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 2, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 3, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 4, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 5, - 'new': false, - 'old': false - } - ], - [ - { - 'active': false, - 'content': null, - 'day': 6, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 7, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 8, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 9, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 10, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 11, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 12, - 'new': false, - 'old': false - } - ], - [ - { - 'active': false, - 'content': null, - 'day': 13, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 14, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 15, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 16, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 17, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 18, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 19, - 'new': false, - 'old': false - } - ], - [ - { - 'active': false, - 'content': null, - 'day': 20, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 21, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 22, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 23, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 24, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 25, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 26, - 'new': false, - 'old': false - } - ], - [ - { - 'active': false, - 'content': null, - 'day': 27, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 28, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 29, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 30, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 31, - 'new': false, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 1, - 'new': true, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 2, - 'new': true, - 'old': false - } - ], - [ - { - 'active': false, - 'content': null, - 'day': 3, - 'new': true, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 4, - 'new': true, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 5, - 'new': true, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 6, - 'new': true, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 7, - 'new': true, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 8, - 'new': true, - 'old': false - }, - { - 'active': false, - 'content': null, - 'day': 9, - 'new': true, - 'old': false - } - ] - ]; - +//old/new/active? +test( 'Weeks for month view are assembled correctly', function( assert ) { const component = this.subject({ - currentMonth: 12, - currentYear: 2015 + viewingDate: window.moment( [ 2015, 1, 1 ] ) }); - assert.deepEqual( - component.get( 'weeksInMonthView' ), - weeksInMonthView, - '"weeksInMonthView" is set correctly' - ); + let allWeeks = component.get( 'weeksInMonthView' ); + let flattenedWeeks = []; - assert.deepEqual( - momentStub.args[ 0 ][ 0 ], - [ - component.get( 'currentYear' ), - component.get( 'currentMonth' ) - 1 - ], - 'Moment called with currentYear and currentMonth' + for ( let weekGroup = 0; weekGroup < allWeeks.length; weekGroup++ ) { + for ( let week = 0; week < allWeeks[ weekGroup ].length; week++ ) { + flattenedWeeks.push( allWeeks[ weekGroup ][ week ] ); + } + } + + assert.strictEqual( + flattenedWeeks.length, + 28, + 'Twenty eight days were generated for the month view' ); - window.moment.restore(); -}); + component.set( 'fixedWeekCount', true ); -skip( 'weeksInMonthView - set previousMonth when: currentMonth equals 1', function() { -}); + allWeeks = component.get( 'weeksInMonthView' ); + flattenedWeeks = []; -skip( 'weeksInMonthView - set nextMonth when: currentMonth is anything other than 12', function() { -}); + for ( let weekGroup = 0; weekGroup < allWeeks.length; weekGroup++ ) { + for ( let week = 0; week < allWeeks[ weekGroup ].length; week++ ) { + flattenedWeeks.push( allWeeks[ weekGroup ][ week ] ); + } + } -skip( 'weeksInMonthView - when firstWeekdayOfCurrentMonth is 0 (Sunday)', function() { + assert.strictEqual( + flattenedWeeks.length, + 42, + 'Forty two days were generated for the month view' + ); }); -skip( 'shortWeekDayNames - returns array of day names in short name format (Su, Mo, Tu...)', function() { +//active? +test( 'Months for year view are assembled correctly', function( assert ) { + const component = this.subject(); + + const allMonths = component.get( 'monthsInYearView' ); + const flattenedMonths = []; + + for ( let monthGroup = 0; monthGroup < allMonths.length; monthGroup++ ) { + for ( let month = 0; month < allMonths[ monthGroup ].length; month++ ) { + flattenedMonths.push( allMonths[ monthGroup ][ month ] ); + } + } + + assert.strictEqual( + flattenedMonths.length, + 12, + 'Twelve months were generated for the year view' + ); }); +//active? test( 'Years for decade view are assembled correctly', function( assert ) { const component = this.subject(); diff --git a/tests/unit/components/sl-date-picker-test.js b/tests/unit/components/sl-date-picker-test.js index fb64ae65..ff7011b0 100755 --- a/tests/unit/components/sl-date-picker-test.js +++ b/tests/unit/components/sl-date-picker-test.js @@ -71,11 +71,11 @@ test( 'Default properties are set correctly', function( assert ) { 'placeholder is null by default' ); - assert.strictEqual( + /*assert.strictEqual( component.get( 'selectConstraint' ), true, 'selectConstraint is ? by default' - ); + );*/ assert.strictEqual( component.get( 'viewMode' ), @@ -88,7 +88,7 @@ test( 'There are no references to Ember.$, $ or jQuery', function( assert ) { const jqueryAliasSpy = sinon.spy( window, '$' ); const jquerySpy = sinon.spy( window, 'jQuery' ); const emberJquery = sinon.spy( Ember, '$' ); - const startDate = window.moment( '2016-01-01' ).toDate(); + const startDate = window.moment( [ 2015, 0, 1 ] ); const component = this.subject(); @@ -113,6 +113,10 @@ test( 'There are no references to Ember.$, $ or jQuery', function( assert ) { test( 'Dependent keys are correct', function( assert ) { const component = this.subject(); + const formatStringDependentKeys = [ + 'format' + ]; + const parseFormatsDependentKeys = [ 'locale' ]; @@ -126,6 +130,12 @@ test( 'Dependent keys are correct', function( assert ) { 'selectedDate' ]; + assert.deepEqual( + component.formatString._dependentKeys, + formatStringDependentKeys, + 'Dependent keys are correct for formatString()' + ); + assert.deepEqual( component.parseFormats._dependentKeys, parseFormatsDependentKeys, diff --git a/tests/unit/components/sl-date-range-picker-test.js b/tests/unit/components/sl-date-range-picker-test.js index bf964769..836a727b 100755 --- a/tests/unit/components/sl-date-range-picker-test.js +++ b/tests/unit/components/sl-date-range-picker-test.js @@ -56,11 +56,11 @@ test( 'Default property values are set correctly', function( assert ) { 'locale is "en" by default' ); - assert.strictEqual( + /*assert.strictEqual( component.get( 'selectConstraint' ), true, 'selectConstraint is ? by default' - ); + );*/ assert.strictEqual( component.get( 'startDate' ), From a90dd2f09373945ebb667bb1d34d916f59316e10 Mon Sep 17 00:00:00 2001 From: J Corley Date: Tue, 2 Feb 2016 12:34:22 -0600 Subject: [PATCH 16/25] Various tests and test cleanup. ** CALENDAR ** Removed locked state. Removed today property. Removed dateValuePath. Cleaned up docblocks. Added showControls property. Added observer to ensure days have correct events. Removed old contentDates property. Added css to support events on day. Added events to the demo app route. ** CALENDAR DAY ** Added hasEvents property. Changed content property to events. Added actions hash to allow events property to exist. Added test for hasEvents. --- addon/components/sl-calendar-day.js | 26 +- addon/components/sl-calendar.js | 178 ++++----- addon/templates/components/sl-calendar.hbs | 128 +++--- app/styles/sl-calendar.less | 22 ++ tests/dummy/app/routes/demos/sl-calendar.js | 8 +- .../dummy/app/templates/demos/sl-calendar.hbs | 2 +- .../components/sl-calendar-day-test.js | 19 + .../components/sl-calendar-test.js | 178 +++------ tests/unit/components/sl-calendar-day-test.js | 36 +- tests/unit/components/sl-calendar-test.js | 373 ++++++++++++++---- 10 files changed, 581 insertions(+), 389 deletions(-) diff --git a/addon/components/sl-calendar-day.js b/addon/components/sl-calendar-day.js index a5913592..5d137f5b 100644 --- a/addon/components/sl-calendar-day.js +++ b/addon/components/sl-calendar-day.js @@ -23,7 +23,8 @@ export default Ember.Component.extend({ 'new', 'old', 'isToday:today', - 'restricted:disabled' + 'restricted:disabled', + 'hasEvents' ], /** @type {String[]} */ @@ -37,6 +38,8 @@ export default Ember.Component.extend({ // ------------------------------------------------------------------------- // Actions + actions: {}, + // ------------------------------------------------------------------------- // Events @@ -45,10 +48,10 @@ export default Ember.Component.extend({ * @returns {undefined} */ click() { - const content = this.get( 'content' ); + const events = this.get( 'events' ); const date = this.get( 'date' ); - this.sendAction( 'action', date, content ); + this.sendAction( 'action', date, events ); }, didInsertElement() { @@ -69,16 +72,10 @@ export default Ember.Component.extend({ ariaRole: 'gridcell', - /** - * The various data representing the day (created and passed in through - * sl-calendar) - * - * @type {?Object} - */ - content: null, - date: null, + events: [], + focused: false, /** @@ -124,6 +121,13 @@ export default Ember.Component.extend({ } ), + hasEvents: Ember.computed( + 'events', + function() { + return !Ember.isEmpty( this.get( 'events' ) ); + } + ), + isToday: Ember.computed( 'date', function() { diff --git a/addon/components/sl-calendar.js b/addon/components/sl-calendar.js index 838b5313..8b7b648d 100755 --- a/addon/components/sl-calendar.js +++ b/addon/components/sl-calendar.js @@ -32,11 +32,6 @@ export default Ember.Component.extend({ 'tabIndex' ], - /** @type {String[]} */ - classNameBindings: [ - 'locked:sl-calendar-locked' - ], - /** @type {String[]} */ classNames: [ 'sl-ember-components', @@ -97,21 +92,21 @@ export default Ember.Component.extend({ }, /** - * Action to trigger component's bound action and pass back content + * Action to trigger component's bound action and pass back events * associated with the clicked date * * @function actions:selectDate * @param {Object} date - Moment date object representing the clicked * date - * @param {Array} data - Collection of content objects with date - * values of the clicked date + * @param {Array} events - Collection of event objects associated with + * the clicked date * @returns {undefined} */ - selectDate( date, data ) { + selectDate( date, events ) { const isValid = this.setDate( date ); if ( isValid ) { - this.sendAction( 'action', date, data ); + this.sendAction( 'action', date, events ); } }, @@ -148,10 +143,6 @@ export default Ember.Component.extend({ * @returns {undefined} */ setView( view ) { - if ( this.get( 'locked' ) ) { - return; - } - this.set( 'viewMode', view ); this.$().focus(); } @@ -175,10 +166,6 @@ export default Ember.Component.extend({ keyDown( event ) { this._super( ...arguments ); - // handle wai-aria here - // https://www.w3.org/TR/2009/WD-wai-aria-practices-20090224/#datepicker - // https://web.archive.org/web/20130127091925/http://codetalks.org/source/widgets/datepicker/datepicker.sample.html - const viewingDate = window.moment( this.get( 'viewingDate' ) ); let timePeriod; @@ -257,37 +244,30 @@ export default Ember.Component.extend({ const today = window.moment(); const selectConstraint = this.get( 'selectConstraint' ); - this.set( 'today', today ); - if ( !this.get( 'viewingDate' ) ) { this.set( 'viewingDate', today ); } - for ( let constraint in selectConstraint ) { + /*for ( let constraint in selectConstraint ) { selectConstraint[ constraint ] = window.moment( selectConstraint[ constraint ] ); if ( !selectConstraint[ constraint ].isValid ) { // throw an error or warning here } } - this.set( 'selectConstraint', selectConstraint ); + this.set( 'selectConstraint', selectConstraint );*/ + + this.applyEvents(); }, // ------------------------------------------------------------------------- // Properties /** - * Array of date value objects + * Array of events to represent on the calendar * * @type {Object[]} */ - content: [], - - /** - * String lookup for the date value on the content objects - * - * @type {String} - */ - dateValuePath: 'date', + events: [], // if true, always shows 6 weeks fixedWeekCount: false, @@ -305,14 +285,6 @@ export default Ember.Component.extend({ */ locale: 'en', - /** - * When true, the view mode is locked and users cannot navigate forward - * and back - * - * @type {Boolean} - */ - locked: false, - // constrain selectable dates selectConstraint: { start: null, @@ -322,13 +294,12 @@ export default Ember.Component.extend({ // currently selected date: represented by moment object selectedDate: null, + showControls: true, + // the currently shown month // used as a computed trigger for building list of weeks in month showingMonth: null, - // today: represented by moment object - today: null, - // currently viewed date: represented by moment object viewingDate: null, @@ -362,6 +333,58 @@ export default Ember.Component.extend({ } ), + applyEvents: Ember.observer( + 'events', + 'weeksInMonthView', + function() { + const events = this.get( 'events' ); + const viewingDate = this.get( 'viewingDate' ); + const weeksInMonthView = this.get( 'weeksInMonthView' ); + const eventsPerDay = []; + + for ( let event = 0; event < events.length; event++ ) { + const currentEvent = events[ event ]; + if ( currentEvent.startDate.isAfter( viewingDate, 'month' ) ) { + continue; + } + + if ( currentEvent.endDate ) { + if ( currentEvent.endDate.isBefore( viewingDate, 'month' ) ) { + continue; + } + } + + for ( let day = 0; day < eventsPerDay.length; day++ ) { + if ( currentEvent.startDate.isSame( eventsPerDay[ day ].date ) ) { + eventsPerDay[ day ].events.push( currentEvent ); + continue; + } + } + + eventsPerDay.push( { + date: currentEvent.startDate, + events: [].push( currentEvent ) + }); + } + + for ( let week = 0; week < weeksInMonthView.length; week++ ) { + daysLoop: + for ( let day = 0; day < weeksInMonthView[ week ].length; day++ ) { + const date = Ember.get( weeksInMonthView[ week ][ day ], 'date' ); + + eventsLoop: + for ( let eventDay = 0; eventDay < eventsPerDay.length; eventDay++ ) { + if ( date.isSame( eventsPerDay[ eventDay ].date, 'day' ) ) { + Ember.set( weeksInMonthView[ week ][ day ], 'events', eventsPerDay[ eventDay ].events ); + continue daysLoop; + } + } + Ember.set( weeksInMonthView[ week ][ day ], 'events', null ); + } + } + } + ), + focusedDateChange: Ember.observer( 'viewingDate', function() { @@ -397,12 +420,14 @@ export default Ember.Component.extend({ if ( selectConstraint.start ) { if ( date.isBefore( selectConstraint.start ) ) { + console.log( 'start' ); return; } } if ( selectConstraint.end ) { if ( date.isAfter( selectConstraint.end ) ) { + console.log( 'end' ); return; } } @@ -413,20 +438,12 @@ export default Ember.Component.extend({ }, setMonth( month ) { - if ( this.get( 'locked' ) ) { - return; - } - const viewingDate = this.get( 'viewingDate' ); this.set( 'viewingDate', window.moment( viewingDate ).month( month - 1 ) ); }, setYear( year ) { - if ( this.get( 'locked' ) ) { - return; - } - const viewingDate = this.get( 'viewingDate' ); this.set( 'viewingDate', window.moment( viewingDate ).year( year ) ); @@ -465,54 +482,13 @@ export default Ember.Component.extend({ } ), - /** - * Object of nested year, month, and day values, representing the dates - * supplied by the calendar's content values - * - * @function - * @returns {Object} - */ - contentDates: Ember.computed( - 'content', - 'dateValuePath', - function() { - const content = this.get( 'content' ); - const dates = {}; - const dateValuePath = this.get( 'dateValuePath' ); - - if ( content ) { - content.forEach( ( item ) => { - const date = new Date( Ember.get( item, dateValuePath ) ); - const year = date.getFullYear(); - const month = date.getMonth() + 1; - const day = date.getDate(); - - if ( !dates.hasOwnProperty( year ) ) { - dates[ year ] = {}; - } - - if ( !dates[ year ].hasOwnProperty( month ) ) { - dates[ year ][ month ] = {}; - } - - if ( !dates[ year ][ month ].hasOwnProperty( day ) ) { - dates[ year ][ month ][ day ] = []; - } - - dates[ year ][ month ][ day ].push( item ); - }); - } - - return dates; - } - ), - /** * Get an array of objects representing months in the year view * * Each item contains the following values: - * - {Boolean} active - Whether a content item's date occurs on this month + * - {Boolean} active - Whether the month is currently selected * - {Number} month - The month number in the year (1-12) + * - {String} monthName - The localized string representation of the month * * @function * @returns {Object[]} @@ -560,7 +536,7 @@ export default Ember.Component.extend({ * An array of abbreviated, formatted day names of each week day * * @function - * @returns {ember/Array} + * @returns {Array} */ shortWeekDayNames: Ember.computed( 'locale', @@ -627,19 +603,19 @@ export default Ember.Component.extend({ * An array of objects representing weeks and days in the month view * * Each day object contains the following values: - * - {Boolean} active - Whether a content item occurs on this date - * - {Array} content - Collection of content items occurring on this date - * - {Number} day - The day number of the month (1-31) + * - {Boolean} active - Whether the day is currently selected + * - {Array} events - Collection of event items occurring on this date + * - {Number} dayName - The day number of the month (1-31) + * - {Object} date - A moment object representing the date * - {Boolean} new - Whether the day occurs in the next month * - {Boolean} old - Whether the day occurs in the previous month + * - {Boolean} focused - Whether the day is currently focused + * - {Boolean} restricted - Whether the day is outside of the selectConstraint * * @function * @returns {ember.Array} */ weeksInMonthView: Ember.computed( - // 'contentDates', - // 'showingYear', - // 'selectedDate', 'fixedWeekCount', 'locale', 'selectConstraint', @@ -726,7 +702,7 @@ export default Ember.Component.extend({ * An array of objects representing years in the decade view * * Each object contains the following values: - * - {Boolean} active - Whether a content item occurs on this year + * - {Boolean} active - Whether the selected date is in the year * - {Boolean} new - Whether this year is in the next decade range * - {Boolean} old - Whether this year is in the previous decade range * - {Number} year - The year number diff --git a/addon/templates/components/sl-calendar.hbs b/addon/templates/components/sl-calendar.hbs index 1ae5d27e..c12a0b9b 100644 --- a/addon/templates/components/sl-calendar.hbs +++ b/addon/templates/components/sl-calendar.hbs @@ -1,25 +1,29 @@
{{#if viewingDays}} - - - - - - -
- - - - {{calendarTitle}} - - - -
+ {{#if showControls}} + + + + + + +
+ + + + {{calendarTitle}} + + + +
+ {{else}} + {{calendarTitle}} + {{/if}} @@ -36,7 +40,7 @@ {{#sl-calendar-day action="selectDate" active=day.active - content=day.content + events=day.events new=day.new old=day.old date=day.date @@ -53,25 +57,29 @@ {{/if}} {{#if viewingMonths}} -
- - - - - -
- - - - {{calendarTitle}} - - - -
+ {{#if showControls}} + + + + + + +
+ + + + {{calendarTitle}} + + + +
+ {{else}} + {{calendarTitle}} + {{/if}} @@ -94,25 +102,29 @@ {{/if}} {{#if viewingYears}} -
- - - - - -
- - - - {{calendarTitle}} - - - -
+ {{#if showControls}} + + + + + + +
+ + + + {{calendarTitle}} + + + +
+ {{else}} + {{calendarTitle}} + {{/if}} diff --git a/app/styles/sl-calendar.less b/app/styles/sl-calendar.less index cde2c909..cf6efb06 100644 --- a/app/styles/sl-calendar.less +++ b/app/styles/sl-calendar.less @@ -13,6 +13,13 @@ display: inline-block; + & > div > span.calendar-title { + display: block; + text-align: center; + font-weight: bold; + margin-bottom: @table-condensed-cell-padding; + } + table.calendar-controls { width: 100%; margin-bottom: @table-condensed-cell-padding; @@ -70,6 +77,21 @@ } } + td.has-events { + position: relative; + + &::after { + content: ''; + display: block; + width: 100%; + position: absolute; + bottom: 0; + height: 3px; + background-color: @brand-info; + border-radius: 0 0 @calendar-border-radius-small @calendar-border-radius-small; + } + } + & > tbody > tr > td > span { width: 25%; display: inline-block; diff --git a/tests/dummy/app/routes/demos/sl-calendar.js b/tests/dummy/app/routes/demos/sl-calendar.js index e0a52895..c2ea07de 100644 --- a/tests/dummy/app/routes/demos/sl-calendar.js +++ b/tests/dummy/app/routes/demos/sl-calendar.js @@ -4,8 +4,12 @@ export default Ember.Route.extend({ model() { return Ember.A([ { - date: new Date(), - label: 'Today!' + startDate: window.moment().subtract( 5, 'days' ), + title: 'Some meeting five days ago' + }, + { + startDate: window.moment().add( 3, 'days' ), + title: 'Lunch meeting three days from now' } ]); } diff --git a/tests/dummy/app/templates/demos/sl-calendar.hbs b/tests/dummy/app/templates/demos/sl-calendar.hbs index f7c807a0..afd04e6b 100755 --- a/tests/dummy/app/templates/demos/sl-calendar.hbs +++ b/tests/dummy/app/templates/demos/sl-calendar.hbs @@ -21,7 +21,7 @@
Rendered Component
- {{sl-calendar action="logLabel" content=content fixedWeekCount=true locale="en" selectConstraint=tempdates}} + {{sl-calendar action="logLabel" events=content fixedWeekCount=true locale="en" selectConstraint=tempdates}}
diff --git a/tests/integration/components/sl-calendar-day-test.js b/tests/integration/components/sl-calendar-day-test.js index 60ca2ea6..03eea598 100644 --- a/tests/integration/components/sl-calendar-day-test.js +++ b/tests/integration/components/sl-calendar-day-test.js @@ -81,6 +81,25 @@ test( 'Disabled class is present when in restricted state', function( assert ) { ); }); +test( 'has-events class is present when events are present', function( assert ) { + const events = [ + { + startDate: window.moment( [ 2015, 0, 1 ] ) + } + ]; + + this.set( 'events', events ); + + this.render( hbs` + {{sl-calendar-day events=events}} + ` ); + + assert.ok( + this.$( '>:first-child' ).hasClass( 'has-events' ), + 'Has class "has-events" when events are present' + ); +}); + test( 'Default action is triggered when element is clicked', function( assert ) { assert.expect( 1 ); diff --git a/tests/integration/components/sl-calendar-test.js b/tests/integration/components/sl-calendar-test.js index c948ecf7..a3276733 100755 --- a/tests/integration/components/sl-calendar-test.js +++ b/tests/integration/components/sl-calendar-test.js @@ -4,29 +4,22 @@ import hbs from 'htmlbars-inline-precompile'; import { skip } from 'qunit'; import sinon from 'sinon'; -const testContent = Ember.A([ - { - date: new Date( 2022, 8, 17 ), - label: 'Today!' - } -]); - const multipleTestContent = Ember.A([ { - date: new Date( 2022, 8, 17 ), - label: 'Event 1 Today!' + startDate: moment( [ 2022, 8, 12 ] ), + title: 'Event 1 Today!' }, { - date: new Date( 2022, 8, 17 ), - label: 'Event 2 Today!' + startDate: moment( [ 2022, 8, 12 ] ), + title: 'Event 2 Today!' }, { - date: new Date( 2022, 8, 17 ), - label: 'Event 3 Today!' + startDate: moment( [ 2022, 8, 17 ] ), + title: 'Event 3 Today!' }, { - date: new Date( 2022, 8, 20 ), - label: 'Event 1 Another Day!' + startDate: moment( [ 2022, 8, 20 ] ), + title: 'Event 1 Another Day!' } ]); @@ -84,70 +77,82 @@ test( 'Next and Previous buttons have appropriate classes', function( assert ) { }; assert.ok( - hasButtonClasses( this.$( '.calendar-controls button' ).first() ), + hasButtonClasses( this.$( '>:first-child' ).find( '.calendar-controls button' ).first() ), 'day view previous button has "btn", "btn-xs", and "btn-default" classes' ); assert.ok( - this.$( '.calendar-controls button' ).first().find( 'span' ).hasClass( 'sl-icon-previous' ), + this.$( '>:first-child' ).find( '.calendar-controls button' ).first().find( 'span' ).hasClass( 'sl-icon-previous' ), 'day view previous button has span with "sl-icon-previous" class' ); assert.ok( - hasButtonClasses( this.$( '.calendar-controls button' ).last() ), + hasButtonClasses( this.$( '>:first-child' ).find( '.calendar-controls button' ).last() ), 'day view next button has "btn", "btn-xs", and "btn-default" classes' ); assert.ok( - this.$( '.calendar-controls button' ).last().find( 'span' ).hasClass( 'sl-icon-next' ), + this.$( '>:first-child' ).find( '.calendar-controls button' ).last().find( 'span' ).hasClass( 'sl-icon-next' ), 'day view previous button has span with "sl-icon-next" class' ); - this.$( '.calendar-controls a' ).click(); + this.$( '>:first-child' ).find( '.calendar-controls a' ).click(); assert.ok( - hasButtonClasses( this.$( '.calendar-controls button' ).first() ), + hasButtonClasses( this.$( '>:first-child' ).find( '.calendar-controls button' ).first() ), 'month view previous button has "btn", "btn-xs", and "btn-default" classes' ); assert.ok( - this.$( '.calendar-controls button' ).first().find( 'span' ).hasClass( 'sl-icon-previous' ), + this.$( '>:first-child' ).find( '.calendar-controls button' ).first().find( 'span' ).hasClass( 'sl-icon-previous' ), 'month view previous button has span with "sl-icon-previous" class' ); assert.ok( - hasButtonClasses( this.$( '.calendar-controls button' ).last() ), + hasButtonClasses( this.$( '>:first-child' ).find( '.calendar-controls button' ).last() ), 'month view next button has "btn", "btn-xs", and "btn-default" classes' ); assert.ok( - this.$( '.calendar-controls button' ).last().find( 'span' ).hasClass( 'sl-icon-next' ), + this.$( '>:first-child' ).find( '.calendar-controls button' ).last().find( 'span' ).hasClass( 'sl-icon-next' ), 'month view previous button has span with "sl-icon-next" class' ); - this.$( '.calendar-controls a' ).click(); + this.$( '>:first-child' ).find( '.calendar-controls a' ).click(); assert.ok( - hasButtonClasses( this.$( '.calendar-controls button' ).first() ), + hasButtonClasses( this.$( '>:first-child' ).find( '.calendar-controls button' ).first() ), 'year view previous button has "btn", "btn-xs", and "btn-default" classes' ); assert.ok( - this.$( '.calendar-controls button' ).first().find( 'span' ).hasClass( 'sl-icon-previous' ), + this.$( '>:first-child' ).find( '.calendar-controls button' ).first().find( 'span' ).hasClass( 'sl-icon-previous' ), 'year view previous button has span with "sl-icon-previous" class' ); assert.ok( - hasButtonClasses( this.$( '.calendar-controls button' ).last() ), + hasButtonClasses( this.$( '>:first-child' ).find( '.calendar-controls button' ).last() ), 'year view next button has "btn", "btn-xs", and "btn-default" classes' ); assert.ok( - this.$( '.calendar-controls button' ).last().find( 'span' ).hasClass( 'sl-icon-next' ), + this.$( '>:first-child' ).find( '.calendar-controls button' ).last().find( 'span' ).hasClass( 'sl-icon-next' ), 'year view previous button has span with "sl-icon-next" class' ); }); +test( 'Controls are not available when showControls is false', function( assert ) { + this.render( hbs` + {{sl-calendar showControls=false}} + ` ); + + assert.strictEqual( + this.$( '>:first-child' ).find( '.calendar-controls' ).length, + 0, + 'calendar controls not available when showControls is false' + ); +}); + test( 'Check for classes set on items outside of range in picker', function( assert ) { this.set( 'viewingDate', window.moment( [ 2015, 1, 1 ] ) ); this.set( 'viewMode', 'days' ); @@ -256,37 +261,6 @@ test( 'Setting viewingDate modifies the view correctly', function( assert ) { ); }); -skip( 'Setting dateValuePath modifies the view correctly', function( assert ) { - - const modifiedValuePath = Ember.A([ - { - modifiedDatePath: new Date( 2022, 8, 17 ), - label: 'Today!' - } - ]); - - this.set( 'currentYear', 2022 ); - - this.set( 'currentMonth', 9 ); - - this.set( 'content', modifiedValuePath ); - - this.render( hbs` - {{sl-calendar - content=content - dateValuePath="modifiedDatePath" - currentYear=currentYear - currentMonth=currentMonth - }} - ` ); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.active' ).text().trim(), - 17, - 'Active day is set correctly' - ); -}); - test( 'selectedDate is set correctly', function( assert ) { this.set( 'selectedDate', window.moment( [ 2015, 1, 15 ] ) ); this.set( 'viewingDate', window.moment( [ 2015, 1, 1 ] ) ); @@ -595,67 +569,6 @@ test( 'Navigating Forward and Backward by Decade', function( assert ) { ); }); -skip( 'When Locked, interacting with the view is not Possible', function( assert ) { - - const currentYear = 2022; - this.set( 'currentYear', currentYear ); - - this.set( 'currentMonth', 8 ); - - this.render( hbs` - {{sl-calendar}} - ` ); - - assert.strictEqual( - this.$( '>:first-child' ).hasClass( 'sl-calendar-locked' ), - false, - 'Default rendered component does not have class "sl-calendar-locked"' - ); - - this.render( hbs` - {{sl-calendar - locked=true - currentYear=currentYear - currentMonth=currentMonth - }} - ` ); - - assert.ok( - this.$( '>:first-child' ).hasClass( 'sl-calendar-locked' ), - 'Locked, rendered component has class "sl-calendar-locked"' - ); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - 'August ' + currentYear, - 'The current month is set correctly' - ); - - this.$( '>:first-child' ).find( '.sl-icon-next' ).click(); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - 'August ' + currentYear, - 'The next month is set correctly' - ); - - this.$( '>:first-child' ).find( '.sl-icon-next' ).click(); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - 'August ' + currentYear, - 'The next month is set correctly' - ); - - this.$( '>:first-child' ).find( '.datepicker-switch' ).click(); - - assert.strictEqual( - this.$( '>:first-child' ).find( '.datepicker-switch' ).text().trim(), - 'August ' + currentYear, - 'The next month is set correctly' - ); -}); - test( 'Changing viewMode by View Switcher', function( assert ) { this.set( 'viewingDate', window.moment( [ 2015, 8, 1 ] ) ); this.set( 'viewMode', 'days' ); @@ -726,12 +639,13 @@ test( 'Changing viewMode by Selection', function( assert ) { ); }); -//add assert for fixedweek test( 'All Days are Displayed in Order', function( assert ) { this.set( 'viewingDate', window.moment( [ 2015, 0, 1 ] ) ); + this.set( 'fixedWeekCount', false ); this.render( hbs` {{sl-calendar + fixedWeekCount=fixedWeekCount viewingDate=viewingDate }} ` ); @@ -744,9 +658,23 @@ test( 'All Days are Displayed in Order', function( assert ) { assert.strictEqual( daysString, - '28293031123456789101112131415161718192021222324252627282930311234567', + '2829303112345678910111213141516171819202122232425262728293031', 'All days listed in order for specified month as expected' ); + + this.set( 'fixedWeekCount', true ); + + daysString = ''; + + this.$( '>:first-child' ).find( 'td.day' ).each( function() { + daysString += $( this ).text().trim(); + }); + + assert.strictEqual( + daysString, + '28293031123456789101112131415161718192021222324252627282930311234567', + 'All days listed in order for specified month when fixedWeekCount as expected' + ); }); test( 'All Twelve Months are Displayed in Order', function( assert ) { @@ -792,3 +720,7 @@ test( 'Twelve Years are Displayed in Order', function( assert ) { 'Twelve years are listed in order' ); }); + +skip( 'Wai-Aria keyboard navigation', function( assert ) { + // make sure to include moving across months and retaining focus +}); diff --git a/tests/unit/components/sl-calendar-day-test.js b/tests/unit/components/sl-calendar-day-test.js index 135a7a48..be3752c2 100644 --- a/tests/unit/components/sl-calendar-day-test.js +++ b/tests/unit/components/sl-calendar-day-test.js @@ -20,18 +20,18 @@ test( 'Default property values', function( assert ) { 'ariaRole is "gridcell" by default' ); - assert.strictEqual( - component.get( 'content' ), - null, - 'content is null by default' - ); - assert.strictEqual( component.get( 'date' ), null, 'date is null by default' ); + assert.deepEqual( + component.get( 'events' ), + [], + 'events is an empty array by default' + ); + assert.strictEqual( component.get( 'focused' ), false, @@ -63,16 +63,20 @@ test( 'Action bindings sends action with expected day content', function( assert const done = assert.async(); - const dayContent = { day: 42 }; + const events = [ + { + startDate: window.moment( [ 2015, 0, 1 ] ) + } + ]; this.subject({ action: 'test', - content: dayContent, + events: events, targetObject: { - test( content ) { + test( date, eventData ) { assert.strictEqual( - content, - dayContent, + eventData, + events, 'Test action fired with expected value' ); @@ -105,6 +109,10 @@ test( 'Dependent keys are correct', function( assert ) { 'active' ]; + const hasEventsDependentKeys = [ + 'events' + ]; + const isTodayDependentKeys = [ 'date' ]; @@ -119,6 +127,12 @@ test( 'Dependent keys are correct', function( assert ) { 'Dependent keys are correct for ariaSelected()' ); + assert.deepEqual( + component.hasEvents._dependentKeys, + hasEventsDependentKeys, + 'Dependent keys are correct for hasEvents()' + ); + assert.deepEqual( component.isToday._dependentKeys, isTodayDependentKeys, diff --git a/tests/unit/components/sl-calendar-test.js b/tests/unit/components/sl-calendar-test.js index 795cc302..1459d238 100755 --- a/tests/unit/components/sl-calendar-test.js +++ b/tests/unit/components/sl-calendar-test.js @@ -17,17 +17,11 @@ test( 'Default property values are set correctly', function( assert ) { const component = this.subject(); assert.deepEqual( - component.get( 'content' ), + component.get( 'events' ), [], 'content is [] by default' ); - assert.strictEqual( - component.get( 'dateValuePath' ), - 'date', - 'dateValuePath is "date" by default' - ); - assert.notOk( component.get( 'fixedWeekCount' ), 'fixedWeekCount is false by default' @@ -49,20 +43,14 @@ test( 'Default property values are set correctly', function( assert ) { 'locale is "en" by default' ); - assert.strictEqual( - component.get( 'locked' ), - false, - 'locked is false by default' - ); - - /*assert.strictEqual( + assert.deepEqual( component.get( 'selectConstraint' ), { start: null, end: null }, - 'selectConstraint is ? by default' - );*/ + 'selectConstraint is an object with start and end properties by default' + ); assert.strictEqual( component.get( 'selectedDate' ), @@ -71,21 +59,20 @@ test( 'Default property values are set correctly', function( assert ) { ); assert.strictEqual( - component.get( 'showingMonth' ), - null, - 'showingMonth is null by default' + component.get( 'showControls' ), + true, + 'showControls is true by default' ); assert.strictEqual( - component.get( 'today' ), + component.get( 'showingMonth' ), null, - 'today is null by default' + 'showingMonth is null by default' ); - assert.strictEqual( - component.get( 'viewingDate' ), - null, - 'viewingDate is null by default' + assert.ok( + window.moment().isSame( component.get( 'viewingDate' ), 'day' ), + 'viewingDate is a moment object representing today by default' ); assert.strictEqual( @@ -95,91 +82,206 @@ test( 'Default property values are set correctly', function( assert ) { ); }); -skip( 'Lock mode prevents changing state', function( assert ) { - const component = this.subject({ locked: true }); +skip( 'locale - Setting causes default of en (English) to be updated', function( assert ) { - const initialDecadeStart = component.get( 'decadeStart' ); - component.send( 'changeDecade', 1 ); - assert.strictEqual( - initialDecadeStart, - component.get( 'decadeStart' ), - 'Value decadeStart is unchanged from actions.changeDecade' +}); + +skip( 'contentDates - Verify dates array', function( assert ) { + +}); + +test( 'setDate method sets the viewingDate and selectedDate', function( assert ) { + const selectConstraint = { + start: window.moment( [ 2014, 2, 1 ] ) + }; + + const component = this.subject({ + viewingDate: window.moment( [ 2015, 0, 1 ] ), + selectConstraint: selectConstraint + }); + + const newDate = window.moment( [ 2014, 3, 3 ] ); + + component.setDate( newDate ); + + assert.ok( + component.get( 'selectedDate' ).isSame( newDate, 'day' ), + 'selectedDate was set to the new date' + ); + + assert.ok( + component.get( 'viewingDate' ).isSame( newDate, 'day' ), + 'viewingDate was set to the new date' ); - const initialMonth = component.get( 'currentMonth' ); - component.send( 'changeMonth', 1 ); + const tooEarlyDate = window.moment( [ 2014, 1, 1 ] ); + + component.setDate( tooEarlyDate ); + + assert.notOk( + component.get( 'selectedDate' ).isSame( tooEarlyDate, 'day' ), + 'selectedDate was not set to the new date' + ); + + assert.notOk( + component.get( 'viewingDate' ).isSame( tooEarlyDate, 'day' ), + 'viewingDate was not set to the new date' + ); +}); + +test( 'setMonth method modifies the viewingDate', function( assert ) { + const component = this.subject({ + viewingDate: window.moment( [ 2015, 0, 1 ] ) + }); + + const newMonth = 4; + + component.setMonth( newMonth ); + assert.strictEqual( - initialMonth, - component.get( 'currentMonth' ), - 'Value currentMonth is unchanged from actions.changeMonth' + component.get( 'viewingDate' ).month() + 1, + newMonth, + 'view set to the selected month' ); +}); + +test( 'setYear method modifies the viewingDate', function( assert ) { + const component = this.subject({ + viewingDate: window.moment( [ 2015, 0, 1 ] ) + }); + + const newYear = 2013; + + component.setYear( newYear ); - const initialYear = component.get( 'currentYear' ); - component.send( 'changeYear', 1 ); assert.strictEqual( - initialYear, - component.get( 'currentYear' ), - 'Value currentYear is unchanged from actions.changeYear' + component.get( 'viewingDate' ).year(), + newYear, + 'view set to the selected year' ); +}); + +test( 'calendar title is correctly generated for each viewMode', function( assert ) { + const component = this.subject({ + viewingDate: window.moment( [ 2015, 2, 15 ] ), + viewMode: 'days' + }); - component.send( 'setMonth', initialMonth + 1 ); assert.strictEqual( - initialMonth, - component.get( 'currentMonth' ), - 'Value currentMonth is unchanged from actions.setMonth' + component.get( 'calendarTitle' ), + 'March 2015', + 'Calendar title is correct in days view' ); - const initialViewMode = component.get( 'viewMode' ); - component.send( 'setView', 'something' ); + component.set( 'viewMode', 'months' ); + assert.strictEqual( - initialViewMode, - component.get( 'viewMode' ), - 'Value viewMode is unchanged from actions.setView' + component.get( 'calendarTitle' ), + '2015', + 'Calendar title is correct in days view' ); - component.send( 'setYear', initialYear + 1 ); + component.set( 'viewMode', 'years' ); + assert.strictEqual( - initialYear, - component.get( 'currentYear' ), - 'Value currentYear is unchanged from actions.setYear' + component.get( 'calendarTitle' ), + '2010 - 2019', + 'Calendar title is correct in days view' ); }); -skip( 'locale - Setting causes default of en (English) to be updated', function() { +test( 'shortWeekDayNames - returns array of day names in short name format (Su, Mo, Tu...)', function( assert ) { + const component = this.subject({}); + assert.deepEqual( + component.get( 'shortWeekDayNames' ), + [ 'Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa' ], + 'short week day names are generated correctly' + ); }); -skip( 'contentDates - Verify dates array', function() { +test( 'activeDateChange - active property is set on the correct day object', function( assert ) { + const startingSelected = window.moment( [ 2015, 0, 15 ] ); -}); + const component = this.subject({ + viewingDate: window.moment( [ 2015, 0, 1 ] ), + selectedDate: startingSelected + }); -skip( 'setDate method sets the viewingDate and selectedDate', function() { + function findDay( dateNeedle ) { + const weeksInMonthView = component.get( 'weeksInMonthView' ); -}); + for ( let week = 0; week < weeksInMonthView.length; week++ ) { + for ( let day = 0; day < weeksInMonthView[ week ].length; day++ ) { + if ( weeksInMonthView[ week ][ day ].date.isSame( dateNeedle, 'day' ) ) { + return weeksInMonthView[ week ][ day ]; + } + } + } + }; -skip( 'setMonth method modifies the viewingDate', function() { + assert.ok( + findDay( startingSelected ).active, + 'the correct day is set to "active"' + ); -}); + const newSelected = window.moment( [ 2015, 1, 12 ] ); -skip( 'setYear method modifies the viewingDate', function() { + component.set( 'viewingDate', newSelected ); + component.set( 'selectedDate', newSelected ); + assert.ok( + findDay( newSelected ).active, + 'the correct day is set to "active"' + ); }); -skip( 'setView - viewMode set correctly', function() { +skip( 'applyEvents - events are set on each day object', function() { }); -skip( 'calendar title is correctly generated for each viewMode', function() { +test( 'focusedDateChange - focused property is set on the correct day object', function( assert ) { + const component = this.subject({ + viewingDate: window.moment( [ 2015, 0, 1 ] ) + }); -}); + const newViewing = window.moment( [ 2015, 0, 15 ] ); -skip( 'shortWeekDayNames - returns array of day names in short name format (Su, Mo, Tu...)', function() { + component.set( 'viewingDate', newViewing ); + function findDay( dateNeedle ) { + const weeksInMonthView = component.get( 'weeksInMonthView' ); + + for ( let week = 0; week < weeksInMonthView.length; week++ ) { + for ( let day = 0; day < weeksInMonthView[ week ].length; day++ ) { + if ( weeksInMonthView[ week ][ day ].date.isSame( dateNeedle, 'day' ) ) { + return weeksInMonthView[ week ][ day ]; + } + } + } + }; + + assert.ok( + findDay( newViewing ).focused, + 'the correct day is set to "focused"' + ); }); -//updateShowingMonth? -//focusedDateChange? -//activeDateChange? +test( 'updateShowingMonth - showingMonth is updated', function( assert ) { + const component = this.subject({ + viewingDate: window.moment( [ 2015, 0, 1 ] ) + }); + + const newMonth = 5; + + component.set( 'viewingDate', window.moment( [ 2015, newMonth, 1 ] ) ); + + assert.strictEqual( + component.get( 'showingMonth' ), + newMonth, + 'showingMonth updated correctly' + ); +}); test( 'changeDecade action works', function( assert ) { const component = this.subject({ @@ -229,6 +331,113 @@ test( 'changeYear action works', function( assert ) { ); }); +skip( 'selectDate action works', function( assert ) { + +}); + +test( 'selectMonth action works', function( assert ) { + const component = this.subject({ + viewingDate: window.moment( [ 2015, 0, 1 ] ), + $: function() { + return { + focus: sinon.spy() + } + } + }); + + const newMonth = 8; + + component.send( 'selectMonth', newMonth ); + + assert.strictEqual( + component.get( 'viewMode' ), + 'days', + 'viewMode is switched to "days" when a month is selected' + ); + + assert.strictEqual( + component.get( 'viewingDate' ).month() + 1, + newMonth, + 'viewingDate was changed to the selected month' + ); +}); + +test( 'selectYear action works', function( assert ) { + const component = this.subject({ + viewingDate: window.moment( [ 2015, 0, 1 ] ), + $: function() { + return { + focus: sinon.spy() + } + } + }); + + const newYear = 2013; + + component.send( 'selectYear', newYear ); + + assert.strictEqual( + component.get( 'viewMode' ), + 'months', + 'viewMode is switched to "months" when a year is selected' + ); + + assert.strictEqual( + component.get( 'viewingDate' ).year(), + newYear, + 'viewingDate was changed to the selected year' + ); +}); + +test( 'setView action works', function( assert ) { + const focusSpy = sinon.spy(); + + const component = this.subject({ + viewingDate: window.moment( [ 2015, 0, 1 ] ), + $: function() { + return { + focus: focusSpy + } + } + }); + + assert.strictEqual( + component.get( 'viewMode' ), + 'days', + 'viewMode is "days"' + ); + + component.send( 'setView', 'months' ); + + assert.strictEqual( + component.get( 'viewMode' ), + 'months', + 'viewMode is "months"' + ); + + component.send( 'setView', 'years' ); + + assert.strictEqual( + component.get( 'viewMode' ), + 'years', + 'viewMode is "years"' + ); + + component.send( 'setView', 'days' ); + + assert.strictEqual( + component.get( 'viewMode' ), + 'days', + 'viewMode is "days"' + ); + + assert.strictEqual( + focusSpy.callCount, + 3, + 'component was focused 3 times' + ); +}); + test( 'Decrementing month from January causes year to decrement', function( assert ) { const component = this.subject({ viewingDate: window.moment( [ 2015, 0, 1 ] ) @@ -404,6 +613,11 @@ test( 'Observer keys are correct', function( assert ) { 'selectedDate' ]; + const applyEventsKeys = [ + 'events', + 'weeksInMonthView' + ]; + const focusedDateChangeKeys = [ 'viewingDate' ]; @@ -418,6 +632,12 @@ test( 'Observer keys are correct', function( assert ) { 'Observer keys are correct for activeDateChange()' ); + assert.deepEqual( + component.applyEvents.__ember_observes__, + applyEventsKeys, + 'Observer keys are correct for applyEvents()' + ); + assert.deepEqual( component.focusedDateChange.__ember_observes__, focusedDateChangeKeys, @@ -440,11 +660,6 @@ test( 'Dependent keys are correct', function( assert ) { 'viewMode' ]; - const contentDatesDependentKeys = [ - 'content', - 'dateValuePath' - ]; - const monthsInYearViewDependentKeys = [ 'viewingDate', 'selectedDate', @@ -490,12 +705,6 @@ test( 'Dependent keys are correct', function( assert ) { 'Dependent keys are correct for calendarTitle()' ); - assert.deepEqual( - component.contentDates._dependentKeys, - contentDatesDependentKeys, - 'Dependent keys are correct for contentDates()' - ); - assert.deepEqual( component.monthsInYearView._dependentKeys, monthsInYearViewDependentKeys, From 8421d33e257aebc1c08641b9139b941a825c9e8a Mon Sep 17 00:00:00 2001 From: J Corley Date: Wed, 3 Feb 2016 09:33:04 -0600 Subject: [PATCH 17/25] Additional tests and functionality. ** CALENDAR ** Fix for multiple events on a single date. Added test for passing events. Added test for application of events. ** DATE RANGE PICKER ** End date will now get focus when start date is selected. --- addon/components/sl-calendar.js | 6 +- addon/components/sl-date-range-picker.js | 8 ++ .../components/sl-date-range-picker.hbs | 1 + .../components/sl-calendar-test.js | 89 +++++-------------- .../components/sl-date-range-picker-test.js | 25 ++++++ tests/unit/components/sl-calendar-test.js | 48 +++++++++- .../components/sl-date-range-picker-test.js | 18 ---- 7 files changed, 104 insertions(+), 91 deletions(-) diff --git a/addon/components/sl-calendar.js b/addon/components/sl-calendar.js index 8b7b648d..5dc6da0e 100755 --- a/addon/components/sl-calendar.js +++ b/addon/components/sl-calendar.js @@ -342,6 +342,7 @@ export default Ember.Component.extend({ const weeksInMonthView = this.get( 'weeksInMonthView' ); const eventsPerDay = []; + eventsLoop: for ( let event = 0; event < events.length; event++ ) { const currentEvent = events[ event ]; if ( currentEvent.startDate.isAfter( viewingDate, 'month' ) ) { @@ -357,13 +358,13 @@ export default Ember.Component.extend({ for ( let day = 0; day < eventsPerDay.length; day++ ) { if ( currentEvent.startDate.isSame( eventsPerDay[ day ].date ) ) { eventsPerDay[ day ].events.push( currentEvent ); - continue; + continue eventsLoop; } } eventsPerDay.push( { date: currentEvent.startDate, - events: [].push( currentEvent ) + events: [ currentEvent ] }); } @@ -372,7 +373,6 @@ export default Ember.Component.extend({ for ( let day = 0; day < weeksInMonthView[ week ].length; day++ ) { const date = Ember.get( weeksInMonthView[ week ][ day ], 'date' ); - eventsLoop: for ( let eventDay = 0; eventDay < eventsPerDay.length; eventDay++ ) { if ( date.isSame( eventsPerDay[ eventDay ].date, 'day' ) ) { Ember.set( weeksInMonthView[ week ][ day ], 'events', eventsPerDay[ eventDay ].events ); diff --git a/addon/components/sl-date-range-picker.js b/addon/components/sl-date-range-picker.js index 8c03b591..cf61e8d7 100755 --- a/addon/components/sl-date-range-picker.js +++ b/addon/components/sl-date-range-picker.js @@ -28,6 +28,14 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { // ------------------------------------------------------------------------- // Actions + actions: { + + startSelected( date ) { + this.$( '.sl-daterange-end-date input' ).focus(); + } + + }, + // ------------------------------------------------------------------------- // Events diff --git a/addon/templates/components/sl-date-range-picker.hbs b/addon/templates/components/sl-date-range-picker.hbs index d02d15e4..95bd19ce 100755 --- a/addon/templates/components/sl-date-range-picker.hbs +++ b/addon/templates/components/sl-date-range-picker.hbs @@ -11,6 +11,7 @@ format=format selectConstraint=endSelectConstraint selectedDate=startDate + action="startSelected" }} {{sl-date-picker diff --git a/tests/integration/components/sl-calendar-test.js b/tests/integration/components/sl-calendar-test.js index a3276733..2e2d7125 100755 --- a/tests/integration/components/sl-calendar-test.js +++ b/tests/integration/components/sl-calendar-test.js @@ -4,21 +4,21 @@ import hbs from 'htmlbars-inline-precompile'; import { skip } from 'qunit'; import sinon from 'sinon'; -const multipleTestContent = Ember.A([ +const testEvents = Ember.A([ { - startDate: moment( [ 2022, 8, 12 ] ), + startDate: moment( [ 2015, 2, 12 ] ), title: 'Event 1 Today!' }, { - startDate: moment( [ 2022, 8, 12 ] ), + startDate: moment( [ 2015, 2, 12 ] ), title: 'Event 2 Today!' }, { - startDate: moment( [ 2022, 8, 17 ] ), + startDate: moment( [ 2015, 2, 17 ] ), title: 'Event 3 Today!' }, { - startDate: moment( [ 2022, 8, 20 ] ), + startDate: moment( [ 2015, 2, 20 ] ), title: 'Event 1 Another Day!' } ]); @@ -328,85 +328,36 @@ test( 'Action fires when day is clicked', function( assert ) { this.$( '>:first-child' ).find( '.today' ).click(); }); -skip( 'Action passes through expected objects in content array', function( assert ) { - - assert.expect( 8 ); +test( 'Action passes through expected objects in content array', function( assert ) { + assert.expect( 1 ); const done = assert.async(); - this.set( 'currentYear', 2022 ); + this.set( 'viewingDate', window.moment( [ 2015, 2, 15 ] ) ); + this.set( 'selectedDate', window.moment( [ 2015, 2, 12 ] ) ); - this.set( 'currentMonth', 9 ); - - this.set( 'content', multipleTestContent ); + this.set( 'events', testEvents ); this.render( hbs` {{sl-calendar action="testAction" - content=content - currentYear=currentYear - currentMonth=currentMonth + events=events + viewingDate=viewingDate + selectedDate=selectedDate }} ` ); - this.on( 'testAction', ( dateContent ) => { - - // This group of asserts verifies the multiple events on Sep. 17th - if ( 'Event 1 Today!' === dateContent[ 0 ].label ) { - assert.strictEqual( - dateContent[ 0 ].date.toString(), - 'Sat Sep 17 2022 00:00:00 GMT-0500 (CDT)', - 'The date property was passed through' - ); - - assert.strictEqual( - dateContent[ 0 ].label, - 'Event 1 Today!', - 'The label property was passed through' - ); - - assert.strictEqual( - dateContent[ 1 ].date.toString(), - 'Sat Sep 17 2022 00:00:00 GMT-0500 (CDT)', - 'The date property was passed through' - ); - - assert.strictEqual( - dateContent[ 1 ].label, - 'Event 2 Today!', - 'The label property was passed through' - ); - - assert.strictEqual( - dateContent[ 2 ].date.toString(), - 'Sat Sep 17 2022 00:00:00 GMT-0500 (CDT)', - 'The date property was passed through' - ); - - assert.strictEqual( - dateContent[ 2 ].label, - 'Event 3 Today!', - 'The label property was passed through' - ); - // This group of asserts verifies the event on Sep. 20th - } else { - assert.strictEqual( - dateContent[ 0 ].date.toString(), - 'Tue Sep 20 2022 00:00:00 GMT-0500 (CDT)', - 'The date property was passed through' - ); - - assert.strictEqual( - dateContent[ 0 ].label, - 'Event 1 Another Day!', - 'The label property was passed through' - ); - } + this.on( 'testAction', ( date, events ) => { + assert.strictEqual( + events.length, + 2, + 'two events retrieved' + ); done(); }); - this.$( '>:first-child' ).find( '.active' ).click(); + this.$( '>:first-child' ).find( '.selected' ).click(); }); test( 'Setting viewMode modifies the view correctly', function( assert ) { diff --git a/tests/integration/components/sl-date-range-picker-test.js b/tests/integration/components/sl-date-range-picker-test.js index 44ec7d2a..833ff6c0 100644 --- a/tests/integration/components/sl-date-range-picker-test.js +++ b/tests/integration/components/sl-date-range-picker-test.js @@ -219,3 +219,28 @@ test( 'helpText is accepted as a parameter', function( assert ) { 'The "helpText" property text was set' ); }); + +test( 'Change focus to end date input upon start date selection', function( assert ) { + assert.expect( 1 ); + + const done = assert.async(); + + this.render( hbs` + {{sl-date-range-picker}} + ` ); + + this.$( '>:first-child' ).find( '.sl-daterange-end-date input' ).on( 'focus', function() { + assert.ok( + true, + 'focus was given to the end date input' + ); + + done(); + }); + + const startDatePicker = this.$( '>:first-child' ).find( '.sl-daterange-start-date' ); + + startDatePicker.find( 'input' ).on( 'focus', function() { + startDatePicker.find( 'td.day:first' ).click(); + }).trigger( 'focus' ); +}); diff --git a/tests/unit/components/sl-calendar-test.js b/tests/unit/components/sl-calendar-test.js index 1459d238..baf8ad73 100755 --- a/tests/unit/components/sl-calendar-test.js +++ b/tests/unit/components/sl-calendar-test.js @@ -3,6 +3,25 @@ import { moduleForComponent, test } from 'ember-qunit'; import sinon from 'sinon'; import { skip } from 'qunit'; +const testEvents = Ember.A([ + { + startDate: moment( [ 2015, 2, 12 ] ), + title: 'Event 1 Today!' + }, + { + startDate: moment( [ 2015, 2, 12 ] ), + title: 'Event 2 Today!' + }, + { + startDate: moment( [ 2015, 2, 17 ] ), + title: 'Event 3 Today!' + }, + { + startDate: moment( [ 2015, 2, 20 ] ), + title: 'Event 1 Another Day!' + } +]); + moduleForComponent( 'sl-calendar', 'Unit | Component | sl calendar', { needs: [ 'component:sl-calendar-day', @@ -236,8 +255,35 @@ test( 'activeDateChange - active property is set on the correct day object', fun ); }); -skip( 'applyEvents - events are set on each day object', function() { +test( 'applyEvents - events are set on each day object', function( assert ) { + const component = this.subject({ + viewingDate: window.moment( [ 2015, 2, 1 ] ), + events: testEvents + }); + + function findDay( dateNeedle ) { + const weeksInMonthView = component.get( 'weeksInMonthView' ); + + for ( let week = 0; week < weeksInMonthView.length; week++ ) { + for ( let day = 0; day < weeksInMonthView[ week ].length; day++ ) { + if ( weeksInMonthView[ week ][ day ].date.isSame( dateNeedle, 'day' ) ) { + return weeksInMonthView[ week ][ day ]; + } + } + } + }; + + assert.strictEqual( + findDay( testEvents[ 0 ].startDate ).events.length, + 2, + 'event day has 3 events as expected' + ); + assert.strictEqual( + findDay( testEvents[ 3 ].startDate ).events.length, + 1, + 'event day has 1 event as expected' + ); }); test( 'focusedDateChange - focused property is set on the correct day object', function( assert ) { diff --git a/tests/unit/components/sl-date-range-picker-test.js b/tests/unit/components/sl-date-range-picker-test.js index 836a727b..f3177b5b 100755 --- a/tests/unit/components/sl-date-range-picker-test.js +++ b/tests/unit/components/sl-date-range-picker-test.js @@ -75,24 +75,6 @@ test( 'Default property values are set correctly', function( assert ) { ); }); -test( 'Change focus to end date input upon start date change', function( assert ) { - const component = this.subject(); - this.render(); - - const daterangeEndDate = component.get( 'endDateInput' ); - const spy = sinon.spy( daterangeEndDate, 'trigger' ); - - component.get( 'startDateInput' ).trigger( 'changeDate' ); - - assert.ok( - spy.calledWithExactly( 'focus' ), - 'End date input was given focus on start date change' - ); - - $( '.datepicker' ).remove(); - daterangeEndDate.trigger.restore(); -}); - test( 'Earliest end date is based on selectConstraint and startDate', function( assert ) { const component = this.subject(); From 88a46de61b1b906a9eabd6d85788f5fb7709bf42 Mon Sep 17 00:00:00 2001 From: J Corley Date: Wed, 3 Feb 2016 14:39:50 -0600 Subject: [PATCH 18/25] updated docblocks and documentation. --- addon/components/sl-calendar-day.js | 70 ++++++- addon/components/sl-calendar-month.js | 6 +- addon/components/sl-calendar-year.js | 6 +- addon/components/sl-calendar.js | 185 ++++++++++++++---- addon/components/sl-date-picker.js | 142 ++++++++++---- addon/components/sl-date-range-picker.js | 69 ++++++- .../dummy/app/templates/demos/sl-calendar.hbs | 32 ++- .../app/templates/demos/sl-date-picker.hbs | 91 ++------- .../templates/demos/sl-date-range-picker.hbs | 49 ++--- .../components/sl-date-range-picker-test.js | 23 ++- 10 files changed, 462 insertions(+), 211 deletions(-) diff --git a/addon/components/sl-calendar-day.js b/addon/components/sl-calendar-day.js index 5d137f5b..1443a183 100644 --- a/addon/components/sl-calendar-day.js +++ b/addon/components/sl-calendar-day.js @@ -12,6 +12,7 @@ export default Ember.Component.extend({ // ------------------------------------------------------------------------- // Attributes + /** @type {String[]} */ attributeBindings: [ 'ariaSelected:aria-selected', 'tabIndex' @@ -38,13 +39,15 @@ export default Ember.Component.extend({ // ------------------------------------------------------------------------- // Actions + /** @type {Object} */ actions: {}, // ------------------------------------------------------------------------- // Events /** - * @function + * Send the click event up to sl-calendar + * * @returns {undefined} */ click() { @@ -54,6 +57,12 @@ export default Ember.Component.extend({ this.sendAction( 'action', date, events ); }, + /** + * Focus this date on insert. + * Needed for keyboard navigation across months. + * + * @returns {undefined} + */ didInsertElement() { this._super( ...arguments ); @@ -64,18 +73,39 @@ export default Ember.Component.extend({ // Properties /** - * Whether the calendar day this cell represents is actively selected day + * Whether the calendar day this cell represents is actively selected * * @type {Boolean} */ active: false, + /** + * The role attribute to apply + * + * @private + * @type {String} + */ ariaRole: 'gridcell', + /** + * The specific moment date that this cell represents + * + * @type {?moment} + */ date: null, + /** + * An array of events bound to the date this cell represents + * + * @type {Object[]} + */ events: [], + /** + * Whether this day is currently focused by keyboard navigation + * + * @type {Boolean} + */ focused: false, /** @@ -94,11 +124,23 @@ export default Ember.Component.extend({ */ old: false, + /** + * Whether the calendar day this cell represents is restricted by parent + * calendar's selectConstraint + * + * @type {Boolean} + */ restricted: false, // ------------------------------------------------------------------------- // Observers + /** + * When tabIndex changes, check if we should apply focus. + * + * @function + * @returns {undefined} + */ focus: Ember.observer( 'tabIndex', function() { @@ -113,6 +155,12 @@ export default Ember.Component.extend({ // ------------------------------------------------------------------------- // Methods + /** + * Sets aria-selected attribute when active state is true. + * + * @function + * @returns {?Boolean} + */ ariaSelected: Ember.computed( 'active', function() { @@ -121,6 +169,12 @@ export default Ember.Component.extend({ } ), + /** + * Whether there are events bound to this date. + * + * @function + * @returns {Boolean} + */ hasEvents: Ember.computed( 'events', function() { @@ -128,6 +182,12 @@ export default Ember.Component.extend({ } ), + /** + * Calculate if this day is today's date. + * + * @function + * @returns {Boolean} + */ isToday: Ember.computed( 'date', function() { @@ -135,6 +195,12 @@ export default Ember.Component.extend({ } ), + /** + * Sets tabIndex attribute based on focused property. + * + * @function + * @returns {Number} + */ tabIndex: Ember.computed( 'focused', function() { diff --git a/addon/components/sl-calendar-month.js b/addon/components/sl-calendar-month.js index 6c0d9ef1..1a7cbc1a 100755 --- a/addon/components/sl-calendar-month.js +++ b/addon/components/sl-calendar-month.js @@ -32,7 +32,8 @@ export default Ember.Component.extend({ // Events /** - * @function + * Send the click event up to sl-calendar + * * @returns {undefined} */ click() { @@ -43,8 +44,7 @@ export default Ember.Component.extend({ // Properties /** - * Whether the month that this component represents is selected by the - * overall calendar component + * Whether the month that this component represents is actively selected * * @type {Boolean} */ diff --git a/addon/components/sl-calendar-year.js b/addon/components/sl-calendar-year.js index 1492ff18..8a955ed1 100644 --- a/addon/components/sl-calendar-year.js +++ b/addon/components/sl-calendar-year.js @@ -38,7 +38,8 @@ export default Ember.Component.extend({ // Events /** - * @function + * Send the click event up to sl-calendar + * * @returns {undefined} */ click() { @@ -49,8 +50,7 @@ export default Ember.Component.extend({ // Properties /** - * Whether the year this component represents is the currently active year - * of the parent calendar component + * Whether the year this component represents is actively selected * * @type {Boolean} */ diff --git a/addon/components/sl-calendar.js b/addon/components/sl-calendar.js index 5dc6da0e..984c3404 100755 --- a/addon/components/sl-calendar.js +++ b/addon/components/sl-calendar.js @@ -28,6 +28,7 @@ export default Ember.Component.extend({ // ------------------------------------------------------------------------- // Attributes + /** @type {String[]} */ attributeBindings: [ 'tabIndex' ], @@ -151,18 +152,33 @@ export default Ember.Component.extend({ // ------------------------------------------------------------------------- // Events + /** + * Track focus on the component + * + * @returns {undefined} + */ focusIn() { this._super( ...arguments ); this.set( 'hasFocus', true ); }, + /** + * Track focus on the component + * + * @returns {undefined} + */ focusOut() { this._super( ...arguments ); this.set( 'hasFocus', false ); }, + /** + * Capture keyDown events for WAI-ARIA + * + * @returns {undefined} + */ keyDown( event ) { this._super( ...arguments ); @@ -269,13 +285,26 @@ export default Ember.Component.extend({ */ events: [], - // if true, always shows 6 weeks + /** + * Whether to always show six weeks or a minimum of weeks. + * + * @type {Boolean} + */ fixedWeekCount: false, - // boolean: whether calendar is focusable for keyboard navigation + /** + * Whether to allow the calendar to receive focus. + * Required for keyboard navigation. + * + * @type {Boolean} + */ focusable: true, - // whether or not the calendar currently has focus + /** + * Whether the calendar currently has focus. + * + * @type {Boolean} + */ hasFocus: false, /** @@ -285,22 +314,46 @@ export default Ember.Component.extend({ */ locale: 'en', - // constrain selectable dates + /** + * Constraints to enforce against selection of dates. + * An object of start and end Moment properties. + * + * @type {Object} + */ selectConstraint: { start: null, end: null }, - // currently selected date: represented by moment object + /** + * The currently selected date. + * + * @type {moment} + */ selectedDate: null, + /** + * Whether to show controls for changing the view. + * + * @type {Boolean} + */ showControls: true, - // the currently shown month - // used as a computed trigger for building list of weeks in month + /** + * The currently shown month number. + * Helps determine if the calendar should be re-rendered. + * + * @private + * @type {?Number} + */ showingMonth: null, - // currently viewed date: represented by moment object + /** + * The currently viewed date. + * Determines what month and year to display. + * + * @type {moment} + */ viewingDate: null, /** @@ -313,6 +366,12 @@ export default Ember.Component.extend({ // ------------------------------------------------------------------------- // Observers + /** + * Keeps the day sub components up to date with the currently selected date. + * + * @function + * @returns {undefined} + */ activeDateChange: Ember.observer( 'selectedDate', function() { @@ -333,6 +392,12 @@ export default Ember.Component.extend({ } ), + /** + * Keeps the day sub components up to date with the events array. + * + * @function + * @returns {undefined} + */ applyEvents: Ember.observer( 'events', 'weeksInMonthView', @@ -385,6 +450,12 @@ export default Ember.Component.extend({ } ), + /** + * Keeps the day sub components up to date with the currently viewed date. + * + * @function + * @returns {undefined} + */ focusedDateChange: Ember.observer( 'viewingDate', function() { @@ -405,6 +476,12 @@ export default Ember.Component.extend({ } ), + /** + * Updates the showingMonth property to track when the calendar switches month. + * + * @function + * @returns {undefined} + */ updateShowingMonth: Ember.observer( 'viewingDate', function() { @@ -415,40 +492,6 @@ export default Ember.Component.extend({ // ------------------------------------------------------------------------- // Methods - setDate( date ) { - const selectConstraint = this.get( 'selectConstraint' ); - - if ( selectConstraint.start ) { - if ( date.isBefore( selectConstraint.start ) ) { - console.log( 'start' ); - return; - } - } - - if ( selectConstraint.end ) { - if ( date.isAfter( selectConstraint.end ) ) { - console.log( 'end' ); - return; - } - } - - this.set( 'selectedDate', window.moment( date ) ); - this.set( 'viewingDate', window.moment( date ) ); - return true; - }, - - setMonth( month ) { - const viewingDate = this.get( 'viewingDate' ); - - this.set( 'viewingDate', window.moment( viewingDate ).month( month - 1 ) ); - }, - - setYear( year ) { - const viewingDate = this.get( 'viewingDate' ); - - this.set( 'viewingDate', window.moment( viewingDate ).year( year ) ); - }, - /** * Locale and viewMode based string title for the calendar * @@ -532,6 +575,58 @@ export default Ember.Component.extend({ } ), + /** + * Sets the viewingDate to the specified date. + * + * @param {moment} date - the date to set + * @returns {Boolean} - true if date passes constraint check + */ + setDate( date ) { + const selectConstraint = this.get( 'selectConstraint' ); + + if ( selectConstraint.start ) { + if ( date.isBefore( selectConstraint.start ) ) { + console.log( 'start' ); + return false; + } + } + + if ( selectConstraint.end ) { + if ( date.isAfter( selectConstraint.end ) ) { + console.log( 'end' ); + return false; + } + } + + this.set( 'selectedDate', window.moment( date ) ); + this.set( 'viewingDate', window.moment( date ) ); + return true; + }, + + /** + * Sets the viewingDate to the specified month. + * + * @param {Number} month - the month to set + * @returns {undefined} + */ + setMonth( month ) { + const viewingDate = this.get( 'viewingDate' ); + + this.set( 'viewingDate', window.moment( viewingDate ).month( month - 1 ) ); + }, + + /** + * Sets the viewingDate to the specified year. + * + * @param {Number} year - the year to set + * @returns {undefined} + */ + setYear( year ) { + const viewingDate = this.get( 'viewingDate' ); + + this.set( 'viewingDate', window.moment( viewingDate ).year( year ) ); + }, + /** * An array of abbreviated, formatted day names of each week day * @@ -553,6 +648,12 @@ export default Ember.Component.extend({ } ), + /** + * Sets tabIndex attribute based on focusable property. + * + * @function + * @returns {Number} + */ tabIndex: Ember.computed( 'focusable', function() { diff --git a/addon/components/sl-date-picker.js b/addon/components/sl-date-picker.js index aaf9bc89..33b09829 100755 --- a/addon/components/sl-date-picker.js +++ b/addon/components/sl-date-picker.js @@ -37,25 +37,50 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa /** @type {Object} */ actions: { + /** + * Watch focus-out from input helper + * + * @function actions:inputBlurred + * @returns {undefined} + */ inputBlurred() { this.trigger( 'focusOut' ); - - // this.updateValue(); }, + /** + * Watch focus-in from input helper + * + * @function actions:inputFocused + * @returns {undefined} + */ inputFocused() { this.trigger( 'focusIn' ); }, + /** + * Watch for keyUp events from input helper + * Triggers parsing of input value if a non-command key was pressed + * + * @function actions:inputKeyUp + * @param {String} value - Current value property of the input + * @param {Event} event - keyUp event object + * @returns {undefined} + */ inputKeyUp( value, event ) { - console.log( 'input key up' ); - // not a tab or modifier key if ( event.keyCode !== 9 && ( event.keyCode > 18 || event.keyCode < 16 ) ) { this.checkInput(); } }, + /** + * sl-calendar has triggered a date selection + * Triggers bound action "action" + * + * @function actions:selectDate + * @param {moment} date - date selected by sl-calendar + * @returns {undefined} + */ selectDate( date ) { this.selectDate( date ); @@ -71,11 +96,15 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa // ------------------------------------------------------------------------- // Events + /** + * Track focus on the component for opening sl-calendar + * + * @returns {undefined} + */ focusIn( event ) { this._super( ...arguments ); this.set( 'hasFocus', true ); - // this.set( 'isOpen', true ); const losingFocus = this.get( 'losingFocus' ); Ember.run.cancel( losingFocus ); @@ -89,31 +118,26 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa } }, + /** + * Track focus on the component for closing sl-calendar + * + * @returns {undefined} + */ focusOut( event ) { this._super( ...arguments ); - const runNext = Ember.run.next( this, () => { - /*if ( !this.get( 'hasFocus' ) ) { - this.set( 'isOpen', false ); - }*/ - this.set( 'hasFocus', false ); }); this.set( 'losingFocus', runNext ); }, - /*keyPress() { - console.log( 'date picker: keypress' ); - },*/ - // ------------------------------------------------------------------------- // Properties /** - * Whether or not to close the datepicker immediately when a date - * is selected + * Whether to close the datepicker immediately when a date is selected * * @type {Boolean} */ @@ -127,31 +151,19 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa disabled: false, /** - * Whether or not to force parsing of the input value when the picker is - * closed + * The date format for input field + * Only effects how selected day is represented in the input value + * This is a moment-based format string * - * When an invalid date is left in the input field by the user, the picker - * will forcibly parse that value, and set the input's value to the new, - * valid date, conforming to the given _format_. - * - * @type {Boolean} + * @type {?String} */ - // forceParse: true, + format: null, /** - * The date format - * - * Combination of the following: - * - d, dd: Numeric date, no leading zero and leading zero, respectively - * - D, DD: Abbreviated and full weekday names, respectively - * - m, mm: Numeric month, no leading zero and leading zero, respectively - * - M, MM: Abbreviated and full month names, respectively - * - yy, yyyy: 2- and 4-digit years, respectively + * Whether the component has focus and should display the sl-calendar * - * @type {?String} + * @type {Boolean} */ - format: null, - hasFocus: false, /** @@ -168,8 +180,19 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa */ label: null, + /** + * The locale string to use for moment date values + * + * @type {String} + */ locale: 'en', + /** + * An Ember.run object for cancelling closing of sl-calendar + * + * @private + * @type {Boolean|Object} + */ losingFocus: false, /** @@ -179,11 +202,21 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa */ placeholder: null, + /** + * A constraint object to pass throught to sl-calendar + * + * @type {Object} + */ selectConstraint: { start: null, end: null }, + /** + * The currently selected date + * + * @type {moment} + */ selectedDate: null, /** @@ -199,9 +232,13 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa // ------------------------------------------------------------------------- // Methods + /** + * Check if the client entered string can be parsed to a moment + * + * @returns {undefined} + */ checkInput() { let value = this.get( 'value' ); - // const format = this.get( 'format' ); const parseFormats = this.get( 'parseFormats' ); const selectConstraint = this.get( 'selectConstraint' ); @@ -209,13 +246,10 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa return; } - // console.log( 'from value observer: ', this.get( 'value' ) ); - value = value.replace( /\W+/g, "-" ); const date = window.moment( value, parseFormats, this.get( 'locale' ), true ); - // console.log( 'date entered: ', date.format( format ) ); - // return; + if ( selectConstraint.start ) { if ( date.isBefore( selectConstraint.start ) ) { return; @@ -235,6 +269,13 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa this.set( 'selectedDate', date ); }, + + /** + * The string to parse client input against + * Defaults to long format from moment + * + * @returns {String} + */ formatString: Ember.computed( 'format', function() { @@ -242,6 +283,11 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa } ), + /** + * Create an array of format strings to compare typed input against. + * + * @returns {String[]} + */ parseFormats: Ember.computed( 'locale', function() { @@ -258,10 +304,21 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa } ), + /** + * Select a date. + * + * @param {moment} date - date to select + * @returns {undefined} + */ selectDate( date ) { this.set( 'selectedDate', date ); }, + /** + * Generate value for input field. + * + * @returns {String} + */ value: Ember.computed( 'selectedDate', 'formatString', @@ -277,6 +334,11 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa } ), + /** + * Sets the viewingDate to the selectedDate. + * + * @returns {moment} + */ viewingDate: Ember.computed( 'selectedDate', function() { diff --git a/addon/components/sl-date-range-picker.js b/addon/components/sl-date-range-picker.js index cf61e8d7..2ef76d81 100755 --- a/addon/components/sl-date-range-picker.js +++ b/addon/components/sl-date-range-picker.js @@ -28,8 +28,16 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { // ------------------------------------------------------------------------- // Actions + /** @type {Object} */ actions: { + /** + * Move focus to the endDate picker when startDate is selected + * + * @function actions:startSelected + * @param {moment} date - The date that was selected + * @returns {undefined} + */ startSelected( date ) { this.$( '.sl-daterange-end-date input' ).focus(); } @@ -43,11 +51,18 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { // Properties /** - * The value for the endDate input + * The currently selected date in the end datepicker + * + * @type {moment} + */ + endDate: null, + + /** + * The placeholder text that the end datepicker input should show * * @type {?String} */ - // endDateValue: null, + endDatePlaceholder: null, /** * The string format for date values @@ -57,35 +72,63 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { format: null, /** - * The value for the startDate input + * The help text below the date-range-pickers * * @type {?String} */ - // startDateValue: null, + helpText: null, + /** + * The label text above the date-range-pickers' input fields + * + * @type {?String} + */ label: null, - startDate: null, - - endDate: null, + /** + * The locale string to use for moment date values + * + * @type {String} + */ + locale: 'en', + /** + * Constraints to enforce against selection of dates. + * An object of start and end Moment properties. + * + * @type {Object} + */ selectConstraint: { start: null, end: null }, - locale: 'en', + /** + * The currently selected date in the start datepicker + * + * @type {moment} + */ + startDate: null, + /** + * The placeholder text that the start datepicker input should show + * + * @type {?String} + */ startDatePlaceholder: null, - endDatePlaceholder: null, - // ------------------------------------------------------------------------- // Observers // ------------------------------------------------------------------------- // Methods + /** + * Modification of selectConstraint for the startDate picker + * + * @function + * @returns {Object} + */ endSelectConstraint: Ember.computed( 'endDate', 'selectConstraint', @@ -100,6 +143,12 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { } ), + /** + * Modification of selectConstraint for the endDate picker + * + * @function + * @returns {Object} + */ startSelectConstraint: Ember.computed( 'startDate', 'selectConstraint', diff --git a/tests/dummy/app/templates/demos/sl-calendar.hbs b/tests/dummy/app/templates/demos/sl-calendar.hbs index afd04e6b..52346ddb 100755 --- a/tests/dummy/app/templates/demos/sl-calendar.hbs +++ b/tests/dummy/app/templates/demos/sl-calendar.hbs @@ -31,23 +31,41 @@
{{#property-text name="action" type="Function"}} - Action to call when a day is clicked that contains one of the content dates. An array of content objects with dates occurring on the clicked date will be returned to this action. + Action to call when a day is clicked. The date and an array of events occurring on the clicked date will be returned to this action. {{/property-text}} - {{#property-text name="content" type="Object[]"}} - Bound array of objects with date values, looked up using the dateValuePath property. + {{#property-text name="events" type="Object[]"}} + Array of objects with properties: startDate, endDate, title. {{/property-text}} - {{#property-text name="dateValuePath" type="String" default="\"date\""}} - Path to the content objects' date value. + {{#property-text name="fixedWeekCount" type="Boolean" default="false"}} + Whether to show a full six weeks for every month. + {{/property-text}} + + {{#property-text name="focusable" type="Boolean" default="true"}} + Whether to allow the calendar to gain focus. Also allows keyboard navigation of the calendar. {{/property-text}} {{#property-text name="locale" type="String" default="\"en\""}} The locale string to use for moment date formats. {{/property-text}} - {{#property-text name="locked" type="Boolean" default="false"}} - When true, the view is locked in the initial mode, and forward and back buttons are disabled. + {{#property-text name="selectConstraint" type="Object"}} + Object representation of a date constraint. Has properties: start, end. + Dates outside of this range will not be selectable. + {{/property-text}} + + {{#property-text name="selectedDate" type="Moment"}} + A moment object representing the currently selected date. + {{/property-text}} + + {{#property-text name="showControls" type="Boolean" default="true"}} + Whether to show the calendar controls for changing the view. + {{/property-text}} + + {{#property-text name="viewingDate" type="Moment"}} + A moment object representing the currently viewed date. + The calendar determines which month and year to show based on this date. {{/property-text}} {{#property-text name="viewMode" type="String" default="\"days\""}} diff --git a/tests/dummy/app/templates/demos/sl-date-picker.hbs b/tests/dummy/app/templates/demos/sl-date-picker.hbs index f3e256f5..ceee5e96 100755 --- a/tests/dummy/app/templates/demos/sl-date-picker.hbs +++ b/tests/dummy/app/templates/demos/sl-date-picker.hbs @@ -1,5 +1,5 @@

sl-date-picker

-

An input component to select date values. Based on bootstrap-datepicker.

+

A component to use for picking dates from a calendar, using {{#link-to "demos.sl-calendar"}}sl-calendar{{/link-to}}.


@@ -46,75 +46,33 @@ Action to call when the date is changed. {{/property-text}} - {{#property-text name="autoclose" type="Boolean" default="true"}} - Whether or not to close the datepicker immediately when a date is selected. - {{/property-text}} - - {{#property-text name="calendarWeeks" type="Boolean" default="false"}} - When true, show week numbers to the left of the week rows. - {{/property-text}} - - {{#property-text name="clearBtn" type="Boolean" default="false"}} - When true, displays a "Clear" button at the bottom of the datepicker to clear the input value. If autoclose is also set to true, this button will also close the datepicker. - {{/property-text}} - - {{#property-text name="daysOfWeekDisabled" type="Array"}} - Days of the week that should be disabled. Values are 0 (Sunday) to 6 (Saturday). Multiple values should be comma-separated. + {{#property-text name="autoClose" type="Boolean" default="true"}} + Whether to close the datepicker immediately when a date is selected. {{/property-text}} {{#property-text name="disabled" type="String" default="false"}} When true, the input field is disabled and the datepicker will never display. {{/property-text}} - {{#property-text name="endDate" type="Date/String"}} - The latest date that may be selected. All later dates will be disabled. - {{/property-text}} - - {{#property-text name="forceParse" type="Boolean" default="true"}} - When true, forces parsing of the input value when the picker is close. That is, when an invalid date is left in the input field by the user, the picker will forcibly parse that value, and set the input's value to the new, valid date, conforming to the given format. + {{#property-text name="format" type="String"}} + The formatting to be applied to typed dates and selected dates in the input field. + This format is seeded by moment long format when not provided. {{/property-text}} - {{#property-text name="format" type="String" default="\"mm/dd/yyyy\""}} - The date format; combination of d, dd, D, DD, m, mm, M, MM, yy, yyyy -
    -
  • d, dd : Numeric date, no leading zero and leading zero, respectively
  • -
  • D, DD : Abbreviated and full weekday names, respectively
  • -
  • m, mm : Numeric month, no leading zero and leading zero, respectively
  • -
  • M, MM : Abbreviated and full month names, respectively
  • -
  • yy, yyyy : 2- and 4-digit years, respectively
  • -
+ {{#property-text name="hasFocus" type="Boolean" default="false"}} + Whether the component has focus. Triggers opening of sl-calendar. {{/property-text}} {{#property-text name="helpText" type="String"}} The help text below the datepicker's input field. {{/property-text}} - {{#property-text name="inputs" type="Array"}} - A list of inputs to be used in a range picker, which will be attached to the selected element. Allows for explicitly creating a range picker on a non-standard element. - {{/property-text}} - - {{#property-text name="keyboardNavigation" type="Boolean" default="true"}} - Whether or not to allow date navigation by arrow keys. - {{/property-text}} - {{#property-text name="label" type="String"}} The label text above the datepicker's input field. {{/property-text}} - {{#property-text name="language" type="String" default="\"en\""}} - The IETF code of the language to use for month and day names. - {{/property-text}} - - {{#property-text name="minViewMode" type="String"}} - Set a limit for the view mode. Accepts "days", "months", or "years". - {{/property-text}} - - {{#property-text name="multidate" type="Boolean/Number" default="false"}} - Enable multidate picking. Each date in month view acts as a toggle button, keeping track of which dates the user has selected in order. If a number is given, the picker will limit how many dates can be selected to that number, dropping the oldest dates from the list when the number is exceeded. true equates to no limit. The input’s value (if present) is set to a string generated by joining the dates, formatted, with multidateSeparator. - {{/property-text}} - - {{#property-text name="orientation" type="String" default="\"auto\""}} - A space-separated string consisting of one or two of "left" or "right", "top" or "bottom", and "auto" (may be omitted). Refers to the location of the picker popup's "anchor". + {{#property-text name="locale" type="String" default="\"en\""}} + The locale string to use for moment date formats. {{/property-text}} {{#property-text name="placeholder" type="String"}} @@ -125,31 +83,20 @@ Popover content text. {{/property-text}} - {{#property-text name="startDate" type="Date/String"}} - The earliest date that may be selected. All earlier dates will be disabled. - {{/property-text}} - - {{#property-text name="startView" type="String" default="\"month\""}} - The view that the calendar's datepicker should show when created. - {{/property-text}} - - {{#property-text name="title" type="String"}} - Tooltip text string, or becomes popover title with supplied popover property. + {{#property-text name="selectConstraint" type="Object"}} + Object representation of a date constraint. Has properties: start, end. + Passes through to sl-calendar for selection constraint. {{/property-text}} - {{#property-text name="todayBtn" type="Boolean/String" default="false"}} - Displays a "Today" button at the bottom of the datepicker to select the current date. If true, the "Today" button will only move the current date into view. If "linked", the current date will also be selected. + {{#property-text name="selectedDate" type="moment"}} + A moment object representing the currently selected date. {{/property-text}} - {{#property-text name="todayHighlight" type="Boolean" default="false"}} - When true, highlight the current date. + {{#property-text name="viewMode" type="String" default="\"days\""}} + The view to display the calendar in; "days", "months", or "years". {{/property-text}} - {{#property-text name="value" type="String"}} - The date either selected by the datepicker or entered by the user. - {{/property-text}} - - {{#property-text name="weekStart" type="Number/String"}} - Day of the week to start on. 0 (Sunday) to 6 (Saturday). + {{#property-text name="title" type="String"}} + Tooltip text string, or becomes popover title with supplied popover property. {{/property-text}}
diff --git a/tests/dummy/app/templates/demos/sl-date-range-picker.hbs b/tests/dummy/app/templates/demos/sl-date-range-picker.hbs index c702f8ea..0b7f0b75 100755 --- a/tests/dummy/app/templates/demos/sl-date-range-picker.hbs +++ b/tests/dummy/app/templates/demos/sl-date-range-picker.hbs @@ -9,10 +9,10 @@
Template
\{{sl-date-range-picker
-    label="Select date range"
-    startDatePlaceholder="Select start date"
-    endDatePlaceholder="Select end date"
-}}
+ label="Select date range" + startDatePlaceholder="Select start date" + endDatePlaceholder="Select end date" + }}
@@ -43,38 +43,41 @@

Properties

+ {{#property-text name="endDate" type="moment"}} + The selected date in the end date picker. + {{/property-text}} + {{#property-text name="endDatePlaceholder" type="String"}} The placeholder attribute text for the end date input. {{/property-text}} - {{#property-text name="endDateValue" type="String" default="null"}} - The binding value for the endDate input. + {{#property-text name="format" type="String"}} + The formatting to be applied to typed dates and selected dates in the input fields. + This value is passed through to each sl-date-picker. {{/property-text}} - {{#property-text name="format" type="String" default="\"mm/dd/yyyy\""}} - The date format used for both inputs; combination of d, dd, D, DD, m, mm, M, MM, yy, yyyy -
    -
  • d, dd : Numeric date, no leading zero and leading zero, respectively
  • -
  • D, DD : Abbreviated and full weekday names, respectively
  • -
  • m, mm : Numeric month, no leading zero and leading zero, respectively
  • -
  • M, MM : Abbreviated and full month names, respectively
  • -
  • yy, yyyy : 2- and 4-digit years, respectively
  • -
+ {{#property-text name="helpText" type="String"}} + The help text below the date-range-picker's input fields. {{/property-text}} - {{#property-text name="maxDate" type="Date/String" default="null"}} - The latest possible date for the range. + {{#property-text name="label" type="String"}} + The label text above the date-range-picker's input fields. {{/property-text}} - {{#property-text name="minDate" type="Date/String" default="null"}} - The earliest possible date for the range. + {{#property-text name="locale" type="String" default="\"en\""}} + The locale string to use for moment date formats. + This value is passed through to each sl-date-picker. {{/property-text}} - {{#property-text name="startDatePlaceholder" type="String"}} - The placeholder attribute text for the start date input. + {{#property-text name="selectConstraint" type="Object"}} + Object representation of a date constraint. Has properties: start, end. + {{/property-text}} + + {{#property-text name="startDate" type="moment"}} + The selected date in the start date picker. {{/property-text}} - {{#property-text name="startDateValue" type="String" default="null"}} - The binding value for the startDate input. + {{#property-text name="startDatePlaceholder" type="String"}} + The placeholder attribute text for the start date input. {{/property-text}}
diff --git a/tests/integration/components/sl-date-range-picker-test.js b/tests/integration/components/sl-date-range-picker-test.js index 833ff6c0..0a721f53 100644 --- a/tests/integration/components/sl-date-range-picker-test.js +++ b/tests/integration/components/sl-date-range-picker-test.js @@ -225,22 +225,27 @@ test( 'Change focus to end date input upon start date selection', function( asse const done = assert.async(); - this.render( hbs` - {{sl-date-range-picker}} - ` ); - - this.$( '>:first-child' ).find( '.sl-daterange-end-date input' ).on( 'focus', function() { + const mockFocus = function() { assert.ok( true, 'focus was given to the end date input' ); done(); - }); + }; + + this.set( 'mock', function() { + return { focus: mockFocus } + } ); + + this.render( hbs` + {{sl-date-range-picker + $=mock + }} + ` ); const startDatePicker = this.$( '>:first-child' ).find( '.sl-daterange-start-date' ); - startDatePicker.find( 'input' ).on( 'focus', function() { - startDatePicker.find( 'td.day:first' ).click(); - }).trigger( 'focus' ); + startDatePicker.find( 'input' ).trigger( 'focusin' ); + startDatePicker.find( 'td.day:first' ).click(); }); From 54f3154734e203acbd4472d3ee9b8d1f478b773a Mon Sep 17 00:00:00 2001 From: J Corley Date: Wed, 3 Feb 2016 14:58:59 -0600 Subject: [PATCH 19/25] lint cleanup --- addon/components/sl-date-picker.js | 10 ++--- addon/components/sl-date-range-picker.js | 3 +- .../components/sl-calendar-day-test.js | 2 +- .../components/sl-calendar-month-test.js | 2 +- .../components/sl-calendar-test.js | 40 +++++++++++-------- .../components/sl-calendar-year-test.js | 2 +- .../components/sl-date-picker-test.js | 2 +- .../components/sl-date-range-picker-test.js | 3 +- tests/unit/components/sl-calendar-day-test.js | 3 +- tests/unit/components/sl-calendar-test.js | 12 +++--- tests/unit/components/sl-date-picker-test.js | 11 +++-- .../components/sl-date-range-picker-test.js | 14 +++---- 12 files changed, 56 insertions(+), 48 deletions(-) diff --git a/addon/components/sl-date-picker.js b/addon/components/sl-date-picker.js index 33b09829..9adbb374 100755 --- a/addon/components/sl-date-picker.js +++ b/addon/components/sl-date-picker.js @@ -123,7 +123,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa * * @returns {undefined} */ - focusOut( event ) { + focusOut() { this._super( ...arguments ); const runNext = Ember.run.next( this, () => { @@ -246,7 +246,7 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa return; } - value = value.replace( /\W+/g, "-" ); + value = value.replace( /\W+/g, '-' ); const date = window.moment( value, parseFormats, this.get( 'locale' ), true ); @@ -295,9 +295,9 @@ export default Ember.Component.extend( ComponentInputId, TooltipEnabled, Namespa const localeData = window.moment().localeData(); formats.push( - localeData.longDateFormat( 'L' ).replace( /\W+/g, "-" ), - localeData.longDateFormat( 'LL' ).replace( /\W+/g, "-" ), - localeData.longDateFormat( 'L' ).replace( 'DD', 'D' ).replace( 'MM', 'M' ).replace( /\W+/g, "-" ) + localeData.longDateFormat( 'L' ).replace( /\W+/g, '-' ), + localeData.longDateFormat( 'LL' ).replace( /\W+/g, '-' ), + localeData.longDateFormat( 'L' ).replace( 'DD', 'D' ).replace( 'MM', 'M' ).replace( /\W+/g, '-' ) ); return formats; diff --git a/addon/components/sl-date-range-picker.js b/addon/components/sl-date-range-picker.js index 2ef76d81..ab313e89 100755 --- a/addon/components/sl-date-range-picker.js +++ b/addon/components/sl-date-range-picker.js @@ -35,10 +35,9 @@ export default Ember.Component.extend( ComponentInputId, Namespace, { * Move focus to the endDate picker when startDate is selected * * @function actions:startSelected - * @param {moment} date - The date that was selected * @returns {undefined} */ - startSelected( date ) { + startSelected() { this.$( '.sl-daterange-end-date input' ).focus(); } diff --git a/tests/integration/components/sl-calendar-day-test.js b/tests/integration/components/sl-calendar-day-test.js index 03eea598..06e7380e 100644 --- a/tests/integration/components/sl-calendar-day-test.js +++ b/tests/integration/components/sl-calendar-day-test.js @@ -1,7 +1,7 @@ import { moduleForComponent, test } from 'ember-qunit'; import hbs from 'htmlbars-inline-precompile'; -moduleForComponent('sl-calendar-day', 'Integration | Component | sl calendar day', { +moduleForComponent( 'sl-calendar-day', 'Integration | Component | sl calendar day', { integration: true }); diff --git a/tests/integration/components/sl-calendar-month-test.js b/tests/integration/components/sl-calendar-month-test.js index 6e2fe9e0..e8e0ce5f 100644 --- a/tests/integration/components/sl-calendar-month-test.js +++ b/tests/integration/components/sl-calendar-month-test.js @@ -1,7 +1,7 @@ import { moduleForComponent, test } from 'ember-qunit'; import hbs from 'htmlbars-inline-precompile'; -moduleForComponent('sl-calendar-month', 'Integration | Component | sl calendar month', { +moduleForComponent( 'sl-calendar-month', 'Integration | Component | sl calendar month', { integration: true }); diff --git a/tests/integration/components/sl-calendar-test.js b/tests/integration/components/sl-calendar-test.js index 2e2d7125..c7a3ace3 100755 --- a/tests/integration/components/sl-calendar-test.js +++ b/tests/integration/components/sl-calendar-test.js @@ -2,7 +2,6 @@ import Ember from 'ember'; import { moduleForComponent, test } from 'ember-qunit'; import hbs from 'htmlbars-inline-precompile'; import { skip } from 'qunit'; -import sinon from 'sinon'; const testEvents = Ember.A([ { @@ -76,68 +75,77 @@ test( 'Next and Previous buttons have appropriate classes', function( assert ) { return hasClasses; }; + let previousButton = this.$( '>:first-child' ).find( '.calendar-controls button' ).first(); + let nextButton = this.$( '>:first-child' ).find( '.calendar-controls button' ).last(); + assert.ok( - hasButtonClasses( this.$( '>:first-child' ).find( '.calendar-controls button' ).first() ), + hasButtonClasses( previousButton ), 'day view previous button has "btn", "btn-xs", and "btn-default" classes' ); assert.ok( - this.$( '>:first-child' ).find( '.calendar-controls button' ).first().find( 'span' ).hasClass( 'sl-icon-previous' ), + previousButton.find( 'span' ).hasClass( 'sl-icon-previous' ), 'day view previous button has span with "sl-icon-previous" class' ); assert.ok( - hasButtonClasses( this.$( '>:first-child' ).find( '.calendar-controls button' ).last() ), + hasButtonClasses( nextButton ), 'day view next button has "btn", "btn-xs", and "btn-default" classes' ); assert.ok( - this.$( '>:first-child' ).find( '.calendar-controls button' ).last().find( 'span' ).hasClass( 'sl-icon-next' ), - 'day view previous button has span with "sl-icon-next" class' + nextButton.find( 'span' ).hasClass( 'sl-icon-next' ), + 'day view next button has span with "sl-icon-next" class' ); this.$( '>:first-child' ).find( '.calendar-controls a' ).click(); + previousButton = this.$( '>:first-child' ).find( '.calendar-controls button' ).first(); + nextButton = this.$( '>:first-child' ).find( '.calendar-controls button' ).last(); + assert.ok( - hasButtonClasses( this.$( '>:first-child' ).find( '.calendar-controls button' ).first() ), + hasButtonClasses( previousButton ), 'month view previous button has "btn", "btn-xs", and "btn-default" classes' ); assert.ok( - this.$( '>:first-child' ).find( '.calendar-controls button' ).first().find( 'span' ).hasClass( 'sl-icon-previous' ), + previousButton.find( 'span' ).hasClass( 'sl-icon-previous' ), 'month view previous button has span with "sl-icon-previous" class' ); assert.ok( - hasButtonClasses( this.$( '>:first-child' ).find( '.calendar-controls button' ).last() ), + hasButtonClasses( nextButton ), 'month view next button has "btn", "btn-xs", and "btn-default" classes' ); assert.ok( - this.$( '>:first-child' ).find( '.calendar-controls button' ).last().find( 'span' ).hasClass( 'sl-icon-next' ), - 'month view previous button has span with "sl-icon-next" class' + nextButton.find( 'span' ).hasClass( 'sl-icon-next' ), + 'month view next button has span with "sl-icon-next" class' ); this.$( '>:first-child' ).find( '.calendar-controls a' ).click(); + previousButton = this.$( '>:first-child' ).find( '.calendar-controls button' ).first(); + nextButton = this.$( '>:first-child' ).find( '.calendar-controls button' ).last(); + assert.ok( - hasButtonClasses( this.$( '>:first-child' ).find( '.calendar-controls button' ).first() ), + hasButtonClasses( previousButton ), 'year view previous button has "btn", "btn-xs", and "btn-default" classes' ); assert.ok( - this.$( '>:first-child' ).find( '.calendar-controls button' ).first().find( 'span' ).hasClass( 'sl-icon-previous' ), + previousButton.find( 'span' ).hasClass( 'sl-icon-previous' ), 'year view previous button has span with "sl-icon-previous" class' ); assert.ok( - hasButtonClasses( this.$( '>:first-child' ).find( '.calendar-controls button' ).last() ), + hasButtonClasses( nextButton ), 'year view next button has "btn", "btn-xs", and "btn-default" classes' ); assert.ok( - this.$( '>:first-child' ).find( '.calendar-controls button' ).last().find( 'span' ).hasClass( 'sl-icon-next' ), - 'year view previous button has span with "sl-icon-next" class' + nextButton.find( 'span' ).hasClass( 'sl-icon-next' ), + 'year view next button has span with "sl-icon-next" class' ); }); diff --git a/tests/integration/components/sl-calendar-year-test.js b/tests/integration/components/sl-calendar-year-test.js index e0c6034e..04433dcd 100644 --- a/tests/integration/components/sl-calendar-year-test.js +++ b/tests/integration/components/sl-calendar-year-test.js @@ -1,7 +1,7 @@ import { moduleForComponent, test } from 'ember-qunit'; import hbs from 'htmlbars-inline-precompile'; -moduleForComponent('sl-calendar-year', 'Integration | Component | sl calendar year', { +moduleForComponent( 'sl-calendar-year', 'Integration | Component | sl calendar year', { integration: true }); diff --git a/tests/integration/components/sl-date-picker-test.js b/tests/integration/components/sl-date-picker-test.js index fa26faf4..6950226a 100644 --- a/tests/integration/components/sl-date-picker-test.js +++ b/tests/integration/components/sl-date-picker-test.js @@ -175,7 +175,7 @@ test( 'placeholder is accepted as a parameter', function( assert ) { test( 'Selected day is set in the input field', function( assert ) { const selectedDate = window.moment( [ 2015, 0, 5 ] ); - const format = "MM/DD/YYYY"; + const format = 'MM/DD/YYYY'; this.set( 'selectedDate', selectedDate ); this.set( 'format', format ); diff --git a/tests/integration/components/sl-date-range-picker-test.js b/tests/integration/components/sl-date-range-picker-test.js index 0a721f53..8376bec3 100644 --- a/tests/integration/components/sl-date-range-picker-test.js +++ b/tests/integration/components/sl-date-range-picker-test.js @@ -1,7 +1,6 @@ import Ember from 'ember'; import { moduleForComponent, test } from 'ember-qunit'; import hbs from 'htmlbars-inline-precompile'; -import { skip } from 'qunit'; moduleForComponent( 'sl-date-range-picker', 'Integration | Component | sl date range picker', { afterEach() { @@ -235,7 +234,7 @@ test( 'Change focus to end date input upon start date selection', function( asse }; this.set( 'mock', function() { - return { focus: mockFocus } + return { focus: mockFocus }; } ); this.render( hbs` diff --git a/tests/unit/components/sl-calendar-day-test.js b/tests/unit/components/sl-calendar-day-test.js index be3752c2..e2cf7d2f 100644 --- a/tests/unit/components/sl-calendar-day-test.js +++ b/tests/unit/components/sl-calendar-day-test.js @@ -1,4 +1,3 @@ -import Ember from 'ember'; import { moduleForComponent, test } from 'ember-qunit'; moduleForComponent( 'sl-calendar-day', 'Unit | Component | sl calendar day', { @@ -16,7 +15,7 @@ test( 'Default property values', function( assert ) { assert.strictEqual( component.get( 'ariaRole' ), - "gridcell", + 'gridcell', 'ariaRole is "gridcell" by default' ); diff --git a/tests/unit/components/sl-calendar-test.js b/tests/unit/components/sl-calendar-test.js index baf8ad73..2c0e19ba 100755 --- a/tests/unit/components/sl-calendar-test.js +++ b/tests/unit/components/sl-calendar-test.js @@ -237,7 +237,7 @@ test( 'activeDateChange - active property is set on the correct day object', fun } } } - }; + } assert.ok( findDay( startingSelected ).active, @@ -271,7 +271,7 @@ test( 'applyEvents - events are set on each day object', function( assert ) { } } } - }; + } assert.strictEqual( findDay( testEvents[ 0 ].startDate ).events.length, @@ -305,7 +305,7 @@ test( 'focusedDateChange - focused property is set on the correct day object', f } } } - }; + } assert.ok( findDay( newViewing ).focused, @@ -387,7 +387,7 @@ test( 'selectMonth action works', function( assert ) { $: function() { return { focus: sinon.spy() - } + }; } }); @@ -414,7 +414,7 @@ test( 'selectYear action works', function( assert ) { $: function() { return { focus: sinon.spy() - } + }; } }); @@ -443,7 +443,7 @@ test( 'setView action works', function( assert ) { $: function() { return { focus: focusSpy - } + }; } }); diff --git a/tests/unit/components/sl-date-picker-test.js b/tests/unit/components/sl-date-picker-test.js index ff7011b0..17118760 100755 --- a/tests/unit/components/sl-date-picker-test.js +++ b/tests/unit/components/sl-date-picker-test.js @@ -71,11 +71,14 @@ test( 'Default properties are set correctly', function( assert ) { 'placeholder is null by default' ); - /*assert.strictEqual( + assert.deepEqual( component.get( 'selectConstraint' ), - true, - 'selectConstraint is ? by default' - );*/ + { + start: null, + end: null + }, + 'selectConstraint is an object with start and end properties by default' + ); assert.strictEqual( component.get( 'viewMode' ), diff --git a/tests/unit/components/sl-date-range-picker-test.js b/tests/unit/components/sl-date-range-picker-test.js index f3177b5b..66753cdb 100755 --- a/tests/unit/components/sl-date-range-picker-test.js +++ b/tests/unit/components/sl-date-range-picker-test.js @@ -1,7 +1,4 @@ -import Ember from 'ember'; import { moduleForComponent, test } from 'ember-qunit'; -import { skip } from 'qunit'; -import sinon from 'sinon'; import ComponentInputId from 'sl-ember-components/mixins/sl-component-input-id'; moduleForComponent( @@ -56,11 +53,14 @@ test( 'Default property values are set correctly', function( assert ) { 'locale is "en" by default' ); - /*assert.strictEqual( + assert.deepEqual( component.get( 'selectConstraint' ), - true, - 'selectConstraint is ? by default' - );*/ + { + start: null, + end: null + }, + 'selectConstraint is an object with start and end properties by default' + ); assert.strictEqual( component.get( 'startDate' ), From d23d6357d78d637e19c4104e92d2ace7124f9a12 Mon Sep 17 00:00:00 2001 From: J Corley Date: Thu, 4 Feb 2016 10:07:07 -0600 Subject: [PATCH 20/25] Last push and clean up. Fixed action tests for calendar sub components. ** CALENDAR ** Added wai-aria keyboard navigation test. Removed control+end and control+home navigation these were removed in most recent wai-aria spec. Changed shift+pageup and shift+pagedown to use control key instead, in accordance with wai-aria. Removed commented code. Removed console logs. ** CALENDAR DAY ** Changed tabIndex to return -1 instead of null due to an issue where Ember is not removing the attribute. --- addon/components/sl-calendar-day.js | 2 +- addon/components/sl-calendar.js | 27 +--- .../components/sl-calendar-test.js | 129 +++++++++++++++++- tests/unit/components/sl-calendar-day-test.js | 14 +- .../unit/components/sl-calendar-month-test.js | 1 - tests/unit/components/sl-calendar-test.js | 107 +++++++++++++-- .../unit/components/sl-calendar-year-test.js | 1 - 7 files changed, 234 insertions(+), 47 deletions(-) diff --git a/addon/components/sl-calendar-day.js b/addon/components/sl-calendar-day.js index 1443a183..b449d644 100644 --- a/addon/components/sl-calendar-day.js +++ b/addon/components/sl-calendar-day.js @@ -204,7 +204,7 @@ export default Ember.Component.extend({ tabIndex: Ember.computed( 'focused', function() { - return this.get( 'focused' ) ? 0 : null; + return this.get( 'focused' ) ? 0 : -1; } ) diff --git a/addon/components/sl-calendar.js b/addon/components/sl-calendar.js index 984c3404..a32adf3d 100755 --- a/addon/components/sl-calendar.js +++ b/addon/components/sl-calendar.js @@ -205,7 +205,7 @@ export default Ember.Component.extend({ case 33: // page up timePeriod = 'months'; - if ( event.shiftKey ) { + if ( event.ctrlKey ) { timePeriod = 'years'; } this.set( 'viewingDate', viewingDate.subtract( 1, timePeriod ) ); @@ -213,26 +213,18 @@ export default Ember.Component.extend({ case 34: // page down timePeriod = 'months'; - if ( event.shiftKey ) { + if ( event.ctrlKey ) { timePeriod = 'years'; } this.set( 'viewingDate', viewingDate.add( 1, timePeriod ) ); break; case 35: // end - timePeriod = 'month'; - if ( event.ctrlKey ) { - timePeriod = 'year'; - } - this.set( 'viewingDate', viewingDate.endOf( timePeriod ) ); + this.set( 'viewingDate', viewingDate.endOf( 'month' ) ); break; case 36: // home - timePeriod = 'month'; - if ( event.ctrlKey ) { - timePeriod = 'year'; - } - this.set( 'viewingDate', viewingDate.startOf( timePeriod ) ); + this.set( 'viewingDate', viewingDate.startOf( 'month' ) ); break; case 32: // space @@ -258,20 +250,11 @@ export default Ember.Component.extend({ this._super( ...arguments ); const today = window.moment(); - const selectConstraint = this.get( 'selectConstraint' ); if ( !this.get( 'viewingDate' ) ) { this.set( 'viewingDate', today ); } - /*for ( let constraint in selectConstraint ) { - selectConstraint[ constraint ] = window.moment( selectConstraint[ constraint ] ); - if ( !selectConstraint[ constraint ].isValid ) { - // throw an error or warning here - } - } - this.set( 'selectConstraint', selectConstraint );*/ - this.applyEvents(); }, @@ -586,14 +569,12 @@ export default Ember.Component.extend({ if ( selectConstraint.start ) { if ( date.isBefore( selectConstraint.start ) ) { - console.log( 'start' ); return false; } } if ( selectConstraint.end ) { if ( date.isAfter( selectConstraint.end ) ) { - console.log( 'end' ); return false; } } diff --git a/tests/integration/components/sl-calendar-test.js b/tests/integration/components/sl-calendar-test.js index c7a3ace3..4541ed70 100755 --- a/tests/integration/components/sl-calendar-test.js +++ b/tests/integration/components/sl-calendar-test.js @@ -1,7 +1,6 @@ import Ember from 'ember'; import { moduleForComponent, test } from 'ember-qunit'; import hbs from 'htmlbars-inline-precompile'; -import { skip } from 'qunit'; const testEvents = Ember.A([ { @@ -680,6 +679,130 @@ test( 'Twelve Years are Displayed in Order', function( assert ) { ); }); -skip( 'Wai-Aria keyboard navigation', function( assert ) { - // make sure to include moving across months and retaining focus +test( 'Wai-Aria keyboard navigation', function( assert ) { + this.set( 'viewingDate', window.moment( [ 2016, 0, 15 ] ) ); + this.set( 'selectedDate', window.moment( [ 2016, 0, 15 ] ) ); + + this.render( hbs` + {{sl-calendar + viewingDate=viewingDate + selectedDate=selectedDate + }} + ` ); + + const calendar = this.$( '>:first-child' ); + + calendar.trigger( 'focusin' ); + + let event = new jQuery.Event( 'keydown' ); + event.keyCode = 33; + calendar.trigger( event ); + + assert.ok( + this.get( 'viewingDate' ).isSame( window.moment( [ 2015, 11, 15 ] ), 'day' ), + 'correctly decreased the date by one month' + ); + + event = new jQuery.Event( 'keydown' ); + event.keyCode = 34; + calendar.trigger( event ); + + assert.ok( + this.get( 'viewingDate' ).isSame( window.moment( [ 2016, 0, 15 ] ), 'day' ), + 'correctly increased the date by one month' + ); + + event = new jQuery.Event( 'keydown' ); + event.keyCode = 35; + calendar.trigger( event ); + + assert.ok( + this.get( 'viewingDate' ).isSame( window.moment( [ 2016, 0, 31 ] ), 'day' ), + 'correctly moved to the last day in the current month' + ); + + event = new jQuery.Event( 'keydown' ); + event.keyCode = 36; + calendar.trigger( event ); + + assert.ok( + this.get( 'viewingDate' ).isSame( window.moment( [ 2016, 0, 1 ] ), 'day' ), + 'correctly moved to the first day in the current month' + ); + + event = new jQuery.Event( 'keydown' ); + event.keyCode = 37; + calendar.trigger( event ); + + assert.ok( + this.get( 'viewingDate' ).isSame( window.moment( [ 2015, 11, 31 ] ), 'day' ), + 'correctly decreased the date by one day' + ); + + event = new jQuery.Event( 'keydown' ); + event.keyCode = 38; + calendar.trigger( event ); + + assert.ok( + this.get( 'viewingDate' ).isSame( window.moment( [ 2015, 11, 24 ] ), 'day' ), + 'correctly decreased the date by one week' + ); + + event = new jQuery.Event( 'keydown' ); + event.keyCode = 39; + calendar.trigger( event ); + + assert.ok( + this.get( 'viewingDate' ).isSame( window.moment( [ 2015, 11, 25 ] ), 'day' ), + 'correctly increased the date by one day' + ); + + event = new jQuery.Event( 'keydown' ); + event.keyCode = 40; + calendar.trigger( event ); + + assert.ok( + this.get( 'viewingDate' ).isSame( window.moment( [ 2016, 0, 1 ] ), 'day' ), + 'correctly increased the date by one week' + ); + + event = new jQuery.Event( 'keydown' ); + event.keyCode = 33; + event.ctrlKey = true; + calendar.trigger( event ); + + assert.ok( + this.get( 'viewingDate' ).isSame( window.moment( [ 2015, 0, 1 ] ), 'day' ), + 'correctly decreased the date by one year' + ); + + event = new jQuery.Event( 'keydown' ); + event.keyCode = 34; + event.ctrlKey = true; + calendar.trigger( event ); + + assert.ok( + this.get( 'viewingDate' ).isSame( window.moment( [ 2016, 0, 1 ] ), 'day' ), + 'correctly increased the date by one year' + ); + + event = new jQuery.Event( 'keydown' ); + event.keyCode = 32; + calendar.trigger( event ); + + assert.ok( + this.get( 'selectedDate' ).isSame( window.moment( [ 2016, 0, 1 ] ), 'day' ), + 'correctly set the selectedDate to the currently focused date' + ); + + this.set( 'viewingDate', window.moment( [ 2016, 0, 15 ] ) ); + + event = new jQuery.Event( 'keydown' ); + event.keyCode = 13; + calendar.trigger( event ); + + assert.ok( + this.get( 'selectedDate' ).isSame( window.moment( [ 2016, 0, 15 ] ), 'day' ), + 'correctly set the selectedDate to the currently focused date' + ); }); diff --git a/tests/unit/components/sl-calendar-day-test.js b/tests/unit/components/sl-calendar-day-test.js index e2cf7d2f..e2ad3522 100644 --- a/tests/unit/components/sl-calendar-day-test.js +++ b/tests/unit/components/sl-calendar-day-test.js @@ -56,9 +56,8 @@ test( 'Default property values', function( assert ) { ); }); -//need to re-visit this one test( 'Action bindings sends action with expected day content', function( assert ) { - assert.expect( 1 ); + assert.expect( 2 ); const done = assert.async(); @@ -68,15 +67,24 @@ test( 'Action bindings sends action with expected day content', function( assert } ]; + const currentDate = window.moment( [ 2014, 1, 4 ] ); + this.subject({ action: 'test', events: events, + date: currentDate, targetObject: { test( date, eventData ) { + assert.strictEqual( + date, + currentDate, + 'Test action fired with proper date' + ); + assert.strictEqual( eventData, events, - 'Test action fired with expected value' + 'Test action fired with expected events' ); done(); diff --git a/tests/unit/components/sl-calendar-month-test.js b/tests/unit/components/sl-calendar-month-test.js index 7c726767..86d84efd 100644 --- a/tests/unit/components/sl-calendar-month-test.js +++ b/tests/unit/components/sl-calendar-month-test.js @@ -23,7 +23,6 @@ test( 'Default property values', function( assert ) { ); }); -//need to re-visit this one test( 'Action binding sends action with month', function( assert ) { this.subject({ action: 'test', diff --git a/tests/unit/components/sl-calendar-test.js b/tests/unit/components/sl-calendar-test.js index 2c0e19ba..5929b305 100755 --- a/tests/unit/components/sl-calendar-test.js +++ b/tests/unit/components/sl-calendar-test.js @@ -1,7 +1,6 @@ import Ember from 'ember'; import { moduleForComponent, test } from 'ember-qunit'; import sinon from 'sinon'; -import { skip } from 'qunit'; const testEvents = Ember.A([ { @@ -101,14 +100,6 @@ test( 'Default property values are set correctly', function( assert ) { ); }); -skip( 'locale - Setting causes default of en (English) to be updated', function( assert ) { - -}); - -skip( 'contentDates - Verify dates array', function( assert ) { - -}); - test( 'setDate method sets the viewingDate and selectedDate', function( assert ) { const selectConstraint = { start: window.moment( [ 2014, 2, 1 ] ) @@ -377,8 +368,42 @@ test( 'changeYear action works', function( assert ) { ); }); -skip( 'selectDate action works', function( assert ) { +test( 'selectDate action works', function( assert ) { + assert.expect( 2 ); + + const done = assert.async(); + + const selectedDate = window.moment( [ 2015, 0, 1 ] ); + const events = [ + { + startDate: window.moment( [ 2015, 1, 4 ] ) + } + ]; + + const component = this.subject({ + action: 'test', + events: events, + date: selectedDate, + targetObject: { + test( sentDate, sentEvents ) { + assert.strictEqual( + sentDate, + selectedDate, + 'date value is as expected' + ); + + assert.deepEqual( + sentEvents, + events, + 'events are sent as expected' + ); + + done(); + } + } + }); + component.send( 'selectDate', selectedDate, events ); }); test( 'selectMonth action works', function( assert ) { @@ -573,7 +598,6 @@ test( 'View mode is settable to "years"', function( assert ) { ); }); -//old/new/active? test( 'Weeks for month view are assembled correctly', function( assert ) { const component = this.subject({ viewingDate: window.moment( [ 2015, 1, 1 ] ) @@ -612,9 +636,50 @@ test( 'Weeks for month view are assembled correctly', function( assert ) { ); }); -//active? +test( 'Weeks for month view are assembled with correct properties', function( assert ) { + const component = this.subject({ + viewingDate: window.moment( [ 2016, 2, 1 ] ), + selectedDate: window.moment( [ 2016, 2, 16 ] ), + fixedWeekCount: true + }); + + const allWeeks = component.get( 'weeksInMonthView' ); + const flattenedWeeks = []; + + for ( let weekGroup = 0; weekGroup < allWeeks.length; weekGroup++ ) { + for ( let week = 0; week < allWeeks[ weekGroup ].length; week++ ) { + flattenedWeeks.push( allWeeks[ weekGroup ][ week ] ); + } + } + + const firstTwo = flattenedWeeks.slice( 0, 1 ); + const lastTwo = flattenedWeeks.slice( 33 ); + + assert.ok( + firstTwo.every( ( day ) => { + return day.old; + }), + 'Expected days have the old property set' + ); + + assert.ok( + lastTwo.every( ( day ) => { + return day.new; + }), + 'Expected days have the new property set' + ); + + assert.ok( + flattenedWeeks[ 17 ].active, + 'Expected day has active property set' + ); +}); + test( 'Months for year view are assembled correctly', function( assert ) { - const component = this.subject(); + const component = this.subject({ + viewingDate: window.moment( [ 2015, 2, 1 ] ), + selectedDate: window.moment( [ 2015, 2, 1 ] ) + }); const allMonths = component.get( 'monthsInYearView' ); const flattenedMonths = []; @@ -630,11 +695,18 @@ test( 'Months for year view are assembled correctly', function( assert ) { 12, 'Twelve months were generated for the year view' ); + + assert.ok( + flattenedMonths[2].active, + 'Expected month is set as active' + ); }); -//active? test( 'Years for decade view are assembled correctly', function( assert ) { - const component = this.subject(); + const component = this.subject({ + viewingDate: window.moment( [ 2015, 2, 1 ] ), + selectedDate: window.moment( [ 2015, 2, 1 ] ) + }); const allYears = component.get( 'yearsInDecadeView' ); const flattenedYears = []; @@ -650,6 +722,11 @@ test( 'Years for decade view are assembled correctly', function( assert ) { 12, 'Twelve years were generated for the decade view' ); + + assert.ok( + flattenedYears[6].active, + 'Expected year is set as active' + ); }); test( 'Observer keys are correct', function( assert ) { diff --git a/tests/unit/components/sl-calendar-year-test.js b/tests/unit/components/sl-calendar-year-test.js index c4272041..9d48b25a 100644 --- a/tests/unit/components/sl-calendar-year-test.js +++ b/tests/unit/components/sl-calendar-year-test.js @@ -26,7 +26,6 @@ test( 'Default property values', function( assert ) { ); }); -//need to re-visit this one test( 'Click event sends action with year value', function( assert ) { assert.expect( 1 ); From e55ff25268f5f2157eb78e0e1cd30f4c7037882b Mon Sep 17 00:00:00 2001 From: J Corley Date: Thu, 4 Feb 2016 10:15:27 -0600 Subject: [PATCH 21/25] removed documentation on bootstrap-datepicker --- tests/dummy/app/controllers/browsers.js | 4 ++-- tests/dummy/app/templates/browsers.hbs | 23 +---------------------- 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/tests/dummy/app/controllers/browsers.js b/tests/dummy/app/controllers/browsers.js index b9c2d764..63124f07 100755 --- a/tests/dummy/app/controllers/browsers.js +++ b/tests/dummy/app/controllers/browsers.js @@ -24,11 +24,11 @@ export default Ember.Controller.extend({ }, { name: 'sl-date-picker', - lib: { 'bd': true } + lib: { 'sec': true } }, { name: 'sl-date-range-picker', - lib: { 'bd': true } + lib: { 'sec': true } }, { name: 'sl-date-time', diff --git a/tests/dummy/app/templates/browsers.hbs b/tests/dummy/app/templates/browsers.hbs index 4967bb5e..0a1b8894 100644 --- a/tests/dummy/app/templates/browsers.hbs +++ b/tests/dummy/app/templates/browsers.hbs @@ -31,15 +31,6 @@
-
-
- BD -
-
- Bootstrap-Datepicker -
-
-
TA @@ -63,11 +54,10 @@
- + - @@ -85,9 +75,6 @@ - @@ -122,14 +109,6 @@

See provided link for most up-to-date information.

-
-
Bootstrap-Datepicker
- -

From http://bootstrap-datepicker.readthedocs.org/en/release/#:

-

Has a dependency on Twitter Bootstrap so same support previously listed.

-

See provided link for most up-to-date information.

-
-
typeahead.js
From c5614e3c07ffa3dd37bf0b72916cee83a332df3b Mon Sep 17 00:00:00 2001 From: J Corley Date: Thu, 4 Feb 2016 10:18:12 -0600 Subject: [PATCH 22/25] removed note about bootstrap-datepicker from readme --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 7e117d3b..b4001582 100755 --- a/README.md +++ b/README.md @@ -107,9 +107,6 @@ All of this functionality is provided through a combination of leveraging the be While this library is MIT licensed not all of the third-party component libraries are. Specifically, Highcharts is only free for non-commercial use and requires a license for any other use. See [this FAQ page](http://shop.highsoft.com/faq/non-commercial#what-is-commercial-website) for more information. -Other libraries that are not MIT licensed, though it should not pose a problem, are: - -* [Bootstrap-Datepicker](https://github.com/eternicode/bootstrap-datepicker/blob/release/LICENSE) From 954b323ed0b5c0206b79c4297ae7bf248d307ca8 Mon Sep 17 00:00:00 2001 From: J Corley Date: Thu, 4 Feb 2016 12:53:43 -0600 Subject: [PATCH 23/25] Updated the demo examples --- .../dummy/app/templates/demos/sl-calendar.hbs | 27 ++++++++++++++----- .../app/templates/demos/sl-date-picker.hbs | 17 +++++++++++- .../templates/demos/sl-date-range-picker.hbs | 23 ++++++++++++---- 3 files changed, 55 insertions(+), 12 deletions(-) diff --git a/tests/dummy/app/templates/demos/sl-calendar.hbs b/tests/dummy/app/templates/demos/sl-calendar.hbs index 52346ddb..3416d85c 100755 --- a/tests/dummy/app/templates/demos/sl-calendar.hbs +++ b/tests/dummy/app/templates/demos/sl-calendar.hbs @@ -8,20 +8,35 @@
Template
-
\{{sl-calendar action="logLabel" content=content}}
+
\{{sl-calendar action="logLabel" events=content locale="en" selectConstraint=tempdates}}
-
Route/Controller
-
model: [
+        
Route
+
model: [
     {
-        date: new Date(),
-        label: 'Today!'
+        startDate: window.moment().subtract( 5, 'days' ),
+        title: 'Some meeting five days ago'
+    },
+    {
+        startDate: window.moment().add( 3, 'days' ),
+        title: 'Lunch meeting three days from now'
     }
 ]
+ +
Controller
+
actions: {
+    logLabel( date, data ) {
+        window.console.log( 'logLabel: ', date, data );
+    }
+},
+
+tempdates: {
+    start: '01/05/2016'
+}
Rendered Component
- {{sl-calendar action="logLabel" events=content fixedWeekCount=true locale="en" selectConstraint=tempdates}} + {{sl-calendar action="logLabel" events=content locale="en" selectConstraint=tempdates}}
diff --git a/tests/dummy/app/templates/demos/sl-date-picker.hbs b/tests/dummy/app/templates/demos/sl-date-picker.hbs index ceee5e96..4f53c7ad 100755 --- a/tests/dummy/app/templates/demos/sl-date-picker.hbs +++ b/tests/dummy/app/templates/demos/sl-date-picker.hbs @@ -8,7 +8,22 @@
Template
-
\{{sl-date-picker label="Date picker"}}
+
\{{sl-date-picker action="logLabel" label="Date picker" selectedDate=selectedDate}}
+ +
Controller
+
actions: {
+    logLabel( date, data ) {
+        window.console.log( 'logLabel: ', date, data );
+    }
+},
+
+selectConstraint: {
+    start: '01/05/2016',
+    end: '02/05/2016'
+},
+
+selectedDate: window.moment( '01/11/2016', 'MM/DD/YYYY' )
+
diff --git a/tests/dummy/app/templates/demos/sl-date-range-picker.hbs b/tests/dummy/app/templates/demos/sl-date-range-picker.hbs index 0b7f0b75..00949cda 100755 --- a/tests/dummy/app/templates/demos/sl-date-range-picker.hbs +++ b/tests/dummy/app/templates/demos/sl-date-range-picker.hbs @@ -8,11 +8,24 @@
Template
-
\{{sl-date-range-picker
-            label="Select date range"
-            startDatePlaceholder="Select start date"
-            endDatePlaceholder="Select end date"
-        }}
+
\{{sl-date-range-picker
+    label="Select date range"
+    selectConstraint=selectConstraint
+    startDatePlaceholder="Select start date"
+    endDatePlaceholder="Select end date"
+    startDate=startDate
+    endDate=endDate
+}}
+ +
Controller
+
selectConstraint: {
+    start: '01/05/2016',
+    end: '02/05/2016'
+},
+
+startDate: window.moment( '01/07/2016', 'MM/DD/YYYY' ),
+endDate: window.moment( '01/28/2016', 'MM/DD/YYYY' )
+
From 06217dbceba06add9f66e66f2b2f7cd19380868b Mon Sep 17 00:00:00 2001 From: J Corley Date: Fri, 5 Feb 2016 09:54:24 -0600 Subject: [PATCH 24/25] jshint fixes --- .../components/sl-calendar-test.js | 32 +++++++++---------- tests/unit/components/sl-calendar-test.js | 8 ++--- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/tests/integration/components/sl-calendar-test.js b/tests/integration/components/sl-calendar-test.js index 4541ed70..5ab3d068 100755 --- a/tests/integration/components/sl-calendar-test.js +++ b/tests/integration/components/sl-calendar-test.js @@ -4,19 +4,19 @@ import hbs from 'htmlbars-inline-precompile'; const testEvents = Ember.A([ { - startDate: moment( [ 2015, 2, 12 ] ), + startDate: window.moment( [ 2015, 2, 12 ] ), title: 'Event 1 Today!' }, { - startDate: moment( [ 2015, 2, 12 ] ), + startDate: window.moment( [ 2015, 2, 12 ] ), title: 'Event 2 Today!' }, { - startDate: moment( [ 2015, 2, 17 ] ), + startDate: window.moment( [ 2015, 2, 17 ] ), title: 'Event 3 Today!' }, { - startDate: moment( [ 2015, 2, 20 ] ), + startDate: window.moment( [ 2015, 2, 20 ] ), title: 'Event 1 Another Day!' } ]); @@ -694,7 +694,7 @@ test( 'Wai-Aria keyboard navigation', function( assert ) { calendar.trigger( 'focusin' ); - let event = new jQuery.Event( 'keydown' ); + let event = new Ember.$.Event( 'keydown' ); event.keyCode = 33; calendar.trigger( event ); @@ -703,7 +703,7 @@ test( 'Wai-Aria keyboard navigation', function( assert ) { 'correctly decreased the date by one month' ); - event = new jQuery.Event( 'keydown' ); + event = new Ember.$.Event( 'keydown' ); event.keyCode = 34; calendar.trigger( event ); @@ -712,7 +712,7 @@ test( 'Wai-Aria keyboard navigation', function( assert ) { 'correctly increased the date by one month' ); - event = new jQuery.Event( 'keydown' ); + event = new Ember.$.Event( 'keydown' ); event.keyCode = 35; calendar.trigger( event ); @@ -721,7 +721,7 @@ test( 'Wai-Aria keyboard navigation', function( assert ) { 'correctly moved to the last day in the current month' ); - event = new jQuery.Event( 'keydown' ); + event = new Ember.$.Event( 'keydown' ); event.keyCode = 36; calendar.trigger( event ); @@ -730,7 +730,7 @@ test( 'Wai-Aria keyboard navigation', function( assert ) { 'correctly moved to the first day in the current month' ); - event = new jQuery.Event( 'keydown' ); + event = new Ember.$.Event( 'keydown' ); event.keyCode = 37; calendar.trigger( event ); @@ -739,7 +739,7 @@ test( 'Wai-Aria keyboard navigation', function( assert ) { 'correctly decreased the date by one day' ); - event = new jQuery.Event( 'keydown' ); + event = new Ember.$.Event( 'keydown' ); event.keyCode = 38; calendar.trigger( event ); @@ -748,7 +748,7 @@ test( 'Wai-Aria keyboard navigation', function( assert ) { 'correctly decreased the date by one week' ); - event = new jQuery.Event( 'keydown' ); + event = new Ember.$.Event( 'keydown' ); event.keyCode = 39; calendar.trigger( event ); @@ -757,7 +757,7 @@ test( 'Wai-Aria keyboard navigation', function( assert ) { 'correctly increased the date by one day' ); - event = new jQuery.Event( 'keydown' ); + event = new Ember.$.Event( 'keydown' ); event.keyCode = 40; calendar.trigger( event ); @@ -766,7 +766,7 @@ test( 'Wai-Aria keyboard navigation', function( assert ) { 'correctly increased the date by one week' ); - event = new jQuery.Event( 'keydown' ); + event = new Ember.$.Event( 'keydown' ); event.keyCode = 33; event.ctrlKey = true; calendar.trigger( event ); @@ -776,7 +776,7 @@ test( 'Wai-Aria keyboard navigation', function( assert ) { 'correctly decreased the date by one year' ); - event = new jQuery.Event( 'keydown' ); + event = new Ember.$.Event( 'keydown' ); event.keyCode = 34; event.ctrlKey = true; calendar.trigger( event ); @@ -786,7 +786,7 @@ test( 'Wai-Aria keyboard navigation', function( assert ) { 'correctly increased the date by one year' ); - event = new jQuery.Event( 'keydown' ); + event = new Ember.$.Event( 'keydown' ); event.keyCode = 32; calendar.trigger( event ); @@ -797,7 +797,7 @@ test( 'Wai-Aria keyboard navigation', function( assert ) { this.set( 'viewingDate', window.moment( [ 2016, 0, 15 ] ) ); - event = new jQuery.Event( 'keydown' ); + event = new Ember.$.Event( 'keydown' ); event.keyCode = 13; calendar.trigger( event ); diff --git a/tests/unit/components/sl-calendar-test.js b/tests/unit/components/sl-calendar-test.js index 5929b305..e0a6ef7c 100755 --- a/tests/unit/components/sl-calendar-test.js +++ b/tests/unit/components/sl-calendar-test.js @@ -4,19 +4,19 @@ import sinon from 'sinon'; const testEvents = Ember.A([ { - startDate: moment( [ 2015, 2, 12 ] ), + startDate: window.moment( [ 2015, 2, 12 ] ), title: 'Event 1 Today!' }, { - startDate: moment( [ 2015, 2, 12 ] ), + startDate: window.moment( [ 2015, 2, 12 ] ), title: 'Event 2 Today!' }, { - startDate: moment( [ 2015, 2, 17 ] ), + startDate: window.moment( [ 2015, 2, 17 ] ), title: 'Event 3 Today!' }, { - startDate: moment( [ 2015, 2, 20 ] ), + startDate: window.moment( [ 2015, 2, 20 ] ), title: 'Event 1 Another Day!' } ]); From 07450080c4a1f557b2508891ae60ef3e6c5c0efa Mon Sep 17 00:00:00 2001 From: J Corley Date: Thu, 5 May 2016 10:07:24 -0500 Subject: [PATCH 25/25] small fixes --- addon/components/sl-calendar.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addon/components/sl-calendar.js b/addon/components/sl-calendar.js index a32adf3d..c949d362 100755 --- a/addon/components/sl-calendar.js +++ b/addon/components/sl-calendar.js @@ -230,7 +230,7 @@ export default Ember.Component.extend({ case 32: // space case 13: // enter - this.setDate( viewingDate ); + this.send( 'selectDate', this.get( 'viewingDate' ) ); break; default: @@ -404,7 +404,7 @@ export default Ember.Component.extend({ } for ( let day = 0; day < eventsPerDay.length; day++ ) { - if ( currentEvent.startDate.isSame( eventsPerDay[ day ].date ) ) { + if ( currentEvent.startDate.isSame( eventsPerDay[ day ].date, 'day' ) ) { eventsPerDay[ day ].events.push( currentEvent ); continue eventsLoop; }
ComponentComponent {{#sl-tooltip title="Twitter Bootstrap"}}TWB{{/sl-tooltip}} {{#sl-tooltip title="sl-ember-components"}}SEC{{/sl-tooltip}} {{#sl-tooltip title="Highcharts"}}HC{{/sl-tooltip}}{{#sl-tooltip title="Bootstrap-Datepicker"}}BD{{/sl-tooltip}} {{#sl-tooltip title="typeahead.js"}}TA{{/sl-tooltip}} {{#sl-tooltip title="Select2"}}S2{{/sl-tooltip}}
{{#if component.lib.hc}}{{else}}{{/if}} - {{#if component.lib.bd}}{{else}}{{/if}} - {{#if component.lib.ta}}{{else}}{{/if}}