var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } (function ($) { 'use strict'; var _defaults = { // the default output format for the input field value format: 'mmm dd, yyyy', // Used to create date object from current input string parse: null, // The initial date to view when first opened defaultDate: null, // Make the `defaultDate` the initial selected value setDefaultDate: false, disableWeekends: false, disableDayFn: null, // First day of week (0: Sunday, 1: Monday etc) firstDay: 0, // The earliest date that can be selected minDate: null, // Thelatest date that can be selected maxDate: null, // Number of years either side, or array of upper/lower range yearRange: 10, // used internally (don't config outside) minYear: 0, maxYear: 9999, minMonth: undefined, maxMonth: undefined, startRange: null, endRange: null, isRTL: false, // Render the month after year in the calendar title showMonthAfterYear: false, // Render days of the calendar grid that fall in the next or previous month showDaysInNextAndPreviousMonths: false, // Specify a DOM element to render the calendar in container: null, // Show clear button showClearBtn: false, // internationalization i18n: { cancel: 'Cancel', clear: 'Clear', done: 'Ok', previousMonth: '‹', nextMonth: '›', months: ['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'], weekdays: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], weekdaysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], weekdaysAbbrev: ['S', 'M', 'T', 'W', 'T', 'F', 'S'] }, // events array events: [], // callback function onSelect: null, onOpen: null, onClose: null, onDraw: null }; /** * @class * */ var Datepicker = function (_Component) { _inherits(Datepicker, _Component); /** * Construct Datepicker instance and set up overlay * @constructor * @param {Element} el * @param {Object} options */ function Datepicker(el, options) { _classCallCheck(this, Datepicker); var _this = _possibleConstructorReturn(this, (Datepicker.__proto__ || Object.getPrototypeOf(Datepicker)).call(this, Datepicker, el, options)); _this.el.M_Datepicker = _this; _this.options = $.extend({}, Datepicker.defaults, options); // make sure i18n defaults are not lost when only few i18n option properties are passed if (!!options && options.hasOwnProperty('i18n') && typeof options.i18n === 'object') { _this.options.i18n = $.extend({}, Datepicker.defaults.i18n, options.i18n); } // Remove time component from minDate and maxDate options if (_this.options.minDate) _this.options.minDate.setHours(0, 0, 0, 0); if (_this.options.maxDate) _this.options.maxDate.setHours(0, 0, 0, 0); _this.id = M.guid(); _this._setupVariables(); _this._insertHTMLIntoDOM(); _this._setupModal(); _this._setupEventHandlers(); if (!_this.options.defaultDate) { _this.options.defaultDate = new Date(Date.parse(_this.el.value)); _this.options.setDefaultDate = true; } var defDate = _this.options.defaultDate; if (Datepicker._isDate(defDate)) { if (_this.options.setDefaultDate) { _this.setDate(defDate, true); } else { _this.gotoDate(defDate); } } else { _this.gotoDate(new Date()); } /** * Describes open/close state of datepicker * @type {Boolean} */ _this.isOpen = false; return _this; } _createClass(Datepicker, [{ key: 'destroy', /** * Teardown component */ value: function destroy() { this._removeEventHandlers(); this.modal.destroy(); $(this.modalEl).remove(); this.destroySelects(); this.el.M_Datepicker = undefined; } }, { key: 'destroySelects', value: function destroySelects() { var oldYearSelect = this.calendarEl.querySelector('.pika-select-year'); if (oldYearSelect) { M.FormSelect.getInstance(oldYearSelect).destroy(); } var oldMonthSelect = this.calendarEl.querySelector('.pika-select-month'); if (oldMonthSelect) { M.FormSelect.getInstance(oldMonthSelect).destroy(); } } }, { key: '_insertHTMLIntoDOM', value: function _insertHTMLIntoDOM() { if (this.options.showClearBtn) { $(this.clearBtn).css({ visibility: '' }); this.clearBtn.innerHTML = this.options.i18n.clear; } this.doneBtn.innerHTML = this.options.i18n.done; this.cancelBtn.innerHTML = this.options.i18n.cancel; if (this.options.container) { this.$modalEl.appendTo(this.options.container); } else { this.$modalEl.insertBefore(this.el); } } }, { key: '_setupModal', value: function _setupModal() { var _this2 = this; this.modalEl.id = 'modal-' + this.id; this.modal = M.Modal.init(this.modalEl, { onCloseEnd: function () { _this2.isOpen = false; } }); } }, { key: 'toString', value: function toString(format) { var _this3 = this; format = format || this.options.format; if (!Datepicker._isDate(this.date)) { return ''; } var formatArray = format.split(/(d{1,4}|m{1,4}|y{4}|yy|!.)/g); var formattedDate = formatArray.map(function (label) { if (_this3.formats[label]) { return _this3.formats[label](); } return label; }).join(''); return formattedDate; } }, { key: 'setDate', value: function setDate(date, preventOnSelect) { if (!date) { this.date = null; this._renderDateDisplay(); return this.draw(); } if (typeof date === 'string') { date = new Date(Date.parse(date)); } if (!Datepicker._isDate(date)) { return; } var min = this.options.minDate, max = this.options.maxDate; if (Datepicker._isDate(min) && date < min) { date = min; } else if (Datepicker._isDate(max) && date > max) { date = max; } this.date = new Date(date.getTime()); this._renderDateDisplay(); Datepicker._setToStartOfDay(this.date); this.gotoDate(this.date); if (!preventOnSelect && typeof this.options.onSelect === 'function') { this.options.onSelect.call(this, this.date); } } }, { key: 'setInputValue', value: function setInputValue() { this.el.value = this.toString(); this.$el.trigger('change', { firedBy: this }); } }, { key: '_renderDateDisplay', value: function _renderDateDisplay() { var displayDate = Datepicker._isDate(this.date) ? this.date : new Date(); var i18n = this.options.i18n; var day = i18n.weekdaysShort[displayDate.getDay()]; var month = i18n.monthsShort[displayDate.getMonth()]; var date = displayDate.getDate(); this.yearTextEl.innerHTML = displayDate.getFullYear(); this.dateTextEl.innerHTML = day + ', ' + month + ' ' + date; } /** * change view to a specific date */ }, { key: 'gotoDate', value: function gotoDate(date) { var newCalendar = true; if (!Datepicker._isDate(date)) { return; } if (this.calendars) { var firstVisibleDate = new Date(this.calendars[0].year, this.calendars[0].month, 1), lastVisibleDate = new Date(this.calendars[this.calendars.length - 1].year, this.calendars[this.calendars.length - 1].month, 1), visibleDate = date.getTime(); // get the end of the month lastVisibleDate.setMonth(lastVisibleDate.getMonth() + 1); lastVisibleDate.setDate(lastVisibleDate.getDate() - 1); newCalendar = visibleDate < firstVisibleDate.getTime() || lastVisibleDate.getTime() < visibleDate; } if (newCalendar) { this.calendars = [{ month: date.getMonth(), year: date.getFullYear() }]; // if (this.options.mainCalendar === 'right') { // this.calendars[0].month += 1 - this.options.numberOfMonths; // } } this.adjustCalendars(); } }, { key: 'adjustCalendars', value: function adjustCalendars() { this.calendars[0] = this.adjustCalendar(this.calendars[0]); // for (let c = 1; c < this.options.numberOfMonths; c++) { // this.calendars[c] = this.adjustCalendar({ // month: this.calendars[0].month + c, // year: this.calendars[0].year // }); // } this.draw(); } }, { key: 'adjustCalendar', value: function adjustCalendar(calendar) { if (calendar.month < 0) { calendar.year -= Math.ceil(Math.abs(calendar.month) / 12); calendar.month += 12; } if (calendar.month > 11) { calendar.year += Math.floor(Math.abs(calendar.month) / 12); calendar.month -= 12; } return calendar; } }, { key: 'nextMonth', value: function nextMonth() { this.calendars[0].month++; this.adjustCalendars(); } }, { key: 'prevMonth', value: function prevMonth() { this.calendars[0].month--; this.adjustCalendars(); } }, { key: 'render', value: function render(year, month, randId) { var opts = this.options, now = new Date(), days = Datepicker._getDaysInMonth(year, month), before = new Date(year, month, 1).getDay(), data = [], row = []; Datepicker._setToStartOfDay(now); if (opts.firstDay > 0) { before -= opts.firstDay; if (before < 0) { before += 7; } } var previousMonth = month === 0 ? 11 : month - 1, nextMonth = month === 11 ? 0 : month + 1, yearOfPreviousMonth = month === 0 ? year - 1 : year, yearOfNextMonth = month === 11 ? year + 1 : year, daysInPreviousMonth = Datepicker._getDaysInMonth(yearOfPreviousMonth, previousMonth); var cells = days + before, after = cells; while (after > 7) { after -= 7; } cells += 7 - after; var isWeekSelected = false; for (var i = 0, r = 0; i < cells; i++) { var day = new Date(year, month, 1 + (i - before)), isSelected = Datepicker._isDate(this.date) ? Datepicker._compareDates(day, this.date) : false, isToday = Datepicker._compareDates(day, now), hasEvent = opts.events.indexOf(day.toDateString()) !== -1 ? true : false, isEmpty = i < before || i >= days + before, dayNumber = 1 + (i - before), monthNumber = month, yearNumber = year, isStartRange = opts.startRange && Datepicker._compareDates(opts.startRange, day), isEndRange = opts.endRange && Datepicker._compareDates(opts.endRange, day), isInRange = opts.startRange && opts.endRange && opts.startRange < day && day < opts.endRange, isDisabled = opts.minDate && day < opts.minDate || opts.maxDate && day > opts.maxDate || opts.disableWeekends && Datepicker._isWeekend(day) || opts.disableDayFn && opts.disableDayFn(day); if (isEmpty) { if (i < before) { dayNumber = daysInPreviousMonth + dayNumber; monthNumber = previousMonth; yearNumber = yearOfPreviousMonth; } else { dayNumber = dayNumber - days; monthNumber = nextMonth; yearNumber = yearOfNextMonth; } } var dayConfig = { day: dayNumber, month: monthNumber, year: yearNumber, hasEvent: hasEvent, isSelected: isSelected, isToday: isToday, isDisabled: isDisabled, isEmpty: isEmpty, isStartRange: isStartRange, isEndRange: isEndRange, isInRange: isInRange, showDaysInNextAndPreviousMonths: opts.showDaysInNextAndPreviousMonths }; row.push(this.renderDay(dayConfig)); if (++r === 7) { data.push(this.renderRow(row, opts.isRTL, isWeekSelected)); row = []; r = 0; isWeekSelected = false; } } return this.renderTable(opts, data, randId); } }, { key: 'renderDay', value: function renderDay(opts) { var arr = []; var ariaSelected = 'false'; if (opts.isEmpty) { if (opts.showDaysInNextAndPreviousMonths) { arr.push('is-outside-current-month'); arr.push('is-selection-disabled'); } else { return ''; } } if (opts.isDisabled) { arr.push('is-disabled'); } if (opts.isToday) { arr.push('is-today'); } if (opts.isSelected) { arr.push('is-selected'); ariaSelected = 'true'; } if (opts.hasEvent) { arr.push('has-event'); } if (opts.isInRange) { arr.push('is-inrange'); } if (opts.isStartRange) { arr.push('is-startrange'); } if (opts.isEndRange) { arr.push('is-endrange'); } return '' + '' + ''; } }, { key: 'renderRow', value: function renderRow(days, isRTL, isRowSelected) { return '' + (isRTL ? days.reverse() : days).join('') + ''; } }, { key: 'renderTable', value: function renderTable(opts, data, randId) { return '
' + this.renderHead(opts) + this.renderBody(data) + '
'; } }, { key: 'renderHead', value: function renderHead(opts) { var i = void 0, arr = []; for (i = 0; i < 7; i++) { arr.push('' + this.renderDayName(opts, i, true) + ''); } return '' + (opts.isRTL ? arr.reverse() : arr).join('') + ''; } }, { key: 'renderBody', value: function renderBody(rows) { return '' + rows.join('') + ''; } }, { key: 'renderTitle', value: function renderTitle(instance, c, year, month, refYear, randId) { var i = void 0, j = void 0, arr = void 0, opts = this.options, isMinYear = year === opts.minYear, isMaxYear = year === opts.maxYear, html = '
', monthHtml = void 0, yearHtml = void 0, prev = true, next = true; for (arr = [], i = 0; i < 12; i++) { arr.push(''); } monthHtml = ''; if ($.isArray(opts.yearRange)) { i = opts.yearRange[0]; j = opts.yearRange[1] + 1; } else { i = year - opts.yearRange; j = 1 + year + opts.yearRange; } for (arr = []; i < j && i <= opts.maxYear; i++) { if (i >= opts.minYear) { arr.push(''); } } yearHtml = ''; var leftArrow = ''; html += ''; html += '
'; if (opts.showMonthAfterYear) { html += yearHtml + monthHtml; } else { html += monthHtml + yearHtml; } html += '
'; if (isMinYear && (month === 0 || opts.minMonth >= month)) { prev = false; } if (isMaxYear && (month === 11 || opts.maxMonth <= month)) { next = false; } // if (c === (this.options.numberOfMonths - 1) ) { var rightArrow = ''; html += ''; // } return html += '
'; } /** * refresh the HTML */ }, { key: 'draw', value: function draw(force) { if (!this.isOpen && !force) { return; } var opts = this.options, minYear = opts.minYear, maxYear = opts.maxYear, minMonth = opts.minMonth, maxMonth = opts.maxMonth, html = '', randId = void 0; if (this._y <= minYear) { this._y = minYear; if (!isNaN(minMonth) && this._m < minMonth) { this._m = minMonth; } } if (this._y >= maxYear) { this._y = maxYear; if (!isNaN(maxMonth) && this._m > maxMonth) { this._m = maxMonth; } } randId = 'pika-title-' + Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 2); for (var c = 0; c < 1; c++) { this._renderDateDisplay(); html += this.renderTitle(this, c, this.calendars[c].year, this.calendars[c].month, this.calendars[0].year, randId) + this.render(this.calendars[c].year, this.calendars[c].month, randId); } this.destroySelects(); this.calendarEl.innerHTML = html; // Init Materialize Select var yearSelect = this.calendarEl.querySelector('.pika-select-year'); var monthSelect = this.calendarEl.querySelector('.pika-select-month'); M.FormSelect.init(yearSelect, { classes: 'select-year', dropdownOptions: { container: document.body, constrainWidth: false } }); M.FormSelect.init(monthSelect, { classes: 'select-month', dropdownOptions: { container: document.body, constrainWidth: false } }); // Add change handlers for select yearSelect.addEventListener('change', this._handleYearChange.bind(this)); monthSelect.addEventListener('change', this._handleMonthChange.bind(this)); if (typeof this.options.onDraw === 'function') { this.options.onDraw(this); } } /** * Setup Event Handlers */ }, { key: '_setupEventHandlers', value: function _setupEventHandlers() { this._handleInputKeydownBound = this._handleInputKeydown.bind(this); this._handleInputClickBound = this._handleInputClick.bind(this); this._handleInputChangeBound = this._handleInputChange.bind(this); this._handleCalendarClickBound = this._handleCalendarClick.bind(this); this._finishSelectionBound = this._finishSelection.bind(this); this._handleMonthChange = this._handleMonthChange.bind(this); this._closeBound = this.close.bind(this); this.el.addEventListener('click', this._handleInputClickBound); this.el.addEventListener('keydown', this._handleInputKeydownBound); this.el.addEventListener('change', this._handleInputChangeBound); this.calendarEl.addEventListener('click', this._handleCalendarClickBound); this.doneBtn.addEventListener('click', this._finishSelectionBound); this.cancelBtn.addEventListener('click', this._closeBound); if (this.options.showClearBtn) { this._handleClearClickBound = this._handleClearClick.bind(this); this.clearBtn.addEventListener('click', this._handleClearClickBound); } } }, { key: '_setupVariables', value: function _setupVariables() { var _this4 = this; this.$modalEl = $(Datepicker._template); this.modalEl = this.$modalEl[0]; this.calendarEl = this.modalEl.querySelector('.pika-single'); this.yearTextEl = this.modalEl.querySelector('.year-text'); this.dateTextEl = this.modalEl.querySelector('.date-text'); if (this.options.showClearBtn) { this.clearBtn = this.modalEl.querySelector('.datepicker-clear'); } this.doneBtn = this.modalEl.querySelector('.datepicker-done'); this.cancelBtn = this.modalEl.querySelector('.datepicker-cancel'); this.formats = { d: function () { return _this4.date.getDate(); }, dd: function () { var d = _this4.date.getDate(); return (d < 10 ? '0' : '') + d; }, ddd: function () { return _this4.options.i18n.weekdaysShort[_this4.date.getDay()]; }, dddd: function () { return _this4.options.i18n.weekdays[_this4.date.getDay()]; }, m: function () { return _this4.date.getMonth() + 1; }, mm: function () { var m = _this4.date.getMonth() + 1; return (m < 10 ? '0' : '') + m; }, mmm: function () { return _this4.options.i18n.monthsShort[_this4.date.getMonth()]; }, mmmm: function () { return _this4.options.i18n.months[_this4.date.getMonth()]; }, yy: function () { return ('' + _this4.date.getFullYear()).slice(2); }, yyyy: function () { return _this4.date.getFullYear(); } }; } /** * Remove Event Handlers */ }, { key: '_removeEventHandlers', value: function _removeEventHandlers() { this.el.removeEventListener('click', this._handleInputClickBound); this.el.removeEventListener('keydown', this._handleInputKeydownBound); this.el.removeEventListener('change', this._handleInputChangeBound); this.calendarEl.removeEventListener('click', this._handleCalendarClickBound); } }, { key: '_handleInputClick', value: function _handleInputClick() { this.open(); } }, { key: '_handleInputKeydown', value: function _handleInputKeydown(e) { if (e.which === M.keys.ENTER) { e.preventDefault(); this.open(); } } }, { key: '_handleCalendarClick', value: function _handleCalendarClick(e) { if (!this.isOpen) { return; } var $target = $(e.target); if (!$target.hasClass('is-disabled')) { if ($target.hasClass('datepicker-day-button') && !$target.hasClass('is-empty') && !$target.parent().hasClass('is-disabled')) { this.setDate(new Date(e.target.getAttribute('data-pika-year'), e.target.getAttribute('data-pika-month'), e.target.getAttribute('data-pika-day'))); } else if ($target.closest('.month-prev').length) { this.prevMonth(); } else if ($target.closest('.month-next').length) { this.nextMonth(); } } // if (!$target.hasClass('pika-select')) { // // if this is touch event prevent mouse events emulation // // if (e.preventDefault) { // // e.preventDefault(); // // } else { // // e.returnValue = false; // // return false; // // } // } else { // this._c = true; // } } }, { key: '_handleClearClick', value: function _handleClearClick() { this.date = null; this.setInputValue(); this.close(); } }, { key: '_handleMonthChange', value: function _handleMonthChange(e) { this.gotoMonth(e.target.value); } }, { key: '_handleYearChange', value: function _handleYearChange(e) { this.gotoYear(e.target.value); } /** * change view to a specific month (zero-index, e.g. 0: January) */ }, { key: 'gotoMonth', value: function gotoMonth(month) { if (!isNaN(month)) { this.calendars[0].month = parseInt(month, 10); this.adjustCalendars(); } } /** * change view to a specific full year (e.g. "2012") */ }, { key: 'gotoYear', value: function gotoYear(year) { if (!isNaN(year)) { this.calendars[0].year = parseInt(year, 10); this.adjustCalendars(); } } }, { key: '_handleInputChange', value: function _handleInputChange(e) { var date = void 0; // Prevent change event from being fired when triggered by the plugin if (e.firedBy === this) { return; } if (this.options.parse) { date = this.options.parse(this.el.value, this.options.format); } else { date = new Date(Date.parse(this.el.value)); } if (Datepicker._isDate(date)) { this.setDate(date); } // if (!self._v) { // self.show(); // } } }, { key: 'renderDayName', value: function renderDayName(opts, day, abbr) { day += opts.firstDay; while (day >= 7) { day -= 7; } return abbr ? opts.i18n.weekdaysAbbrev[day] : opts.i18n.weekdays[day]; } /** * Set input value to the selected date and close Datepicker */ }, { key: '_finishSelection', value: function _finishSelection() { this.setInputValue(); this.close(); } /** * Open Datepicker */ }, { key: 'open', value: function open() { if (this.isOpen) { return; } this.isOpen = true; if (typeof this.options.onOpen === 'function') { this.options.onOpen.call(this); } this.draw(); this.modal.open(); return this; } /** * Close Datepicker */ }, { key: 'close', value: function close() { if (!this.isOpen) { return; } this.isOpen = false; if (typeof this.options.onClose === 'function') { this.options.onClose.call(this); } this.modal.close(); return this; } }], [{ key: 'init', value: function init(els, options) { return _get(Datepicker.__proto__ || Object.getPrototypeOf(Datepicker), 'init', this).call(this, this, els, options); } }, { key: '_isDate', value: function _isDate(obj) { return (/Date/.test(Object.prototype.toString.call(obj)) && !isNaN(obj.getTime()) ); } }, { key: '_isWeekend', value: function _isWeekend(date) { var day = date.getDay(); return day === 0 || day === 6; } }, { key: '_setToStartOfDay', value: function _setToStartOfDay(date) { if (Datepicker._isDate(date)) date.setHours(0, 0, 0, 0); } }, { key: '_getDaysInMonth', value: function _getDaysInMonth(year, month) { return [31, Datepicker._isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]; } }, { key: '_isLeapYear', value: function _isLeapYear(year) { // solution by Matti Virkkunen: http://stackoverflow.com/a/4881951 return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0; } }, { key: '_compareDates', value: function _compareDates(a, b) { // weak date comparison (use setToStartOfDay(date) to ensure correct result) return a.getTime() === b.getTime(); } }, { key: '_setToStartOfDay', value: function _setToStartOfDay(date) { if (Datepicker._isDate(date)) date.setHours(0, 0, 0, 0); } /** * Get Instance */ }, { key: 'getInstance', value: function getInstance(el) { var domElem = !!el.jquery ? el[0] : el; return domElem.M_Datepicker; } }, { key: 'defaults', get: function () { return _defaults; } }]); return Datepicker; }(Component); Datepicker._template = [''].join(''); M.Datepicker = Datepicker; if (M.jQueryLoaded) { M.initializeJqueryWrapper(Datepicker, 'datepicker', 'M_Datepicker'); } })(cash);