/*! * Date picker for pickadate.js v3.1.1 * http://amsul.github.io/pickadate.js/date.htm */ /*jshint debug: true, devel: true, browser: true, asi: true, unused: true, boss: true */ // Create a new scope. (function() { /** * Globals and constants */ var DAYS_IN_WEEK = 7, WEEKS_IN_CALENDAR = 6 /** * The date picker constructor */ function DatePicker( picker, settings ) { var calendar = this, elementValue = picker.$node[ 0 ].value, elementDataValue = picker.$node.data( 'value' ), valueString = elementDataValue || elementValue, formatString = elementDataValue ? settings.formatSubmit : settings.format calendar.settings = settings // The queue of methods that will be used to build item objects. calendar.queue = { min: 'measure create', max: 'measure create', now: 'now create', select: 'parse create validate', highlight: 'navigate create validate', view: 'create validate viewset', disable: 'flipItem', enable: 'flipItem' } // The component's item object. calendar.item = {} calendar.item.disable = ( settings.disable || [] ).slice( 0 ) calendar.item.enable = -(function( collectionDisabled ) { return collectionDisabled[ 0 ] === true ? collectionDisabled.shift() : -1 })( calendar.item.disable ) calendar. set( 'min', settings.min ). set( 'max', settings.max ). set( 'now' ). // Setting the `select` also sets the `highlight` and `view`. set( 'select', // Use the value provided or default to selecting “today”. valueString || calendar.item.now, { // Use the appropriate format. format: formatString, // Set user-provided month data as true when there is a // “mm” or “m” used in the relative format string. data: (function( formatArray ) { return valueString && ( formatArray.indexOf( 'mm' ) > -1 || formatArray.indexOf( 'm' ) > -1 ) })( calendar.formats.toArray( formatString ) ) } ) // The keycode to movement mapping. calendar.key = { 40: 7, // Down 38: -7, // Up 39: 1, // Right 37: -1, // Left go: function( timeChange ) { calendar.set( 'highlight', [ calendar.item.highlight.year, calendar.item.highlight.month, calendar.item.highlight.date + timeChange ], { interval: timeChange } ) this.render() } } // Bind some picker events. picker. on( 'render', function() { picker.$root.find( '.' + settings.klass.selectMonth ).on( 'change', function() { picker.set( 'highlight', [ picker.get( 'view' ).year, this.value, picker.get( 'highlight' ).date ] ) picker.$root.find( '.' + settings.klass.selectMonth ).focus() }) picker.$root.find( '.' + settings.klass.selectYear ).on( 'change', function() { picker.set( 'highlight', [ this.value, picker.get( 'view' ).month, picker.get( 'highlight' ).date ] ) picker.$root.find( '.' + settings.klass.selectYear ).focus() }) }). on( 'open', function() { picker.$root.find( 'button, select' ).attr( 'disabled', false ) }). on( 'close', function() { picker.$root.find( 'button, select' ).attr( 'disabled', true ) }) } //DatePicker /** * Set a datepicker item object. */ DatePicker.prototype.set = function( type, value, options ) { var calendar = this // Go through the queue of methods, and invoke the function. Update this // as the time unit, and set the final resultant as this item type. // * In the case of `enable`, keep the queue but set `disable` instead. // And in the case of `flip`, keep the queue but set `enable` instead. calendar.item[ ( type == 'enable' ? 'disable' : type == 'flip' ? 'enable' : type ) ] = calendar.queue[ type ].split( ' ' ).map( function( method ) { return value = calendar[ method ]( type, value, options ) }).pop() // Check if we need to cascade through more updates. if ( type == 'select' ) { calendar.set( 'highlight', calendar.item.select, options ) } else if ( type == 'highlight' ) { calendar.set( 'view', calendar.item.highlight, options ) } else if ( ( type == 'flip' || type == 'min' || type == 'max' || type == 'disable' || type == 'enable' ) && calendar.item.select && calendar.item.highlight ) { calendar. set( 'select', calendar.item.select, options ). set( 'highlight', calendar.item.highlight, options ) } return calendar } //DatePicker.prototype.set /** * Get a datepicker item object. */ DatePicker.prototype.get = function( type ) { return this.item[ type ] } //DatePicker.prototype.get /** * Create a picker date object. */ DatePicker.prototype.create = function( type, value, options ) { var isInfiniteValue, calendar = this // If there’s no value, use the type as the value. value = value === undefined ? type : value // If it’s infinity, update the value. if ( value == -Infinity || value == Infinity ) { isInfiniteValue = value } // If it’s an object, use the native date object. else if ( Picker._.isObject( value ) && Picker._.isInteger( value.pick ) ) { value = value.obj } // If it’s an array, convert it into a date and make sure // that it’s a valid date – otherwise default to today. else if ( Array.isArray( value ) ) { value = new Date( value[ 0 ], value[ 1 ], value[ 2 ] ) value = Picker._.isDate( value ) ? value : calendar.create().obj } // If it’s a number or date object, make a normalized date. else if ( Picker._.isInteger( value ) || Picker._.isDate( value ) ) { value = calendar.normalize( new Date( value ), options ) } // If it’s a literal true or any other case, set it to now. else /*if ( value === true )*/ { value = calendar.now( type, value, options ) } // Return the compiled object. return { year: isInfiniteValue || value.getFullYear(), month: isInfiniteValue || value.getMonth(), date: isInfiniteValue || value.getDate(), day: isInfiniteValue || value.getDay(), obj: isInfiniteValue || value, pick: isInfiniteValue || value.getTime() } } //DatePicker.prototype.create /** * Get the date today. */ DatePicker.prototype.now = function( type, value, options ) { value = new Date() if ( options && options.rel ) { value.setDate( value.getDate() + options.rel ) } return this.normalize( value, options ) } //DatePicker.prototype.now /** * Navigate to next/prev month. */ DatePicker.prototype.navigate = function( type, value, options ) { if ( Picker._.isObject( value ) ) { var targetDateObject = new Date( value.year, value.month + ( options && options.nav ? options.nav : 0 ), 1 ), year = targetDateObject.getFullYear(), month = targetDateObject.getMonth(), date = value.date // Make sure the date is valid and if the month we’re going to doesn’t have enough // days, keep decreasing the date until we reach the month’s last date. while ( Picker._.isDate( targetDateObject ) && new Date( year, month, date ).getMonth() !== month ) { date -= 1 } value = [ year, month, date ] } return value } //DatePicker.prototype.navigate /** * Normalize a date by setting the hours to midnight. */ DatePicker.prototype.normalize = function( value/*, options*/ ) { value.setHours( 0, 0, 0, 0 ) return value } /** * Measure the range of dates. */ DatePicker.prototype.measure = function( type, value/*, options*/ ) { var calendar = this // If it's anything false-y, remove the limits. if ( !value ) { value = type == 'min' ? -Infinity : Infinity } // If it's an integer, get a date relative to today. else if ( Picker._.isInteger( value ) ) { value = calendar.now( type, value, { rel: value } ) } return value } ///DatePicker.prototype.measure /** * Create a viewset object based on navigation. */ DatePicker.prototype.viewset = function( type, dateObject/*, options*/ ) { return this.create([ dateObject.year, dateObject.month, 1 ]) } /** * Validate a date as enabled and shift if needed. */ DatePicker.prototype.validate = function( type, dateObject, options ) { var calendar = this, // Keep a reference to the original date. originalDateObject = dateObject, // Make sure we have an interval. interval = options && options.interval ? options.interval : 1, // Check if the calendar enabled dates are inverted. isInverted = calendar.item.enable === -1, // Check if we have any enabled dates after/before now. hasEnabledBeforeTarget, hasEnabledAfterTarget, // The min & max limits. minLimitObject = calendar.item.min, maxLimitObject = calendar.item.max, // Check if we’ve reached the limit during shifting. reachedMin, reachedMax, // Check if the calendar is inverted and at least one weekday is enabled. hasEnabledWeekdays = isInverted && calendar.item.disable.filter( function( value ) { // If there’s a date, check where it is relative to the target. if ( Array.isArray( value ) ) { var dateTime = calendar.create( value ).pick if ( dateTime < dateObject.pick ) hasEnabledBeforeTarget = true else if ( dateTime > dateObject.pick ) hasEnabledAfterTarget = true } // Return only integers for enabled weekdays. return Picker._.isInteger( value ) }).length // Cases to validate for: // [1] Not inverted and date disabled. // [2] Inverted and some dates enabled. // [3] Out of range. // // Cases to **not** validate for: // • Not inverted and date enabled. // • Inverted and all dates disabled. // • Navigating months. // • ..and anything else. if ( /* 1 */ ( !isInverted && calendar.disabled( dateObject ) ) || /* 2 */ ( isInverted && calendar.disabled( dateObject ) && ( hasEnabledWeekdays || hasEnabledBeforeTarget || hasEnabledAfterTarget ) ) || /* 3 */ ( dateObject.pick <= minLimitObject.pick || dateObject.pick >= maxLimitObject.pick ) ) { // When inverted, flip the direction if there aren’t any enabled weekdays // and there are no enabled dates in the direction of the interval. if ( isInverted && !hasEnabledWeekdays && ( ( !hasEnabledAfterTarget && interval > 0 ) || ( !hasEnabledBeforeTarget && interval < 0 ) ) ) { interval *= -1 } // Keep looping until we reach an enabled date. while ( calendar.disabled( dateObject ) ) { // If we’ve looped into the next/prev month, return to the original date and flatten the interval. if ( Math.abs( interval ) > 1 && ( dateObject.month < originalDateObject.month || dateObject.month > originalDateObject.month ) ) { dateObject = originalDateObject interval = Math.abs( interval ) / interval } // If we’ve reached the min/max limit, reverse the direction and flatten the interval. if ( dateObject.pick <= minLimitObject.pick ) { reachedMin = true interval = 1 } else if ( dateObject.pick >= maxLimitObject.pick ) { reachedMax = true interval = -1 } // If we’ve reached both limits, just break out of the loop. if ( reachedMin && reachedMax ) { break } // Finally, create the shifted date using the interval and keep looping. dateObject = calendar.create([ dateObject.year, dateObject.month, dateObject.date + interval ]) } } //endif // Return the date object settled on. return dateObject } //DatePicker.prototype.validate /** * Check if an object is disabled. */ DatePicker.prototype.disabled = function( dateObject ) { var calendar = this, // Filter through the disabled dates to check if this is one. isDisabledDate = calendar.item.disable.filter( function( dateToDisable ) { // If the date is a number, match the weekday with 0index and `firstDay` check. if ( Picker._.isInteger( dateToDisable ) ) { return dateObject.day === ( calendar.settings.firstDay ? dateToDisable : dateToDisable - 1 ) % 7 } // If it's an array, create the object and match the exact date. if ( Array.isArray( dateToDisable ) ) { return dateObject.pick === calendar.create( dateToDisable ).pick } }).length // It’s disabled beyond the min/max limits. If within the limits, check the // calendar “enabled” flag is flipped and respectively flip the condition. return dateObject.pick < calendar.item.min.pick || dateObject.pick > calendar.item.max.pick || calendar.item.enable === -1 ? !isDisabledDate : isDisabledDate } //DatePicker.prototype.disabled /** * Parse a string into a usable type. */ DatePicker.prototype.parse = function( type, value, options ) { var calendar = this, parsingObject = {} if ( !value || Picker._.isInteger( value ) || Array.isArray( value ) || Picker._.isDate( value ) || Picker._.isObject( value ) && Picker._.isInteger( value.pick ) ) { return value } // We need a `.format` to parse the value. if ( !( options && options.format ) ) { // should probably default to the default format. throw "Need a formatting option to parse this.." } // Convert the format into an array and then map through it. calendar.formats.toArray( options.format ).map( function( label ) { var // Grab the formatting label. formattingLabel = calendar.formats[ label ], // The format length is from the formatting label function or the // label length without the escaping exclamation (!) mark. formatLength = formattingLabel ? Picker._.trigger( formattingLabel, calendar, [ value, parsingObject ] ) : label.replace( /^!/, '' ).length // If there's a format label, split the value up to the format length. // Then add it to the parsing object with appropriate label. if ( formattingLabel ) { parsingObject[ label ] = value.substr( 0, formatLength ) } // 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. return [ parsingObject.yyyy || parsingObject.yy, +( parsingObject.mm || parsingObject.m ) - ( options.data ? 1 : 0 ), parsingObject.dd || parsingObject.d ] } //DatePicker.prototype.parse /** * Various formats to display the object in. */ DatePicker.prototype.formats = (function() { // Return the length of the first word in a collection. function getWordLengthFromCollection( string, collection, dateObject ) { // 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 ) } // Return the length of the word. return word.length } // Get the length of the first word in a string. function getFirstWordLength( string ) { return string.match( /\w+/ )[ 0 ].length } return { d: function( string, dateObject ) { // If there's string, then get the digits length. // Otherwise return the selected date. return string ? Picker._.digits( string ) : dateObject.date }, dd: function( string, dateObject ) { // If there's a string, then the length is always 2. // Otherwise return the selected date with a leading zero. return string ? 2 : Picker._.lead( dateObject.date ) }, ddd: function( string, dateObject ) { // If there's a string, then get the length of the first word. // Otherwise return the short selected weekday. return string ? getFirstWordLength( string ) : this.settings.weekdaysShort[ dateObject.day ] }, dddd: function( string, dateObject ) { // If there's a string, then get the length of the first word. // Otherwise return the full selected weekday. return string ? getFirstWordLength( string ) : this.settings.weekdaysFull[ dateObject.day ] }, m: function( string, dateObject ) { // If there's a string, then get the length of the digits // Otherwise return the selected month with 0index compensation. return string ? Picker._.digits( string ) : dateObject.month + 1 }, mm: function( string, dateObject ) { // If there's a string, then the length is always 2. // Otherwise return the selected month with 0index and leading zero. return string ? 2 : Picker._.lead( dateObject.month + 1 ) }, mmm: function( string, dateObject ) { var collection = this.settings.monthsShort // If there's a string, get length of the relevant month from the short // months collection. Otherwise return the selected month from that collection. return string ? getWordLengthFromCollection( string, collection, dateObject ) : collection[ dateObject.month ] }, mmmm: function( string, dateObject ) { var collection = this.settings.monthsFull // If there's a string, get length of the relevant month from the full // months collection. Otherwise return the selected month from that collection. return string ? getWordLengthFromCollection( string, collection, dateObject ) : collection[ dateObject.month ] }, yy: function( string, dateObject ) { // If there's a string, then the length is always 2. // Otherwise return the selected year by slicing out the first 2 digits. return string ? 2 : ( '' + dateObject.year ).slice( 2 ) }, yyyy: function( string, dateObject ) { // If there's a string, then the length is always 4. // Otherwise return the selected year. return string ? 4 : dateObject.year }, // Create an array by splitting the formatting string passed. toArray: function( formatString ) { return formatString.split( /(d{1,4}|m{1,4}|y{4}|yy|!.)/g ) }, // Format an object into a string using the formatting options. toString: function ( formatString, itemObject ) { var calendar = this return calendar.formats.toArray( formatString ).map( function( label ) { return Picker._.trigger( calendar.formats[ label ], calendar, [ 0, itemObject ] ) || label.replace( /^!/, '' ) }).join( '' ) } } })() //DatePicker.prototype.formats /** * Flip an item as enabled or disabled. */ DatePicker.prototype.flipItem = function( type, value/*, options*/ ) { var calendar = this, collection = calendar.item.disable, isInverted = calendar.item.enable === -1 // Flip the enabled and disabled dates. if ( value == 'flip' ) { calendar.item.enable = isInverted ? 1 : -1 } // Check if we have to add/remove from collection. else if ( !isInverted && type == 'enable' || isInverted && type == 'disable' ) { collection = calendar.removeDisabled( collection, value ) } else if ( !isInverted && type == 'disable' || isInverted && type == 'enable' ) { collection = calendar.addDisabled( collection, value ) } return collection } //DatePicker.prototype.flipItem /** * Add an item to the disabled collection. */ DatePicker.prototype.addDisabled = function( collection, item ) { var calendar = this item.map( function( timeUnit ) { if ( !calendar.filterDisabled( collection, timeUnit ).length ) { collection.push( timeUnit ) } }) return collection } //DatePicker.prototype.addDisabled /** * Remove an item from the disabled collection. */ DatePicker.prototype.removeDisabled = function( collection, item ) { var calendar = this item.map( function( timeUnit ) { collection = calendar.filterDisabled( collection, timeUnit, 1 ) }) return collection } //DatePicker.prototype.removeDisabled /** * Filter through the disabled collection to find a time unit. */ DatePicker.prototype.filterDisabled = function( collection, timeUnit, isRemoving ) { var timeIsArray = Array.isArray( timeUnit ) return collection.filter( function( disabledTimeUnit ) { var isMatch = !timeIsArray && timeUnit === disabledTimeUnit || timeIsArray && Array.isArray( disabledTimeUnit ) && timeUnit.toString() === disabledTimeUnit.toString() return isRemoving ? !isMatch : isMatch }) } //DatePicker.prototype.filterDisabled /** * Create a string for the nodes in the picker. */ DatePicker.prototype.nodes = function( isOpen ) { var calendar = this, settings = calendar.settings, nowObject = calendar.item.now, selectedObject = calendar.item.select, highlightedObject = calendar.item.highlight, viewsetObject = calendar.item.view, disabledCollection = calendar.item.disable, minLimitObject = calendar.item.min, maxLimitObject = calendar.item.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 ) { // If the first day should be Monday, move Sunday to the end. if ( settings.firstDay ) { collection.push( collection.shift() ) } // Create and return the table head group. return Picker._.node( 'thead', Picker._.group({ min: 0, max: DAYS_IN_WEEK - 1, i: 1, node: 'th', item: function( counter ) { return [ collection[ counter ], settings.klass.weekdays ] } }) ) //endreturn })( ( settings.showWeekdaysFull ? settings.weekdaysFull : settings.weekdaysShort ).slice( 0 ) ), //tableHead // Create the nav for next/prev month. createMonthNav = function( next ) { // Otherwise, return the created month tag. return Picker._.node( 'div', ' ', settings.klass[ 'nav' + ( next ? 'Next' : 'Prev' ) ] + ( // 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 ) ) //endreturn }, //createMonthNav // Create the month label. createMonthLabel = function( monthsCollection ) { // If there are months to select, add a dropdown menu. if ( settings.selectMonths ) { return Picker._.node( 'select', Picker._.group({ min: 0, max: 11, i: 1, node: 'option', item: function( loopedMonth ) { return [ // The looped month and no classes. monthsCollection[ loopedMonth ], 0, // 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' ) } // If there's a need for a month selector return Picker._.node( 'div', monthsCollection[ viewsetObject.month ], settings.klass.month ) }, //createMonthLabel // Create the year label. createYearLabel = function() { var focusedYear = viewsetObject.year, // If years selector is set to a literal "true", set it to 5. Otherwise // divide in half to get half before and half after focused year. numberYears = settings.selectYears === true ? 5 : ~~( settings.selectYears / 2 ) // If there are years to select, add a dropdown menu. if ( numberYears ) { var minYear = minLimitObject.year, maxYear = maxLimitObject.year, lowestYear = focusedYear - numberYears, highestYear = focusedYear + numberYears // If the min year is greater than the lowest year, increase the highest year // by the difference and set the lowest year to the min year. if ( minYear > lowestYear ) { highestYear += minYear - lowestYear lowestYear = minYear } // If the max year is less than the highest year, decrease the lowest year // by the lower of the two: available and needed years. Then set the // highest year to the max year. if ( maxYear < highestYear ) { var availableYears = lowestYear - minYear, neededYears = highestYear - maxYear lowestYear -= availableYears > neededYears ? neededYears : availableYears highestYear = maxYear } return Picker._.node( 'select', Picker._.group({ min: lowestYear, max: highestYear, i: 1, node: 'option', item: function( loopedYear ) { return [ // The looped year and no classes. loopedYear, 0, // Set the value and selected index. 'value=' + loopedYear + ( focusedYear == loopedYear ? ' selected' : '' ) ] } }), settings.klass.selectYear, isOpen ? '' : 'disabled' ) } // Otherwise just return the year focused return Picker._.node( 'div', focusedYear, settings.klass.year ) } //createYearLabel // Create and return the entire calendar. return Picker._.node( 'div', createMonthNav() + createMonthNav( 1 ) + createMonthLabel( settings.showMonthsShort ? settings.monthsShort : settings.monthsFull ) + createYearLabel(), settings.klass.header ) + Picker._.node( 'table', tableHead + Picker._.node( 'tbody', Picker._.group({ min: 0, max: WEEKS_IN_CALENDAR - 1, i: 1, node: 'tr', item: function( rowCounter ) { // If Monday is the first day and the month starts on Sunday, shift the date back a week. var shiftDateBy = settings.firstDay && calendar.create([ viewsetObject.year, viewsetObject.month, 1 ]).day === 0 ? -7 : 0 return [ Picker._.group({ min: DAYS_IN_WEEK * rowCounter - viewsetObject.day + shiftDateBy + 1, // Add 1 for weekday 0index max: function() { return this.min + DAYS_IN_WEEK - 1 }, i: 1, node: 'td', item: function( targetDate ) { // Convert the time date from a relative date to a target date. targetDate = calendar.create([ viewsetObject.year, viewsetObject.month, targetDate + ( settings.firstDay ? 1 : 0 ) ]) return [ Picker._.node( 'div', targetDate.date, (function( klasses ) { // Add the `infocus` or `outfocus` classes based on month in view. klasses.push( viewsetObject.month == targetDate.month ? settings.klass.infocus : settings.klass.outfocus ) // Add the `today` class if needed. if ( nowObject.pick == targetDate.pick ) { klasses.push( settings.klass.now ) } // Add the `selected` class if something's selected and the time matches. if ( selectedObject && selectedObject.pick == targetDate.pick ) { klasses.push( settings.klass.selected ) } // Add the `highlighted` class if something's highlighted and the time matches. if ( highlightedObject && highlightedObject.pick == targetDate.pick ) { klasses.push( settings.klass.highlighted ) } // Add the `disabled` class if something's disabled and the object matches. if ( disabledCollection && calendar.disabled( targetDate ) || targetDate.pick < minLimitObject.pick || targetDate.pick > maxLimitObject.pick ) { klasses.push( settings.klass.disabled ) } return klasses.join( ' ' ) })([ settings.klass.day ]), 'data-pick=' + targetDate.pick ) ] //endreturn } }) ] //endreturn } }) ), settings.klass.table ) + Picker._.node( 'div', Picker._.node( 'button', settings.today, settings.klass.buttonToday, 'data-pick=' + nowObject.pick + ( isOpen ? '' : ' disabled' ) ) + Picker._.node( 'button', settings.clear, settings.klass.buttonClear, 'data-clear=1' + ( isOpen ? '' : ' disabled' ) ), settings.klass.footer ) //endreturn } //DatePicker.prototype.nodes /** * The date picker defaults. */ DatePicker.defaults = (function( prefix ) { return { // 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' ], weekdaysShort: [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ], // Today and clear today: 'Today', clear: 'Clear', // The format to show on the `input` element format: 'd mmmm, yyyy', // Classes klass: { table: prefix + 'table', header: prefix + 'header', navPrev: prefix + 'nav--prev', navNext: prefix + 'nav--next', navDisabled: prefix + 'nav--disabled', month: prefix + 'month', year: prefix + 'year', selectMonth: prefix + 'select--month', selectYear: prefix + 'select--year', weekdays: prefix + 'weekday', day: prefix + 'day', disabled: prefix + 'day--disabled', selected: prefix + 'day--selected', highlighted: prefix + 'day--highlighted', now: prefix + 'day--today', infocus: prefix + 'day--infocus', outfocus: prefix + 'day--outfocus', footer: prefix + 'footer', buttonClear: prefix + 'button--clear', buttonToday: prefix + 'button--today' } } })( Picker.klasses().picker + '__' ) /** * Extend the picker to add the date picker. */ Picker.extend( 'pickadate', DatePicker ) // Close the scope. })();