Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changed datepicker for flatpicker #2790

Merged
merged 1 commit into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 73 additions & 11 deletions adhocracy-plus/assets/js/init-picker.js
Original file line number Diff line number Diff line change
@@ -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++) {
hom3mad3 marked this conversation as resolved.
Show resolved Hide resolved
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 () {
Copy link
Contributor

@hom3mad3 hom3mad3 Oct 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest splitting into smaller, well-named chunks and then call them inside the function. It will make the code easier to read and maintain and we can keep the main initializer nice and clean.

Copy link
Contributor

@goapunk goapunk Oct 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if that's something @rjlanari wants to take over as the focus was more on django, what do you think @rjlanari ? Otherwise maybe you can work on that @hom3mad3 if you have an idea in mind? If we change it we should port it over to mb (or if both files are identical we could even consider moving it into a4)

const datepickers = document.querySelectorAll('.datepicker')
const format = django.get_format('DATE_INPUT_FORMATS')[0].replaceAll('%', '')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could add a fallback date format here const format = django.get_format ? django.get_format('DATE_INPUT_FORMATS')[0].replaceAll('%', '') : 'Y-m-d';

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)
109 changes: 4 additions & 105 deletions adhocracy-plus/assets/scss/components/_datepicker.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
5 changes: 5 additions & 0 deletions changelog/8302.md
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"dsgvo-video-embed": "git+https://github.com/liqd/dsgvo-video-embed.git",
"file-saver": "2.0.5",
"glob": "11.0.0",
"flatpickr": "4.6.13",
"immutability-helper": "3.1.1",
"jquery": "3.7.1",
"js-cookie": "3.0.5",
Expand Down
2 changes: 1 addition & 1 deletion webpack.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'
},
Expand Down