Date field doesn't allow attributes

Created on 21 February 2017, almost 8 years ago
Updated 11 March 2024, 10 months ago

My custom form date field is set up as follows:

$form['right']['validfrom'] = array(
      '#type' => 'date',
      '#title' => $this->t('Start date'),
      '#description' => $this->t('The beginning date.'),
      '#attributes' => array('class' => array('lala')),
    );

And the error thrown is the following:

Notice: Undefined index: type in Drupal\Core\Render\Element\Date::processDate() (line 63 of /var/www/website/public_html/core/lib/Drupal/Core/Render/Element/Date.php)
#0 /var/www/website/public_html/core/includes/bootstrap.inc(548): _drupal_error_handler_real(8, 'Undefined index...', '/var/www/website...', 63, Array)
#1 /var/www/website/public_html/core/lib/Drupal/Core/Render/Element/Date.php(63): _drupal_error_handler(8, 'Undefined index...', '/var/www/website...', 63, Array)
#2 [internal function]: Drupal\Core\Render\Element\Date::processDate(Array, Object(Drupal\Core\Form\FormState), Array)
#3 /var/www/website/public_html/core/lib/Drupal/Core/Form/FormBuilder.php(981): call_user_func_array(Array, Array)
#4 /var/www/website/public_html/core/lib/Drupal/Core/Form/FormBuilder.php(1044): Drupal\Core\Form\FormBuilder->doBuildForm('vehicle_main_fo...', Array, Object(Drupal\Core\Form\FormState))
#5 /var/www/website/public_html/core/lib/Drupal/Core/Form/FormBuilder.php(1044): Drupal\Core\Form\FormBuilder->doBuildForm('vehicle_main_fo...', Array, Object(Drupal\Core\Form\FormState))
#6 /var/www/website/public_html/core/lib/Drupal/Core/Form/FormBuilder.php(557): Drupal\Core\Form\FormBuilder->doBuildForm('vehicle_main_fo...', Array, Object(Drupal\Core\Form\FormState))
#7 /var/www/website/public_html/core/lib/Drupal/Core/Form/FormBuilder.php(314): Drupal\Core\Form\FormBuilder->processForm('vehicle_main_fo...', Array, Object(Drupal\Core\Form\FormState))
#8 /var/www/website/public_html/core/lib/Drupal/Core/Controller/FormController.php(74): Drupal\Core\Form\FormBuilder->buildForm('vehicle_main_fo...', Object(Drupal\Core\Form\FormState))
#9 [internal function]: Drupal\Core\Controller\FormController->getContentResult(Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\RouteMatch))
#10 /var/www/website/public_html/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array)
#11 /var/www/website/public_html/core/lib/Drupal/Core/Render/Renderer.php(574): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#12 /var/www/website/public_html/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#13 /var/www/website/public_html/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array)
#14 [internal function]: Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#15 /var/www/website/public_html/vendor/symfony/http-kernel/HttpKernel.php(144): call_user_func_array(Object(Closure), Array)
#16 /var/www/website/public_html/vendor/symfony/http-kernel/HttpKernel.php(64): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#17 /var/www/website/public_html/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#18 /var/www/website/public_html/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#19 /var/www/website/public_html/core/modules/page_cache/src/StackMiddleware/PageCache.php(99): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#20 /var/www/website/public_html/core/modules/page_cache/src/StackMiddleware/PageCache.php(78): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#21 /var/www/website/public_html/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#22 /var/www/website/public_html/modules/devel/webprofiler/src/StackMiddleware/WebprofilerMiddleware.php(38): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#23 /var/www/website/public_html/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(50): Drupal\webprofiler\StackMiddleware\WebprofilerMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#24 /var/www/website/public_html/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#25 /var/www/website/public_html/core/lib/Drupal/Core/DrupalKernel.php(652): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#26 /var/www/website/public_html/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#27 {main}.

I've tested that this happens with whatever attribute you try to set and works perfectly when no attribute set.

EDIT adding more debugging info:

The code in /core/lib/Drupal/Core/Render/Element/Date for the relevant parts is:

class Date extends FormElement {

  /**
   * {@inheritdoc}
   */
  public function getInfo() {
    $class = get_class($this);
    return [
      '#input' => TRUE,
      '#theme' => 'input__date',
      '#process' => [[$class, 'processDate']],
      '#pre_render' => [[$class, 'preRenderDate']],
      '#theme_wrappers' => ['form_element'],
      '#attributes' => ['type' => 'date'],
      '#date_date_format' => 'Y-m-d',
    ];
  }

  /**
   * Processes a date form element.
   *
   * @param array $element
   *   The form element to process. Properties used:
   *   - #attributes: An associative array containing:
   *     - type: The type of date field rendered.
   *   - #date_date_format: The date format used in PHP formats.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   * @param array $complete_form
   *   The complete form structure.
   *
   * @return array
   *   The processed element.
   */
  public static function processDate(&$element, FormStateInterface $form_state, &$complete_form) {
    // Attach JS support for the date field, if we can determine which date
    // format should be used.
    if ($element['#attributes']['type'] == 'date' && !empty($element['#date_date_format'])) {
      $element['#attached']['library'][] = 'core/drupal.date';
      $element['#attributes']['data-drupal-date-format'] = [$element['#date_date_format']];
    }
    return $element;
  }

The sequence the code is processed is:

  1. Creation of field in custom form code
  2. Date::getInfo()
  3. Date::processDate()
  4. Date::preRenderDate - not relevant here

So now if I dpm($element) in Date::processDate()

when there's no attributes set in my field the element seems to have the attributes returned from Date::getInfo() :

But when I set attributes from my own field declaration they seem to override the attributes all together:

All my other fields work fine with attributes just the date seems to be going crazy.

๐Ÿ› Bug report
Status

Needs work

Version

11.0 ๐Ÿ”ฅ

Component
Formย  โ†’

Last updated about 14 hours ago

Created by

๐Ÿ‡ช๐Ÿ‡ชEstonia Alluuu

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.

  • The Needs Review Queue Bot โ†’ tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

    Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.

    Consult the Drupal Contributor Guide โ†’ to find step-by-step guides for working with issues.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States alison

    #69 doesn't apply to Drupal 10 (10.0 or 10.1), because (as far as I can tell), processDate() isn't there anymore -- as of #3256549: Deprecate core/drupal.date asset library in 9.4.0 โ†’ .

    I can't tell if this issue is still needed for Drupal 10 (but with a rewrite), or if it can be closed (given that Drupal 9 EOL is coming up in less than a week)?? -- I poked around a bit, but I'm just not sure where to look.

  • ๐Ÿ‡ฎ๐Ÿ‡ณIndia AditiVB

    Aditi Saraf โ†’ made their first commit to this issueโ€™s fork.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium fernly

    This has been fixed in Drupal 10, as you can see here.
    This ticket can be closed soon.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States alison

    Fabulous, thank you @Fernly!

  • ๐Ÿ‡ง๐Ÿ‡ทBrazil charlliequadros

    I couldn't apply patch from #69 using version 10.2.1, therefore i'm attaching an updated version of the patch.

  • ๐Ÿ‡ซ๐Ÿ‡ทFrance duaelfr Montpellier, France

    I have no idea why it's happening but I'm facing the same issue with my simple date field in a facet widget.

        $form['date_start'] = [
          '#type' => 'date',
          '#title' => $this->t('From', [], ['context' => 'date_range_widget']),
          '#default_value' => $existingValues['min'] ?? NULL,
        ];
    

    I can only fix the issue by removing the type attribute added in both \Drupal\Core\Render\Element\Date::getInfo() and \Drupal\Core\Render\Element\Date::preRenderDate().
    Interestingly, this does not prevent the actual tag in the markup to have the appropriate type attribute.

Production build 0.71.5 2024