UNPKG

vanillajs-datepicker

Version:

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

194 lines (175 loc) 5.94 kB
import {today, dateValue, addDays, addWeeks, dayOfTheWeekOf} from '../../lib/date.js'; import {formatDate} from '../../lib/date-format.js'; import {parseHTML, showElement, hideElement} from '../../lib/dom.js'; import daysTemplate from '../templates/daysTemplate.js'; import weekNumbersTemplate from '../templates/weekNumbersTemplate.js'; import View from './View.js'; export default class DaysView extends View { constructor(picker) { super(picker, { id: 0, name: 'days', cellClass: 'day', }); } init(options, onConstruction = true) { if (onConstruction) { const inner = parseHTML(daysTemplate).firstChild; this.dow = inner.firstChild; this.grid = inner.lastChild; this.element.appendChild(inner); } super.init(options); } setOptions(options) { let updateDOW; if ('minDate' in options) { this.minDate = options.minDate; } if ('maxDate' in options) { this.maxDate = options.maxDate; } if (options.checkDisabled) { this.checkDisabled = options.checkDisabled; } if (options.daysOfWeekDisabled) { this.daysOfWeekDisabled = options.daysOfWeekDisabled; updateDOW = true; } if (options.daysOfWeekHighlighted) { this.daysOfWeekHighlighted = options.daysOfWeekHighlighted; } if ('todayHighlight' in options) { this.todayHighlight = options.todayHighlight; } if ('weekStart' in options) { this.weekStart = options.weekStart; this.weekEnd = options.weekEnd; updateDOW = true; } if (options.locale) { const locale = this.locale = options.locale; this.dayNames = locale.daysMin; this.switchLabelFormat = locale.titleFormat; updateDOW = true; } if ('beforeShowDay' in options) { this.beforeShow = typeof options.beforeShowDay === 'function' ? options.beforeShowDay : undefined; } if ('weekNumbers' in options) { if (options.weekNumbers && !this.weekNumbers) { const weeksElem = parseHTML(weekNumbersTemplate).firstChild; this.weekNumbers = { element: weeksElem, dow: weeksElem.firstChild, weeks: weeksElem.lastChild, }; this.element.insertBefore(weeksElem, this.element.firstChild); } else if (this.weekNumbers && !options.weekNumbers) { this.element.removeChild(this.weekNumbers.element); this.weekNumbers = null; } } if ('getWeekNumber' in options) { this.getWeekNumber = options.getWeekNumber; } if ('showDaysOfWeek' in options) { if (options.showDaysOfWeek) { showElement(this.dow); if (this.weekNumbers) { showElement(this.weekNumbers.dow); } } else { hideElement(this.dow); if (this.weekNumbers) { hideElement(this.weekNumbers.dow); } } } // update days-of-week when locale, daysOfweekDisabled or weekStart is changed if (updateDOW) { Array.from(this.dow.children).forEach((el, index) => { const dow = (this.weekStart + index) % 7; el.textContent = this.dayNames[dow]; el.className = this.daysOfWeekDisabled.includes(dow) ? 'dow disabled' : 'dow'; }); } } // Apply update on the focused date to view's settings updateFocus() { const viewDate = new Date(this.picker.viewDate); const viewYear = viewDate.getFullYear(); const viewMonth = viewDate.getMonth(); const firstOfMonth = dateValue(viewYear, viewMonth, 1); const start = dayOfTheWeekOf(firstOfMonth, this.weekStart, this.weekStart); this.first = firstOfMonth; this.last = dateValue(viewYear, viewMonth + 1, 0); this.start = start; this.focused = this.picker.viewDate; } // Apply update on the selected dates to view's settings updateSelection() { const {dates, rangepicker} = this.picker.datepicker; this.selected = dates; if (rangepicker) { this.range = rangepicker.dates; } } // Update the entire view UI render() { // update today marker on ever render this.today = this.todayHighlight ? today() : undefined; this.prepareForRender( formatDate(this.focused, this.switchLabelFormat, this.locale), this.first <= this.minDate, this.last >= this.maxDate ); if (this.weekNumbers) { const weekStart = this.weekStart; const startOfWeek = dayOfTheWeekOf(this.first, weekStart, weekStart); Array.from(this.weekNumbers.weeks.children).forEach((el, index) => { const dateOfWeekStart = addWeeks(startOfWeek, index); el.textContent = this.getWeekNumber(dateOfWeekStart, weekStart); if (index > 3) { el.classList[dateOfWeekStart > this.last ? 'add' : 'remove']('next'); } }); } Array.from(this.grid.children).forEach((el, index) => { const current = addDays(this.start, index); const dateObj = new Date(current); const day = dateObj.getDay(); const extraClasses = []; if (this.today === current) { extraClasses.push('today'); } if (this.daysOfWeekHighlighted.includes(day)) { extraClasses.push('highlighted'); } this.renderCell( el, dateObj.getDate(), current, current, this, current < this.minDate || current > this.maxDate || this.daysOfWeekDisabled.includes(day), extraClasses ); }); } // Update the view UI by applying the changes of selected and focused items refresh() { const range = this.range || []; Array.from(this.grid.children).forEach((el) => { this.refreshCell(el, Number(el.dataset.date), this.selected, range); }); } // Update the view UI by applying the change of focused item refreshFocus() { this.changeFocusedCell(Math.round((this.focused - this.start) / 86400000)); } }