wagtail / wagtail

A Django content management system focused on flexibility and user experience
https://wagtail.org
BSD 3-Clause "New" or "Revised" License
18.01k stars 3.8k forks source link

Replace date & date time picker widget with native browser date pickers #8056

Open thibaudcolas opened 2 years ago

thibaudcolas commented 2 years ago

Is your proposal related to a problem?

There are a lot of issues with Wagtail’s existing date / datetime picker implementation. This is a high-level issue to formalise our intention to replace it with a new implementation that should address some or all of those issues.

Issues under consideration:

Describe the solution you'd like

We’ll be selecting a UI widget for the calendar / time picker element as part of #7980. We’ll then have to integrate this well with existing Wagtail & Django APIs for date & time formats, and finally remove the existing implementation based on jQuery Datetimepicker, replacing it with the new one.

Describe alternatives you've considered

Additional context

Copying research from @allcaps shared on Slack:

Some notes about input formats, datepickers and internationalisation.

Locale aware input in forms\ When formatting is enabled, Django can use localized formats when parsing dates, times and numbers in forms. That means it tries different formats for different locales when guessing the format used by the user when inputting data on forms.

https://docs.djangoproject.com/en/4.0/topics/i18n/formatting/#locale-aware-input-in-forms

DATE_INPUT_FORMATS\ When USE_L10N is True, the locale-dictated format has higher precedence and will be applied instead.

https://docs.djangoproject.com/en/4.0/ref/settings/#std:setting-DATE_INPUT_FORMATSThese are the Dutch formats: https://github.com/django/django/blob/7119f40c9881666b6f9b5cf7df09ee1d21cc8344/django/conf/locale/nl/formats.py\ According to this test, Dutch has some special time formatting rules (you may use a . as separator).These Wagtail settings kill the Django fine-grained date(time) input handling.\ https://docs.wagtail.org/en/stable/reference/settings.html?highlight=WAGTAIL_DATE#wagtail-date-format-wagtail-datetime-format-wagtail-time-formatTo make things worse, Django allows custom format files...\ https://docs.djangoproject.com/en/4.0/topics/i18n/formatting/#creating-custom-format-filesI think, Wagtail date(time) inputs should follow Django: use Django to validate and convert the input string to date(time) objects. This allows the user to enter multiple formats, as long as it is an acceptable format for their locale. Django will convert any input format to date(time), if it can. Unfortunately this is a backend process. A JS datepicker should be aware of the Django current locale and use the correct display format and a preferred input format for the active locale. Django has JavaScriptCatalog for that...

The JavaScriptCatalog view\ A view that produces a JavaScript code library with functions that mimic the gettext interface, plus an array of translation strings.

https://docs.djangoproject.com/en/4.0/topics/i18n/translation/#module-django.views.i18n

get_format\ The get_format function has access to the configured i18n formatting settings and can retrieve the format string for a given setting name:

document.write(get_format('DATE_FORMAT'));

https://docs.djangoproject.com/en/4.0/topics/i18n/translation/#get-format The SHORT_DATE_FORMAT , SHORT_DATETIME_FORMAT , and TIME_FORMAT  seem logical formats to use in JS picker enhanced inputs. But then we need to be sure that the values are also accepted by DATE_INPUT_FORMATS , DATETIME_INPUT_FORMATS and TIME_INPUT_FORMATS. I'm not sure if that is guaranteed.Maybe it is better to format by the first value from DATE_INPUT_FORMATS , DATETIME_INPUT_FORMATS and TIME_INPUT_FORMATS ? I've got to investigate.An additional challenging scenario: If a user manually enters a date in an input, and opens the date picker, we expect the picker to highlight correct date. Again, the picker needs to understand the current locale formats (multiple). I'd suggest to create a simple Django view to accept a sting and return the iso formatted date.

lb- commented 2 years ago

Interesting twitter thread on using native browser date pickers.

https://mobile.twitter.com/reinink/status/1507811705945997323

hallpower commented 2 years ago

As this is being actively researched, I would like to add feature requests for the datepicker:

These options look interesting:

Above can be configured to only allow single choice as well.

thibaudcolas commented 2 years ago

@hallpower thank you for the suggestions, could you provide more information about the use cases for this? We’ve already selected a new widget as part of #7980, I don’t think we’d reconsider that decision based on features Wagtail doesn’t already support, but it’s worth keeping in mind.

lb- commented 2 years ago

Saw this the other day and it seems that Adobe Spectrum React has a well thought out solution to datepickers that has recently had an overhaul.

https://react-spectrum.adobe.com/blog/date-and-time-pickers-for-all.html

Note that this is React so we would need to think carefully about how this integrates with existing HTML

But - again - it may be better to just keep with the decision made here about adoption of native browser date pickers.

https://github.com/wagtail/wagtail/issues/7980#issuecomment-1059302980

hazho commented 2 years ago

Browsers' built-in components like the date, time and date-time pickers (among others) are well fabricated to fulfill these goals, almost all browser engines are taking care of all needed features.. and if there is a certain test that failed, we can rais and issue on their repos..!

lb- commented 1 year ago

Some useful links based on my feedback on https://github.com/wagtail/wagtail/issues/9311

hazho commented 1 year ago

For your info, I've replaced the Date and DateTime widgets of wagtail in my projects to native widgets, looks pretty well (input type="datetime-local")

Screenshot (112) Screenshot (113) the screenshot is for 1- Chromium-Edge browser 2- Mozilla Firefox respectively (both in dark mode browsing)

lb- commented 1 year ago

Yeah, I still think the native inputs are the way to go personally, just as long as we are reviewing other viewpoints.

I think we can add some default data attributes to these so that with the new RFC78 (Stimulus) approach it would be reasonably easy to add back in any kind of JS widget you wanted.

lb- commented 1 year ago

Added this as a likely scope item for the Stimulus RFC 78 project.

lb- commented 1 year ago

I have renamed this issue to align with the current plan as per discussions with @laymonage / @thibaudcolas .

See https://github.com/wagtail/wagtail/issues/10261#issuecomment-1670990916_

Closing #10260 as no longer required.

lb- commented 10 months ago

Another reason to move away from the current jQuery date picker solution is that it introduces three known, medium, security risks.

https://github.com/wagtail/wagtail/security/code-scanning/1 https://github.com/wagtail/wagtail/security/code-scanning/11 https://github.com/wagtail/wagtail/security/code-scanning/10

lb- commented 7 months ago

https://a11ysupport.io/tests/tech__html__input__input-datetime-local

Still not a great picture for Safari VoiceOver and Dragon (datetime-local). However, it's likely overall a better position than our current JS widgets.

With Safari 15 our oldest supported version as of Wagtail 6.0 we are good to go on the native browser date pickers I think.

lb- commented 7 months ago

Looks like there is an investigation into native date pickers in Django also.

https://github.com/django/django/pull/15806 https://code.djangoproject.com/ticket/29822

Including constraints such as i18n and accessibility.

As per convo with @laymonage & @thibaudcolas today - we will likely want to hold on this work until there is a bit more traction/direction on the Django side.