"Date and time" Form API element allows entry beyond min/max values

Created on 31 December 2016, over 7 years ago
Updated 8 January 2024, 6 months ago

Problem/Motivation

As originally reported in #2900251: "Date and time" Form API element allows to type 6 digit year component β†’ , The core date Form API element (and therefore, field widgets) allows values that don't match the min/max settings for the field.

This can lead to problems, such as users being able to enter more than 4 digits for the year. It should be limited to 4 digits.

Root cause

An empty "Date" field loads with no min/max year set.

\lib\Drupal\Core\Datetime\Element\Datetime::processDatetime() has this comment:

   * Optional properties include:
   *   - #date_year_range: A description of the range of years to allow, like
   *     '1900:2050', '-3:+3' or '2000:+3', where the first value describes the
   *     earliest year and the second the latest year in the range. A year
   *     in either position means that specific year. A +/- value describes a
   *     dynamic value that is that many years earlier or later than the current
   *     year at the time the form is displayed. Used in jQueryUI datepicker year
   *     range and HTML5 min/max date settings. Defaults to '1900:2050'.


When this element loads and is empty / doesn't have a defaul value this section of code is never hit:

      // Adds the HTML5 date attributes.
      if ($date instanceof DrupalDateTime && !$date->hasErrors()) {
        $html5_min = clone($date);
        $range = static::datetimeRangeYears($element['#date_year_range'], $date);
        $html5_min->setDate($range[0], 1, 1)->setTime(0, 0, 0);
        $html5_max = clone($date);
        $html5_max->setDate($range[1], 12, 31)->setTime(23, 59, 59);

        $extra_attributes += array(
          'min' => $html5_min->format($date_format, $format_settings),
          'max' => $html5_max->format($date_format, $format_settings),
        );
      }

Date fields that have a value may set min max year to unwanted values

When the value of a date is set either via the default value or a saved date then the max min is calculated and set. This defaults to 1900-2050 (hard coded). However if the field year is set to a time before 1900 or above 2050 then this date is used _forever_ as the max or min value of that field. For example:

I can enter 1776-07-04 as a date in an empty element, and then this year gets used as the min year on the element instead of the range defined on the element (which is by design per a comment in DateElementBase::datetimeRangeYears()), but then you cant edit the year to be less than this (E.g. 1775) ever again. Same goes if you set the date to 2060 you can't then set it to 2062 (And worse there is no error shown on Chrome for this situation, it just silently fails).

Proposed resolution

  • Add the date_range_yearsconfiguration setting to the field edit form
    • If there is no data in this fields storage default to the current settings for date_range_years (1900-2050)
    • If there is data in this fields storage default to blank (?) for backwards capacitity
    • Allow the date_range_years config setting to be modified, validated and saved for this field
    • Add a description to the date_range_years field that if the field is left blank it will not add max-min to field at all
    • Perhaps this ticket covers some of that work? https://www.drupal.org/project/drupal/issues/2836054 ✨ Allow configuring of datelist year range date_year_range via UI Needs work
  • The form element on the form display, If date_range_years is not empty should:
    • Use the date_range_years setting saved in the config.
    • Add the min/max elements even when the value on the element is empty.
  • Update code/docs to explain the new features when '#date_year_range' === NULL?
  • Show an error when the max value is exceeded (is this from the browser?)
  • Validate the date/range year submission from the widget [3269890]

Remaining tasks

  • Fix up patch of deprecation
  • Review
  • Commit

User interface changes

NA

API changes

NA

Data model changes

NA

πŸ› Bug report
Status

Needs work

Version

11.0 πŸ”₯

Component
DatetimeΒ  β†’

Last updated about 16 hours ago

Created by

πŸ‡ΊπŸ‡ΈUnited States mpdonadio Philadelphia/PA/USA (UTC-5)

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡ΊπŸ‡ΈUnited States mark_fullmer Tucson
  • πŸ‡ΊπŸ‡ΈUnited States mark_fullmer Tucson

    This could use an issue title update. What 'buggy' behavior is being fixed here?

    I've updated the title to capture the bugginess: "Date and time" Form API element allows entry beyond min/max values

  • Status changed to Needs work about 1 year ago
  • πŸ‡©πŸ‡ͺGermany FeyP

    This issue is being reviewed by the kind folks in Slack, #need-reveiw-queue. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge request β†’ as a guide.

    Looking at the proposed resolution in the issue summary, it seems that the patch only implements the "Add the min/max elements even when the value on the element is empty." part. All the rest is missing, which is a lot. So this is very far from ready, unfortunately.

    If this change breaks the functionality of the date field for working with dates outside the default range, then I think we also can't just rescope this issue and do the rest in a follow-up. We must at least ensure that people who use the field with existing data outside of the default range can still use the date field until the follow-up is implemented.

    The issue linked from the top of the issue summary mentions that it is annoying for editors when they accidentally enter a 6 digit year instead of entering a 4 digit year and then the first 2 digits of the next date component. I tested the patch in both current Firefox and Chromium on Linux and although min and max are now set to the default date range, I can still enter 6 digit years. Only when I then try to submit the form, instead of getting an error from Form API about the required date format, I now get a browser validation error (which will also enforce that the date is within the date range specified). I'm not sure how to fix this, maybe this would need some Javascript?

    I would also suggest to use an ordered list instead of an unordered list for the proposed resolution in the issue summary, as that will make it easier to refer to individual items in comments.

  • last update 11 months ago
    30,341 pass
  • last update 11 months ago
    29,457 pass
  • πŸ‡·πŸ‡ΊRussia Dimm

    https://www.drupal.org/project/datetime_more β†’
    The "Datetime More Widget" module allows the user to independently specify the minimum and maximum year 0001-9999.

Production build 0.69.0 2024