vendor/assets/javascripts/pickadate/picker.date.js in pickadate-rails-1.4.0 vs vendor/assets/javascripts/pickadate/picker.date.js in pickadate-rails-1.5.0
- old
+ new
@@ -1,8 +1,8 @@
/*!
- * Date picker for pickadate.js v3.4.0
+ * Date picker for pickadate.js v3.5.0
* http://amsul.github.io/pickadate.js/date.htm
*/
(function ( factory ) {
@@ -55,10 +55,11 @@
}
// The component's item object.
calendar.item = {}
+ calendar.item.clear = null
calendar.item.disable = ( settings.disable || [] ).slice( 0 )
calendar.item.enable = -(function( collectionDisabled ) {
return collectionDisabled[ 0 ] === true ? collectionDisabled.shift() : -1
})( calendar.item.disable )
@@ -68,14 +69,11 @@
set( 'now' )
// When there’s a value, set the `select`, which in turn
// also sets the `highlight` and `view`.
if ( valueString ) {
- calendar.set( 'select', valueString, {
- format: formatString,
- fromValue: !!elementValue
- })
+ calendar.set( 'select', valueString, { format: formatString })
}
// If there’s no value, default to highlighting “today”.
else {
calendar.
@@ -139,10 +137,11 @@
var calendar = this,
calendarItem = calendar.item
// If the value is `null` just set it immediately.
if ( value === null ) {
+ if ( type == 'clear' ) type = 'select'
calendarItem[ type ] = value
return calendar
}
// Otherwise go through the queue of methods, and invoke the functions.
@@ -288,11 +287,11 @@
// Convert the ranges into comparable dates.
one = calendar.createRange( one.from, one.to )
two = calendar.createRange( two.from, two.to )
- return calendar.withinRange( one, two.from ) || calendar.withinRange( one, two.to ) ||
+ return calendar.withinRange( one, two.from ) || calendar.withinRange( one, two.to ) ||
calendar.withinRange( two, one.from ) || calendar.withinRange( two, one.to )
}
/**
@@ -488,16 +487,24 @@
// If we’ve reached the min/max limit, reverse the direction, flatten the interval and set it to the limit.
if ( dateObject.pick <= minLimitObject.pick ) {
reachedMin = true
interval = 1
- dateObject = calendar.create([ minLimitObject.year, minLimitObject.month, minLimitObject.date - 1 ])
+ dateObject = calendar.create([
+ minLimitObject.year,
+ minLimitObject.month,
+ minLimitObject.date + (dateObject.pick === minLimitObject.pick ? 0 : -1)
+ ])
}
else if ( dateObject.pick >= maxLimitObject.pick ) {
reachedMax = true
interval = -1
- dateObject = calendar.create([ maxLimitObject.year, maxLimitObject.month, maxLimitObject.date + 1 ])
+ dateObject = calendar.create([
+ maxLimitObject.year,
+ maxLimitObject.month,
+ maxLimitObject.date + (dateObject.pick === maxLimitObject.pick ? 0 : 1)
+ ])
}
// If we’ve reached both limits, just break out of the loop.
if ( reachedMin && reachedMax ) {
@@ -563,26 +570,23 @@
* Parse a string into a usable type.
*/
DatePicker.prototype.parse = function( type, value, options ) {
var calendar = this,
- parsingObject = {},
- monthIndex
+ parsingObject = {}
- if ( !value || _.isInteger( value ) || $.isArray( value ) || _.isDate( value ) || $.isPlainObject( value ) && _.isInteger( value.pick ) ) {
+ // If it’s already parsed, we’re good.
+ if ( !value || typeof value != 'string' ) {
return value
}
// We need a `.format` to parse the value with.
if ( !( options && options.format ) ) {
options = options || {}
options.format = calendar.settings.format
}
- // Calculate the month index to adjust with.
- monthIndex = typeof value == 'string' && !options.fromValue ? 1 : 0
-
// Convert the format into an array and then map through it.
calendar.formats.toArray( options.format ).map( function( label ) {
var
// Grab the formatting label.
@@ -600,14 +604,14 @@
// Update the value as the substring from format length to end.
value = value.substr( formatLength )
})
- // If it’s parsing a user provided month value, compensate for month 0index.
+ // Compensate for month 0index.
return [
parsingObject.yyyy || parsingObject.yy,
- +( parsingObject.mm || parsingObject.m ) - monthIndex,
+ +( parsingObject.mm || parsingObject.m ) - 1,
parsingObject.dd || parsingObject.d
]
} //DatePicker.prototype.parse
@@ -622,11 +626,11 @@
// Grab the first word from the string.
var word = string.match( /\w+/ )[ 0 ]
// If there's no month index, add it to the date object
if ( !dateObject.mm && !dateObject.m ) {
- dateObject.m = collection.indexOf( word )
+ dateObject.m = collection.indexOf( word ) + 1
}
// Return the length of the word.
return word.length
}
@@ -953,15 +957,16 @@
maxLimitObject = calendarItem.max,
// Create the calendar table head using a copy of weekday labels collection.
// * We do a copy so we don't mutate the original array.
- tableHead = (function( collection ) {
+ tableHead = (function( collection, fullCollection ) {
// If the first day should be Monday, move Sunday to the end.
if ( settings.firstDay ) {
collection.push( collection.shift() )
+ fullCollection.push( fullCollection.shift() )
}
// Create and return the table head group.
return _.node(
'thead',
@@ -973,17 +978,18 @@
i: 1,
node: 'th',
item: function( counter ) {
return [
collection[ counter ],
- settings.klass.weekdays
+ settings.klass.weekdays,
+ 'scope=col title="' + fullCollection[ counter ] + '"'
]
}
})
)
) //endreturn
- })( ( settings.showWeekdaysFull ? settings.weekdaysFull : settings.weekdaysShort ).slice( 0 ) ), //tableHead
+ })( ( settings.showWeekdaysFull ? settings.weekdaysFull : settings.weekdaysShort ).slice( 0 ), settings.weekdaysFull.slice( 0 ) ), //tableHead
// Create the nav for next/prev month.
createMonthNav = function( next ) {
@@ -996,46 +1002,59 @@
// If the focused month is outside the range, disabled the button.
( next && viewsetObject.year >= maxLimitObject.year && viewsetObject.month >= maxLimitObject.month ) ||
( !next && viewsetObject.year <= minLimitObject.year && viewsetObject.month <= minLimitObject.month ) ?
' ' + settings.klass.navDisabled : ''
),
- 'data-nav=' + ( next || -1 )
+ 'data-nav=' + ( next || -1 ) + ' ' +
+ _.ariaAttr({
+ role: 'button',
+ controls: calendar.$node[0].id + '_table'
+ }) + ' ' +
+ 'title="' + (next ? settings.labelMonthNext : settings.labelMonthPrev ) + '"'
) //endreturn
}, //createMonthNav
// Create the month label.
- createMonthLabel = function( monthsCollection ) {
+ createMonthLabel = function() {
+ var monthsCollection = settings.showMonthsShort ? settings.monthsShort : settings.monthsFull
+
// If there are months to select, add a dropdown menu.
if ( settings.selectMonths ) {
- return _.node( 'select', _.group({
- min: 0,
- max: 11,
- i: 1,
- node: 'option',
- item: function( loopedMonth ) {
+ return _.node( 'select',
+ _.group({
+ min: 0,
+ max: 11,
+ i: 1,
+ node: 'option',
+ item: function( loopedMonth ) {
- return [
+ return [
- // The looped month and no classes.
- monthsCollection[ loopedMonth ], 0,
+ // The looped month and no classes.
+ monthsCollection[ loopedMonth ], 0,
- // Set the value and selected index.
- 'value=' + loopedMonth +
- ( viewsetObject.month == loopedMonth ? ' selected' : '' ) +
- (
+ // Set the value and selected index.
+ 'value=' + loopedMonth +
+ ( viewsetObject.month == loopedMonth ? ' selected' : '' ) +
(
- ( viewsetObject.year == minLimitObject.year && loopedMonth < minLimitObject.month ) ||
- ( viewsetObject.year == maxLimitObject.year && loopedMonth > maxLimitObject.month )
- ) ?
- ' disabled' : ''
- )
- ]
- }
- }), settings.klass.selectMonth, isOpen ? '' : 'disabled' )
+ (
+ ( viewsetObject.year == minLimitObject.year && loopedMonth < minLimitObject.month ) ||
+ ( viewsetObject.year == maxLimitObject.year && loopedMonth > maxLimitObject.month )
+ ) ?
+ ' disabled' : ''
+ )
+ ]
+ }
+ }),
+ settings.klass.selectMonth,
+ ( isOpen ? '' : 'disabled' ) + ' ' +
+ _.ariaAttr({ controls: calendar.$node[0].id + '_table' }) + ' ' +
+ 'title="' + settings.labelMonthSelect + '"'
+ )
}
// If there's a need for a month selector
return _.node( 'div', monthsCollection[ viewsetObject.month ], settings.klass.month )
}, //createMonthLabel
@@ -1076,39 +1095,43 @@
lowestYear -= availableYears > neededYears ? neededYears : availableYears
highestYear = maxYear
}
- return _.node( 'select', _.group({
- min: lowestYear,
- max: highestYear,
- i: 1,
- node: 'option',
- item: function( loopedYear ) {
- return [
+ return _.node( 'select',
+ _.group({
+ min: lowestYear,
+ max: highestYear,
+ i: 1,
+ node: 'option',
+ item: function( loopedYear ) {
+ return [
- // The looped year and no classes.
- loopedYear, 0,
+ // The looped year and no classes.
+ loopedYear, 0,
- // Set the value and selected index.
- 'value=' + loopedYear + ( focusedYear == loopedYear ? ' selected' : '' )
- ]
- }
- }), settings.klass.selectYear, isOpen ? '' : 'disabled' )
+ // Set the value and selected index.
+ 'value=' + loopedYear + ( focusedYear == loopedYear ? ' selected' : '' )
+ ]
+ }
+ }),
+ settings.klass.selectYear,
+ ( isOpen ? '' : 'disabled' ) + ' ' + _.ariaAttr({ controls: calendar.$node[0].id + '_table' }) + ' ' +
+ 'title="' + settings.labelYearSelect + '"'
+ )
}
// Otherwise just return the year focused
return _.node( 'div', focusedYear, settings.klass.year )
} //createYearLabel
// Create and return the entire calendar.
return _.node(
'div',
- createMonthNav() + createMonthNav( 1 ) +
- createMonthLabel( settings.showMonthsShort ? settings.monthsShort : settings.monthsFull ) +
- createYearLabel(),
+ ( settings.selectYears ? createYearLabel() + createMonthLabel() : createMonthLabel() + createYearLabel() ) +
+ createMonthNav() + createMonthNav( 1 ),
settings.klass.header
) + _.node(
'table',
tableHead +
_.node(
@@ -1170,36 +1193,48 @@
}
return klasses.join( ' ' )
})([ settings.klass.day ]),
'data-pick=' + targetDate.pick + ' ' + _.ariaAttr({
- role: 'button',
- controls: calendar.$node[0].id,
- checked: isSelected && calendar.$node.val() === _.trigger(
+ role: 'gridcell',
+ selected: isSelected && calendar.$node.val() === _.trigger(
calendar.formats.toString,
calendar,
[ settings.format, targetDate ]
) ? true : null,
activedescendant: isHighlighted ? true : null,
disabled: isDisabled ? true : null
})
- )
+ ),
+ '',
+ _.ariaAttr({ role: 'presentation' })
] //endreturn
}
})
] //endreturn
}
})
),
- settings.klass.table
+ settings.klass.table,
+ 'id="' + calendar.$node[0].id + '_table' + '" ' + _.ariaAttr({
+ role: 'grid',
+ controls: calendar.$node[0].id,
+ readonly: true
+ })
) +
// * For Firefox forms to submit, make sure to set the buttons’ `type` attributes as “button”.
_.node(
'div',
- _.node( 'button', settings.today, settings.klass.buttonToday, 'type=button data-pick=' + nowObject.pick + ( isOpen ? '' : ' disabled' ) ) +
- _.node( 'button', settings.clear, settings.klass.buttonClear, 'type=button data-clear=1' + ( isOpen ? '' : ' disabled' ) ),
+ _.node( 'button', settings.today, settings.klass.buttonToday,
+ 'type=button data-pick=' + nowObject.pick +
+ ( isOpen ? '' : ' disabled' ) + ' ' +
+ _.ariaAttr({ controls: calendar.$node[0].id }) ) +
+ _.node( 'button', settings.clear, settings.klass.buttonClear,
+ 'type=button data-clear=1' +
+ ( isOpen ? '' : ' disabled' ) + ' ' +
+ _.ariaAttr({ controls: calendar.$node[0].id }) ),
settings.klass.footer
) //endreturn
} //DatePicker.prototype.nodes
@@ -1209,9 +1244,17 @@
* The date picker defaults.
*/
DatePicker.defaults = (function( prefix ) {
return {
+
+ // The title label to use for the month nav buttons
+ labelMonthNext: 'Next month',
+ labelMonthPrev: 'Previous month',
+
+ // The title label to use for the dropdown selectors
+ labelMonthSelect: 'Select a month',
+ labelYearSelect: 'Select a year',
// Months and weekdays
monthsFull: [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ],
monthsShort: [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ],
weekdaysFull: [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ],