Files
myep/assets/controllers/datepicker_controller.js
T

71 lines
2.6 KiB
JavaScript

import { Controller } from '@hotwired/stimulus'
import { Calendar } from 'vanilla-calendar-pro'
/* stimulusFetch: 'lazy' */
export default class extends Controller {
static targets = ['field', 'hiddenField']
static values = {
minDate: String,
maxDate: String,
disableWeekends: Boolean,
disabledDates: Array,
}
connect() {
const options = {
inputMode: true,
locale: 'de-DE',
selectedTheme: 'light',
selectedDates: this.hiddenFieldTarget.value ? [this.hiddenFieldTarget.value] : [],
onClickDate: (self) => {
const iso = self.context.selectedDates[0] ?? null
this.hiddenFieldTarget.value = iso ?? ''
if (iso) {
const [year, month, day] = iso.split('-')
this.fieldTarget.value = `${day}.${month}.${year}`
} else {
this.fieldTarget.value = ''
}
this.element.dispatchEvent(new CustomEvent('datepicker:picked', {
detail: { date: this.fieldTarget.value }
}))
},
onHide: () => {
this.element.dispatchEvent(new CustomEvent('datepicker:closed'))
},
}
if (this.minDateValue) options.dateMin = this.minDateValue
if (this.maxDateValue) options.dateMax = this.maxDateValue
if (this.disableWeekendsValue) options.disableWeekdays = [0, 6]
if (this.disabledDatesValue.length) options.disableDates = this.disabledDatesValue
this.picker = new Calendar(this.fieldTarget, options)
this.picker.init()
this.handleManualInput = () => {
const value = this.fieldTarget.value.trim()
if (!value) {
this.hiddenFieldTarget.value = ''
this.picker.set({ selectedDates: [] }, { dates: true })
} else {
const match = value.match(/^(\d{1,2})\.(\d{1,2})\.(\d{4})$/)
if (match) {
const [, day, month, year] = match
const iso = `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}`
this.hiddenFieldTarget.value = iso
this.picker.set({ selectedDates: [iso] }, { dates: true })
}
}
this.element.dispatchEvent(new CustomEvent('datepicker:closed'))
}
this.fieldTarget.addEventListener('change', this.handleManualInput)
}
disconnect() {
this.fieldTarget.removeEventListener('change', this.handleManualInput)
this.picker.destroy()
}
}