initial commit
This commit is contained in:
commit
52aad94550
94 changed files with 43651 additions and 0 deletions
983
node_modules/@materializecss/materialize/js/datepicker.js
generated
vendored
Executable file
983
node_modules/@materializecss/materialize/js/datepicker.js
generated
vendored
Executable file
|
@ -0,0 +1,983 @@
|
|||
(function($) {
|
||||
'use strict';
|
||||
|
||||
let _defaults = {
|
||||
// Close when date is selected
|
||||
autoClose: false,
|
||||
|
||||
// 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
|
||||
*
|
||||
*/
|
||||
class Datepicker extends Component {
|
||||
/**
|
||||
* Construct Datepicker instance and set up overlay
|
||||
* @constructor
|
||||
* @param {Element} el
|
||||
* @param {Object} options
|
||||
*/
|
||||
constructor(el, options) {
|
||||
super(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));
|
||||
}
|
||||
|
||||
let defDate = this.options.defaultDate;
|
||||
if (Datepicker._isDate(defDate)) {
|
||||
if (this.options.setDefaultDate) {
|
||||
this.setDate(defDate, true);
|
||||
this.setInputValue();
|
||||
} else {
|
||||
this.gotoDate(defDate);
|
||||
}
|
||||
} else {
|
||||
this.gotoDate(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes open/close state of datepicker
|
||||
* @type {Boolean}
|
||||
*/
|
||||
this.isOpen = false;
|
||||
}
|
||||
|
||||
static get defaults() {
|
||||
return _defaults;
|
||||
}
|
||||
|
||||
static init(els, options) {
|
||||
return super.init(this, els, options);
|
||||
}
|
||||
|
||||
static _isDate(obj) {
|
||||
return /Date/.test(Object.prototype.toString.call(obj)) && !isNaN(obj.getTime());
|
||||
}
|
||||
|
||||
static _isWeekend(date) {
|
||||
let day = date.getDay();
|
||||
return day === 0 || day === 6;
|
||||
}
|
||||
|
||||
static _setToStartOfDay(date) {
|
||||
if (Datepicker._isDate(date)) date.setHours(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
static _getDaysInMonth(year, month) {
|
||||
return [31, Datepicker._isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][
|
||||
month
|
||||
];
|
||||
}
|
||||
|
||||
static _isLeapYear(year) {
|
||||
// solution by Matti Virkkunen: http://stackoverflow.com/a/4881951
|
||||
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
|
||||
}
|
||||
|
||||
static _compareDates(a, b) {
|
||||
// weak date comparison (use setToStartOfDay(date) to ensure correct result)
|
||||
return a.getTime() === b.getTime();
|
||||
}
|
||||
|
||||
static _setToStartOfDay(date) {
|
||||
if (Datepicker._isDate(date)) date.setHours(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Instance
|
||||
*/
|
||||
static getInstance(el) {
|
||||
let domElem = !!el.jquery ? el[0] : el;
|
||||
return domElem.M_Datepicker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Teardown component
|
||||
*/
|
||||
destroy() {
|
||||
this._removeEventHandlers();
|
||||
this.modal.destroy();
|
||||
$(this.modalEl).remove();
|
||||
this.destroySelects();
|
||||
this.el.M_Datepicker = undefined;
|
||||
}
|
||||
|
||||
destroySelects() {
|
||||
let oldYearSelect = this.calendarEl.querySelector('.orig-select-year');
|
||||
if (oldYearSelect) {
|
||||
M.FormSelect.getInstance(oldYearSelect).destroy();
|
||||
}
|
||||
let oldMonthSelect = this.calendarEl.querySelector('.orig-select-month');
|
||||
if (oldMonthSelect) {
|
||||
M.FormSelect.getInstance(oldMonthSelect).destroy();
|
||||
}
|
||||
}
|
||||
|
||||
_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) {
|
||||
const optEl = this.options.container;
|
||||
this.options.container =
|
||||
optEl instanceof HTMLElement ? optEl : document.querySelector(optEl);
|
||||
this.$modalEl.appendTo(this.options.container);
|
||||
} else {
|
||||
this.$modalEl.insertBefore(this.el);
|
||||
}
|
||||
}
|
||||
|
||||
_setupModal() {
|
||||
this.modalEl.id = 'modal-' + this.id;
|
||||
this.modal = M.Modal.init(this.modalEl, {
|
||||
onCloseEnd: () => {
|
||||
this.isOpen = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
toString(format) {
|
||||
format = format || this.options.format;
|
||||
if (typeof format === 'function') {
|
||||
return format(this.date);
|
||||
}
|
||||
|
||||
if (!Datepicker._isDate(this.date)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
let formatArray = format.split(/(d{1,4}|m{1,4}|y{4}|yy|!.)/g);
|
||||
let formattedDate = formatArray
|
||||
.map((label) => {
|
||||
if (this.formats[label]) {
|
||||
return this.formats[label]();
|
||||
}
|
||||
|
||||
return label;
|
||||
})
|
||||
.join('');
|
||||
return formattedDate;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
let 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);
|
||||
}
|
||||
}
|
||||
|
||||
setInputValue() {
|
||||
this.el.value = this.toString();
|
||||
this.$el.trigger('change', { firedBy: this });
|
||||
}
|
||||
|
||||
_renderDateDisplay() {
|
||||
let displayDate = Datepicker._isDate(this.date) ? this.date : new Date();
|
||||
let i18n = this.options.i18n;
|
||||
let day = i18n.weekdaysShort[displayDate.getDay()];
|
||||
let month = i18n.monthsShort[displayDate.getMonth()];
|
||||
let date = displayDate.getDate();
|
||||
this.yearTextEl.innerHTML = displayDate.getFullYear();
|
||||
this.dateTextEl.innerHTML = `${day}, ${month} ${date}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* change view to a specific date
|
||||
*/
|
||||
gotoDate(date) {
|
||||
let newCalendar = true;
|
||||
|
||||
if (!Datepicker._isDate(date)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.calendars) {
|
||||
let 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()
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
this.adjustCalendars();
|
||||
}
|
||||
|
||||
adjustCalendars() {
|
||||
this.calendars[0] = this.adjustCalendar(this.calendars[0]);
|
||||
this.draw();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
nextMonth() {
|
||||
this.calendars[0].month++;
|
||||
this.adjustCalendars();
|
||||
}
|
||||
|
||||
prevMonth() {
|
||||
this.calendars[0].month--;
|
||||
this.adjustCalendars();
|
||||
}
|
||||
|
||||
render(year, month, randId) {
|
||||
let 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;
|
||||
}
|
||||
}
|
||||
let 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);
|
||||
let cells = days + before,
|
||||
after = cells;
|
||||
while (after > 7) {
|
||||
after -= 7;
|
||||
}
|
||||
cells += 7 - after;
|
||||
let isWeekSelected = false;
|
||||
for (let i = 0, r = 0; i < cells; i++) {
|
||||
let 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;
|
||||
}
|
||||
}
|
||||
|
||||
let 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);
|
||||
}
|
||||
|
||||
renderDay(opts) {
|
||||
let arr = [];
|
||||
let ariaSelected = 'false';
|
||||
if (opts.isEmpty) {
|
||||
if (opts.showDaysInNextAndPreviousMonths) {
|
||||
arr.push('is-outside-current-month');
|
||||
arr.push('is-selection-disabled');
|
||||
} else {
|
||||
return '<td class="is-empty"></td>';
|
||||
}
|
||||
}
|
||||
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 (
|
||||
`<td data-day="${opts.day}" class="${arr.join(' ')}" aria-selected="${ariaSelected}">` +
|
||||
`<button class="datepicker-day-button" type="button" data-year="${opts.year}" data-month="${opts.month}" data-day="${opts.day}">${opts.day}</button>` +
|
||||
'</td>'
|
||||
);
|
||||
}
|
||||
|
||||
renderRow(days, isRTL, isRowSelected) {
|
||||
return (
|
||||
'<tr class="datepicker-row' +
|
||||
(isRowSelected ? ' is-selected' : '') +
|
||||
'">' +
|
||||
(isRTL ? days.reverse() : days).join('') +
|
||||
'</tr>'
|
||||
);
|
||||
}
|
||||
|
||||
renderTable(opts, data, randId) {
|
||||
return (
|
||||
'<div class="datepicker-table-wrapper"><table cellpadding="0" cellspacing="0" class="datepicker-table" role="grid" aria-labelledby="' +
|
||||
randId +
|
||||
'">' +
|
||||
this.renderHead(opts) +
|
||||
this.renderBody(data) +
|
||||
'</table></div>'
|
||||
);
|
||||
}
|
||||
|
||||
renderHead(opts) {
|
||||
let i,
|
||||
arr = [];
|
||||
for (i = 0; i < 7; i++) {
|
||||
arr.push(
|
||||
`<th scope="col"><abbr title="${this.renderDayName(opts, i)}">${this.renderDayName(
|
||||
opts,
|
||||
i,
|
||||
true
|
||||
)}</abbr></th>`
|
||||
);
|
||||
}
|
||||
return '<thead><tr>' + (opts.isRTL ? arr.reverse() : arr).join('') + '</tr></thead>';
|
||||
}
|
||||
|
||||
renderBody(rows) {
|
||||
return '<tbody>' + rows.join('') + '</tbody>';
|
||||
}
|
||||
|
||||
renderTitle(instance, c, year, month, refYear, randId) {
|
||||
let i,
|
||||
j,
|
||||
arr,
|
||||
opts = this.options,
|
||||
isMinYear = year === opts.minYear,
|
||||
isMaxYear = year === opts.maxYear,
|
||||
html =
|
||||
'<div id="' +
|
||||
randId +
|
||||
'" class="datepicker-controls" role="heading" aria-live="assertive">',
|
||||
monthHtml,
|
||||
yearHtml,
|
||||
prev = true,
|
||||
next = true;
|
||||
|
||||
for (arr = [], i = 0; i < 12; i++) {
|
||||
arr.push(
|
||||
'<option value="' +
|
||||
(year === refYear ? i - c : 12 + i - c) +
|
||||
'"' +
|
||||
(i === month ? ' selected="selected"' : '') +
|
||||
((isMinYear && i < opts.minMonth) || (isMaxYear && i > opts.maxMonth)
|
||||
? 'disabled="disabled"'
|
||||
: '') +
|
||||
'>' +
|
||||
opts.i18n.months[i] +
|
||||
'</option>'
|
||||
);
|
||||
}
|
||||
|
||||
monthHtml =
|
||||
'<select class="datepicker-select orig-select-month" tabindex="-1">' +
|
||||
arr.join('') +
|
||||
'</select>';
|
||||
|
||||
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(`<option value="${i}" ${i === year ? 'selected="selected"' : ''}>${i}</option>`);
|
||||
}
|
||||
}
|
||||
if (opts.yearRangeReverse) {
|
||||
arr.reverse();
|
||||
}
|
||||
|
||||
yearHtml = `<select class="datepicker-select orig-select-year" tabindex="-1">${arr.join(
|
||||
''
|
||||
)}</select>`;
|
||||
|
||||
let leftArrow =
|
||||
'<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M15.41 16.09l-4.58-4.59 4.58-4.59L14 5.5l-6 6 6 6z"/><path d="M0-.5h24v24H0z" fill="none"/></svg>';
|
||||
html += `<button class="month-prev${
|
||||
prev ? '' : ' is-disabled'
|
||||
}" type="button">${leftArrow}</button>`;
|
||||
|
||||
html += '<div class="selects-container">';
|
||||
if (opts.showMonthAfterYear) {
|
||||
html += yearHtml + monthHtml;
|
||||
} else {
|
||||
html += monthHtml + yearHtml;
|
||||
}
|
||||
html += '</div>';
|
||||
|
||||
if (isMinYear && (month === 0 || opts.minMonth >= month)) {
|
||||
prev = false;
|
||||
}
|
||||
|
||||
if (isMaxYear && (month === 11 || opts.maxMonth <= month)) {
|
||||
next = false;
|
||||
}
|
||||
|
||||
let rightArrow =
|
||||
'<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"/><path d="M0-.25h24v24H0z" fill="none"/></svg>';
|
||||
html += `<button class="month-next${
|
||||
next ? '' : ' is-disabled'
|
||||
}" type="button">${rightArrow}</button>`;
|
||||
|
||||
return (html += '</div>');
|
||||
}
|
||||
|
||||
/**
|
||||
* refresh the HTML
|
||||
*/
|
||||
draw(force) {
|
||||
if (!this.isOpen && !force) {
|
||||
return;
|
||||
}
|
||||
let opts = this.options,
|
||||
minYear = opts.minYear,
|
||||
maxYear = opts.maxYear,
|
||||
minMonth = opts.minMonth,
|
||||
maxMonth = opts.maxMonth,
|
||||
html = '',
|
||||
randId;
|
||||
|
||||
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 =
|
||||
'datepicker-title-' +
|
||||
Math.random()
|
||||
.toString(36)
|
||||
.replace(/[^a-z]+/g, '')
|
||||
.substr(0, 2);
|
||||
|
||||
for (let 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
|
||||
let yearSelect = this.calendarEl.querySelector('.orig-select-year');
|
||||
let monthSelect = this.calendarEl.querySelector('.orig-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
|
||||
*/
|
||||
_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);
|
||||
}
|
||||
}
|
||||
|
||||
_setupVariables() {
|
||||
this.$modalEl = $(Datepicker._template);
|
||||
this.modalEl = this.$modalEl[0];
|
||||
|
||||
this.calendarEl = this.modalEl.querySelector('.datepicker-calendar');
|
||||
|
||||
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: () => {
|
||||
return this.date.getDate();
|
||||
},
|
||||
dd: () => {
|
||||
let d = this.date.getDate();
|
||||
return (d < 10 ? '0' : '') + d;
|
||||
},
|
||||
ddd: () => {
|
||||
return this.options.i18n.weekdaysShort[this.date.getDay()];
|
||||
},
|
||||
dddd: () => {
|
||||
return this.options.i18n.weekdays[this.date.getDay()];
|
||||
},
|
||||
m: () => {
|
||||
return this.date.getMonth() + 1;
|
||||
},
|
||||
mm: () => {
|
||||
let m = this.date.getMonth() + 1;
|
||||
return (m < 10 ? '0' : '') + m;
|
||||
},
|
||||
mmm: () => {
|
||||
return this.options.i18n.monthsShort[this.date.getMonth()];
|
||||
},
|
||||
mmmm: () => {
|
||||
return this.options.i18n.months[this.date.getMonth()];
|
||||
},
|
||||
yy: () => {
|
||||
return ('' + this.date.getFullYear()).slice(2);
|
||||
},
|
||||
yyyy: () => {
|
||||
return this.date.getFullYear();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove Event Handlers
|
||||
*/
|
||||
_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);
|
||||
}
|
||||
|
||||
_handleInputClick() {
|
||||
this.open();
|
||||
}
|
||||
|
||||
_handleInputKeydown(e) {
|
||||
if (e.which === M.keys.ENTER) {
|
||||
e.preventDefault();
|
||||
this.open();
|
||||
}
|
||||
}
|
||||
|
||||
_handleCalendarClick(e) {
|
||||
if (!this.isOpen) {
|
||||
return;
|
||||
}
|
||||
|
||||
let $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-year'),
|
||||
e.target.getAttribute('data-month'),
|
||||
e.target.getAttribute('data-day')
|
||||
)
|
||||
);
|
||||
if (this.options.autoClose) {
|
||||
this._finishSelection();
|
||||
}
|
||||
} else if ($target.closest('.month-prev').length) {
|
||||
this.prevMonth();
|
||||
} else if ($target.closest('.month-next').length) {
|
||||
this.nextMonth();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_handleClearClick() {
|
||||
this.date = null;
|
||||
this.setInputValue();
|
||||
this.close();
|
||||
}
|
||||
|
||||
_handleMonthChange(e) {
|
||||
this.gotoMonth(e.target.value);
|
||||
}
|
||||
|
||||
_handleYearChange(e) {
|
||||
this.gotoYear(e.target.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* change view to a specific month (zero-index, e.g. 0: January)
|
||||
*/
|
||||
gotoMonth(month) {
|
||||
if (!isNaN(month)) {
|
||||
this.calendars[0].month = parseInt(month, 10);
|
||||
this.adjustCalendars();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* change view to a specific full year (e.g. "2012")
|
||||
*/
|
||||
gotoYear(year) {
|
||||
if (!isNaN(year)) {
|
||||
this.calendars[0].year = parseInt(year, 10);
|
||||
this.adjustCalendars();
|
||||
}
|
||||
}
|
||||
|
||||
_handleInputChange(e) {
|
||||
let date;
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
_finishSelection() {
|
||||
this.setInputValue();
|
||||
this.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Open Datepicker
|
||||
*/
|
||||
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
|
||||
*/
|
||||
close() {
|
||||
if (!this.isOpen) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.isOpen = false;
|
||||
if (typeof this.options.onClose === 'function') {
|
||||
this.options.onClose.call(this);
|
||||
}
|
||||
this.modal.close();
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
Datepicker._template = [
|
||||
'<div class= "modal datepicker-modal">',
|
||||
'<div class="modal-content datepicker-container">',
|
||||
'<div class="datepicker-date-display">',
|
||||
'<span class="year-text"></span>',
|
||||
'<span class="date-text"></span>',
|
||||
'</div>',
|
||||
'<div class="datepicker-calendar-container">',
|
||||
'<div class="datepicker-calendar"></div>',
|
||||
'<div class="datepicker-footer">',
|
||||
'<button class="btn-flat datepicker-clear waves-effect" style="visibility: hidden;" type="button"></button>',
|
||||
'<div class="confirmation-btns">',
|
||||
'<button class="btn-flat datepicker-cancel waves-effect" type="button"></button>',
|
||||
'<button class="btn-flat datepicker-done waves-effect" type="button"></button>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'</div>'
|
||||
].join('');
|
||||
|
||||
M.Datepicker = Datepicker;
|
||||
|
||||
if (M.jQueryLoaded) {
|
||||
M.initializeJqueryWrapper(Datepicker, 'datepicker', 'M_Datepicker');
|
||||
}
|
||||
})(cash);
|
Loading…
Add table
Add a link
Reference in a new issue