UNPKG

vanillajs-datepicker

Version:

A vanilla JavaScript remake of bootstrap-datepicker for Bulma and other CSS frameworks

149 lines (136 loc) 4.51 kB
import {pushUnique, createTagRepeat} from '../../lib/utils.js'; import {dateValue, regularizeDate} from '../../lib/date.js'; import {parseHTML} from '../../lib/dom.js'; import View from './View.js'; function computeMonthRange(range, thisYear) { if (!range || !range[0] || !range[1]) { return; } const [[startY, startM], [endY, endM]] = range; if (startY > thisYear || endY < thisYear) { return; } return [ startY === thisYear ? startM : -1, endY === thisYear ? endM : 12, ]; } export default class MonthsView extends View { constructor(picker) { super(picker, { id: 1, name: 'months', cellClass: 'month', }); } init(options, onConstruction = true) { if (onConstruction) { this.grid = this.element; this.element.classList.add('months', 'datepicker-grid'); this.grid.appendChild(parseHTML(createTagRepeat('span', 12, {'data-month': ix => ix}))); this.first = 0; this.last = 11; } super.init(options); } setOptions(options) { if (options.locale) { this.monthNames = options.locale.monthsShort; } if ('minDate' in options) { if (options.minDate === undefined) { this.minYear = this.minMonth = this.minDate = undefined; } else { const minDateObj = new Date(options.minDate); this.minYear = minDateObj.getFullYear(); this.minMonth = minDateObj.getMonth(); this.minDate = minDateObj.setDate(1); } } if ('maxDate' in options) { if (options.maxDate === undefined) { this.maxYear = this.maxMonth = this.maxDate = undefined; } else { const maxDateObj = new Date(options.maxDate); this.maxYear = maxDateObj.getFullYear(); this.maxMonth = maxDateObj.getMonth(); this.maxDate = dateValue(this.maxYear, this.maxMonth + 1, 0); } } if (options.checkDisabled) { this.checkDisabled = this.isMinView || options.datesDisabled === null ? options.checkDisabled : () => false; } if ('beforeShowMonth' in options) { this.beforeShow = typeof options.beforeShowMonth === 'function' ? options.beforeShowMonth : undefined; } } // Update view's settings to reflect the viewDate set on the picker updateFocus() { const viewDate = new Date(this.picker.viewDate); this.year = viewDate.getFullYear(); this.focused = viewDate.getMonth(); } // Update view's settings to reflect the selected dates updateSelection() { const {dates, rangepicker} = this.picker.datepicker; this.selected = dates.reduce((selected, timeValue) => { const date = new Date(timeValue); const year = date.getFullYear(); const month = date.getMonth(); if (selected[year] === undefined) { selected[year] = [month]; } else { pushUnique(selected[year], month); } return selected; }, {}); if (rangepicker && rangepicker.dates) { this.range = rangepicker.dates.map(timeValue => { const date = new Date(timeValue); return isNaN(date) ? undefined : [date.getFullYear(), date.getMonth()]; }); } } // Update the entire view UI render() { this.prepareForRender( this.year, this.year <= this.minYear, this.year >= this.maxYear ); const selected = this.selected[this.year] || []; const yrOutOfRange = this.year < this.minYear || this.year > this.maxYear; const isMinYear = this.year === this.minYear; const isMaxYear = this.year === this.maxYear; const range = computeMonthRange(this.range, this.year); Array.from(this.grid.children).forEach((el, index) => { const date = regularizeDate(new Date(this.year, index, 1), 1, this.isRangeEnd); this.renderCell( el, this.monthNames[index], index, date, {selected, range}, yrOutOfRange || isMinYear && index < this.minMonth || isMaxYear && index > this.maxMonth ); }); } // Update the view UI by applying the changes of selected and focused items refresh() { const selected = this.selected[this.year] || []; const range = computeMonthRange(this.range, this.year) || []; Array.from(this.grid.children).forEach((el, index) => { this.refreshCell(el, index, selected, range); }); } // Update the view UI by applying the change of focused item refreshFocus() { this.changeFocusedCell(this.focused); } }