diff --git a/adhocracy-plus/assets/js/init-picker.js b/adhocracy-plus/assets/js/init-picker.js index f095f350d..652d8fbe1 100644 --- a/adhocracy-plus/assets/js/init-picker.js +++ b/adhocracy-plus/assets/js/init-picker.js @@ -1,15 +1,77 @@ -const $ = require('jquery') -const datePickerController = require('datepicker') -const django = require('django') +import django from 'django' +import flatpickr from 'flatpickr' -$(function () { - const $inputs = $('.datepicker') +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)) + } + f0.config.onChange.push((selectedDates, dateStr) => { + // if date of p0 is changed adapt minDate for p1 + f1.set('minDate', dateStr) + }) +} + +function linkDatePickers (flatpickrs) { + // normal flatpickers + const idStart = 'id_start_date_date' + const idEnd = 'id_end_date_date' + // (multi-)phase flatpickrs + const phaseIds = [ + 'id_phase_set-0-start_date_date', + 'id_phase_set-0-end_date_date', + 'id_phase_set-1-start_date_date', + 'id_phase_set-1-end_date_date', + 'id_phase_set-2-start_date_date', + '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 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) + } + } +} - $inputs.addClass('form-control') +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) + }) + + linkDatePickers(flatpickrs) - $inputs.each(function (i, e) { - const initObject = { formElements: {} } - initObject.formElements[e.id] = django.get_format('DATE_INPUT_FORMATS')[0] - datePickerController.createDatePicker(initObject) + const timepickers = document.querySelectorAll('.timepicker') + + 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', + dateFormat: 'H:i', + enableTime: true, + noCalendar: true, + time_24hr: true + }) + flatpickrs.set(e.id, f) }) -}) +} + +document.addEventListener('DOMContentLoaded', initDatePicker, false) diff --git a/adhocracy-plus/assets/scss/components/_datepicker.scss b/adhocracy-plus/assets/scss/components/_datepicker.scss index 28e845f19..5ca8397d9 100644 --- a/adhocracy-plus/assets/scss/components/_datepicker.scss +++ b/adhocracy-plus/assets/scss/components/_datepicker.scss @@ -2,111 +2,10 @@ @include clearfix; } -.datepicker { - @extend .input-group__input; - - &::placeholder { - opacity: 50%; - } -} - -// stylelint-disable selector-max-specificity -// need to override the default styling -.date-picker-control:link { - background-image: none !important; - min-width: 3em; - z-index: 0; - - @extend .input-group__after; - @extend .btn; - @extend .btn--light; - - span:first-child { - display: inline; - - &:before { - font-family: "Font Awesome 5 Free", sans-serif; - font-weight: 300; // to use the light version (formerly calendar-o) - content: "\f133"; // calendar - } - } - - &:focus { - outline: 2px solid Highlight !important; - outline: 5px auto -webkit-focus-ring-color !important; - } - - &:focus, - &:hover { - span:first-child:before { - content: "\f073"; // calendar-alt - } - - span { - box-shadow: none !important; - animation: none !important; - } +.flatpickr-calendar { + // overwrite style from _form.scss + select { + display: unset; } } -// stylelint-enable -.date-picker { - font-family: $font-family-base; - - // overwrite gradient - table, - td { - background: $body-bg; - } - - .date-picker-unused { - background: $bg-light; - } - - .date-picker-highlight { - color: $text-color; - } - - .prev-but, - .next-but { - font-size: 0; - - &:before { - font-family: "Font Awesome 5 Free", sans-serif; - font-weight: 900; - font-size: $font-size-lg; - vertical-align: bottom; - } - } - - .prev-but:before { - content: "\f104"; // angle-left - } - - .prev-year:before { - content: "\f100"; // angle-double-left - } - - .next-but:before { - content: "\f105"; // angle-right - } - - .next-year:before { - content: "\f101"; // angle-double-right - } - - .date-picker-hover { - border: none; - - background: $brand-primary; - color: contrast-color($brand-primary); - box-shadow: none; - text-shadow: none; - } -} - -// The original styling causes a huge focus box in firefox -.fd-screen-reader.fd-screen-reader { - @include visually-hidden; - left: 0; -} diff --git a/changelog/8302.md b/changelog/8302.md new file mode 100644 index 000000000..bab7ec2d4 --- /dev/null +++ b/changelog/8302.md @@ -0,0 +1,5 @@ +### Changed + +- replaced the old datepicker with flatpickr +- make flatpickr instances aware of each other (e.g. for start and end phase of + a module, you can't choose an end date which is earlier than the start date) \ No newline at end of file diff --git a/package.json b/package.json index 144724522..8cc1d8030 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "datepicker": "git+https://github.com/liqd/datePicker.git", "dsgvo-video-embed": "git+https://github.com/liqd/dsgvo-video-embed.git", "file-saver": "2.0.5", + "flatpickr": "^4.6.13", "glob": "10.4.1", "immutability-helper": "3.1.1", "jquery": "3.7.1", diff --git a/webpack.common.js b/webpack.common.js index 75c786988..df9112079 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -34,7 +34,7 @@ module.exports = { datepicker: { import: [ './adhocracy-plus/assets/js/init-picker.js', - 'datepicker/css/datepicker.min.css' + './node_modules/flatpickr/dist/flatpickr.css' ], dependOn: 'adhocracy4' },