Skip to content

Commit

Permalink
assets/js: make new flatpickr language aware and fix some small issues
Browse files Browse the repository at this point in the history
- selecting a start date in a later month than the end date wouldn't
  move the end date picker to the new month
- remove the possibility to select a start date past the current end
  date
  • Loading branch information
goapunk authored and m4ra committed Nov 18, 2024
1 parent 1dadf14 commit ce91244
Showing 1 changed file with 61 additions and 46 deletions.
107 changes: 61 additions & 46 deletions adhocracy-plus/assets/js/init-picker.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,34 @@
import django from 'django'
import flatpickr from 'flatpickr'
import { German } from 'flatpickr/dist/l10n/de.js'
import { Russian } from 'flatpickr/dist/l10n/ru.js'
import { Dutch } from 'flatpickr/dist/l10n/nl.js'
import English from 'flatpickr/dist/l10n/default.js'

function link (f0, f1) {
const date = f0.selectedDates[0]
if (date) {
// if p0 has a date set that date as minDate for p1
f1.set('minDate', f0.formatDate(date, f0.config.dateFormat))
// Helper to link start and end date pickers
function linkPair (startPicker, endPicker) {
const selectedDate = startPicker.selectedDates[0]
if (selectedDate) {
endPicker.set(
'minDate',
startPicker.formatDate(selectedDate, startPicker.config.dateFormat)
)
}
f0.config.onChange.push((selectedDates, dateStr) => {
// if date of p0 is changed adapt minDate for p1
f1.set('minDate', dateStr)
startPicker.config.onChange.push((selectedDates, dateStr) => {
if (selectedDates[0] > endPicker.selectedDates[0]) endPicker.clear()
endPicker.set('minDate', dateStr)
})

endPicker.config.onChange.push((selectedDates, dateStr) => {
if (selectedDates[0] < startPicker.selectedDates[0]) startPicker.clear()
startPicker.set('maxDate', dateStr)
})
}

function linkDatePickers (flatpickrs) {
// normal flatpickers
const idStart = 'id_start_date_date'
const idEnd = 'id_end_date_date'
// (multi-)phase flatpickrs
const phaseIds = [
// Initializes linked date pickers for start and end date fields
function linkDatePickers (flatpickrsMap) {
const singlePhaseIds = ['id_start_date_date', 'id_end_date_date']
const multiPhaseIds = [
'id_phase_set-0-start_date_date',
'id_phase_set-0-end_date_date',
'id_phase_set-1-start_date_date',
Expand All @@ -27,50 +37,55 @@ function linkDatePickers (flatpickrs) {
'id_phase_set-2-end_date_date'
]

// link non-phase datepickers if exist
const fStart = flatpickrs.get(idStart)
const fEnd = flatpickrs.get(idEnd)
if (fStart && fEnd) {
link(fStart, fEnd)
}
// Link single-phase pickers
const startPicker = flatpickrsMap.get(singlePhaseIds[0])
const endPicker = flatpickrsMap.get(singlePhaseIds[1])
if (startPicker && endPicker) linkPair(startPicker, endPicker)

// link phase datepickers if exist
for (let i = 0; i < phaseIds.length - 1; i++) {
if (flatpickrs.length <= i) {
return
}
const p0 = flatpickrs.get(phaseIds[i])
const p1 = flatpickrs.get(phaseIds[i + 1])
if (p0 && p1) {
link(p0, p1)
}
// Link multi-phase pickers in pairs
for (let i = 0; i < multiPhaseIds.length - 1; i += 2) {
const phaseStartPicker = flatpickrsMap.get(multiPhaseIds[i])
const phaseEndPicker = flatpickrsMap.get(multiPhaseIds[i + 1])
if (phaseStartPicker && phaseEndPicker) { linkPair(phaseStartPicker, phaseEndPicker) }
}
}

// Returns the appropriate language object based on the document language
function getLanguage () {
const languages = { de: German, nl: Dutch, ru: Russian }
return languages[document.documentElement.lang] || English
}

// Initializes all date and time pickers on the page
function initDatePicker () {
const datepickers = document.querySelectorAll('.datepicker')
const format = django.get_format('DATE_INPUT_FORMATS')[0].replaceAll('%', '')
const flatpickrs = new Map()
datepickers.forEach((e) => {
e.classList.add('form-control')
const f = flatpickr(e, { dateFormat: format })
flatpickrs.set(e.id, f)
})
const lang = getLanguage()
const dateFormat = django
.get_format('DATE_INPUT_FORMATS')[0]
.replaceAll('%', '')
const flatpickrsMap = new Map()

linkDatePickers(flatpickrs)
// Initialize date pickers
document.querySelectorAll('.datepicker').forEach((element) => {
element.classList.add('form-control')
const datePicker = flatpickr(element, { dateFormat, locale: lang })
flatpickrsMap.set(element.id, datePicker)
})

const timepickers = document.querySelectorAll('.timepicker')
// Link date pickers if needed
linkDatePickers(flatpickrsMap)

timepickers.forEach((e) => {
const f = flatpickr(e, {
defaultHour: e.id.endsWith('start_date_time') ? '00' : '23',
defaultMinute: e.id.endsWith('start_date_time') ? '00' : '59',
// Initialize time pickers
document.querySelectorAll('.timepicker').forEach((element) => {
const timePicker = flatpickr(element, {
defaultHour: element.id.endsWith('start_date_time') ? '00' : '23',
defaultMinute: element.id.endsWith('start_date_time') ? '00' : '59',
dateFormat: 'H:i',
enableTime: true,
noCalendar: true,
time_24hr: true
time_24hr: true,
locale: lang
})
flatpickrs.set(e.id, f)
flatpickrsMap.set(element.id, timePicker)
})
}

Expand Down

0 comments on commit ce91244

Please sign in to comment.