diff --git a/core/includes/theme.inc b/core/includes/theme.inc index 2aef832c..d19c0ff 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -481,6 +481,10 @@ function template_preprocess_datetime_wrapper(&$variables) { $variables['title'] = $element['#title']; } + if (!empty($element['#errors'])) { + $variables['errors'] = $element['#errors']; + } + if (!empty($element['#description'])) { $variables['description'] = $element['#description']; } diff --git a/core/lib/Drupal/Core/Datetime/Element/Datelist.php b/core/lib/Drupal/Core/Datetime/Element/Datelist.php index c330a4f..f938a7e 100644 --- a/core/lib/Drupal/Core/Datetime/Element/Datelist.php +++ b/core/lib/Drupal/Core/Datetime/Element/Datelist.php @@ -265,6 +265,7 @@ public static function processDatelist(&$element, FormStateInterface $form_state '#attributes' => $element['#attributes'], '#options' => $options, '#required' => $element['#required'], + '#error_use_parent' => TRUE, ); } diff --git a/core/lib/Drupal/Core/Datetime/Element/Datetime.php b/core/lib/Drupal/Core/Datetime/Element/Datetime.php index d298e21..8af82f1 100644 --- a/core/lib/Drupal/Core/Datetime/Element/Datetime.php +++ b/core/lib/Drupal/Core/Datetime/Element/Datetime.php @@ -267,6 +267,7 @@ public static function processDatetime(&$element, FormStateInterface $form_state '#attributes' => $element['#attributes'] + $extra_attributes, '#required' => $element['#required'], '#size' => max(12, strlen($element['#value']['date'])), + '#error_use_parent' => TRUE, ); // Allows custom callbacks to alter the element. @@ -298,6 +299,7 @@ public static function processDatetime(&$element, FormStateInterface $form_state '#attributes' => $element['#attributes'] + $extra_attributes, '#required' => $element['#required'], '#size' => 12, + '#error_use_parent' => TRUE, ); // Allows custom callbacks to alter the element. diff --git a/core/lib/Drupal/Core/Form/FormErrorHandler.php b/core/lib/Drupal/Core/Form/FormErrorHandler.php index 75ef779..d8bf7d0 100644 --- a/core/lib/Drupal/Core/Form/FormErrorHandler.php +++ b/core/lib/Drupal/Core/Form/FormErrorHandler.php @@ -24,7 +24,7 @@ class FormErrorHandler implements FormErrorHandlerInterface { use LinkGeneratorTrait; /** - * Associated array of elements with errors which need to be linked to from + * Array of elements with errors which need to be linked to from * the error message * * @var array[] @@ -52,7 +52,7 @@ public function handleFormErrors(array &$form, FormStateInterface $form_state) { $this->setElementErrorsFromFormState($form, $form_state); // Display error messages for each element. - $this->displayErrorMessages($form_state, $this->errorLinkElements); + $this->displayErrorMessages($form_state); // Reset the list of elements with errors $this->errorLinkElements = []; @@ -66,14 +66,14 @@ public function handleFormErrors(array &$form, FormStateInterface $form_state) { * @param \Drupal\Core\Form\FormStateInterface $form_state * The current state of the form. * @param array[] $error_elements - * An associative array of elements with errors + * An array of elements with errors */ - protected function displayErrorMessages(FormStateInterface $form_state, array $error_elements = []) { + protected function displayErrorMessages(FormStateInterface $form_state) { $error_links = []; $errors = $form_state->getErrors(); // Create error links - foreach ($error_elements as $form_element) { + foreach ($this->errorLinkElements as $form_element) { $title = FormElementHelper::getElementTitle($form_element); // Only show links to erroneous elements that are visible @@ -123,7 +123,7 @@ protected function displayErrorMessages(FormStateInterface $form_state, array $e * specific element. The most common usage of this is a #pre_render callback. * * @param array $elements - * An associative array containing the structure of a form element. + * An array containing the structure of a form element. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current state of the form. */ @@ -137,10 +137,8 @@ protected function setElementErrorsFromFormState(array &$elements, FormStateInte // Store the errors for this element on the element directly and // keep a list of elements with errors - // @todo get the element name differently when $elements['#name'] is not set - // like from #parents or the form structure - if (($elements['#errors'] = $form_state->getError($elements)) && !empty($elements['#name'])) { - $this->errorLinkElements[$elements['#name']] = $elements; + if (($elements['#errors'] = $form_state->getError($elements))) { + $this->errorLinkElements[] = $elements; }; } diff --git a/core/modules/file/src/Element/ManagedFile.php b/core/modules/file/src/Element/ManagedFile.php index 40d0c31..4c70ef1 100644 --- a/core/modules/file/src/Element/ManagedFile.php +++ b/core/modules/file/src/Element/ManagedFile.php @@ -328,7 +328,7 @@ public static function validateManagedFile(&$element, FormStateInterface $form_s // Check required property based on the FID. if ($element['#required'] && empty($element['fids']['#value']) && !in_array($clicked_button, ['upload_button', 'remove_button'])) { - $form_state->setError($element['upload'], t('!name field is required.', ['!name' => $element['#title']])); + $form_state->setError($element, t('!name is required.', ['!name' => $element['#title']])); } // Consolidate the array value of this field to array of FIDs. diff --git a/core/modules/shortcut/src/Tests/ShortcutSetsTest.php b/core/modules/shortcut/src/Tests/ShortcutSetsTest.php index 476a393..3d2c5cf 100644 --- a/core/modules/shortcut/src/Tests/ShortcutSetsTest.php +++ b/core/modules/shortcut/src/Tests/ShortcutSetsTest.php @@ -134,7 +134,7 @@ function testShortcutSetSwitchNoSetName() { $edit = array('set' => 'new'); $this->drupalPostForm('user/' . $this->adminUser->id() . '/shortcuts', $edit, t('Change set')); $this->assertRaw(\Drupal::translation()->formatPlural(1, '1 error has been found: !errors', '@count errors have been found: !errors', [ - '!errors' => SafeMarkup::set('New set') + '!errors' => SafeMarkup::set('Label') ])); $current_set = shortcut_current_displayed_set($this->adminUser); $this->assertEqual($current_set->id(), $this->set->id(), 'Attempting to switch to a new shortcut set without providing a set name does not succeed.'); diff --git a/core/tests/Drupal/Tests/Core/Form/FormErrorHandlerTest.php b/core/tests/Drupal/Tests/Core/Form/FormErrorHandlerTest.php index d785e27..4b14df0 100644 --- a/core/tests/Drupal/Tests/Core/Form/FormErrorHandlerTest.php +++ b/core/tests/Drupal/Tests/Core/Form/FormErrorHandlerTest.php @@ -44,14 +44,12 @@ public function testDisplayErrorMessages() { '#type' => 'textfield', '#title' => 'Test 1', '#parents' => ['test1'], - '#name' => 'test1', '#id' => 'edit-test1', ]; $form['test2'] = [ '#type' => 'textfield', '#title' => 'Test 2', '#parents' => ['test2'], - '#name' => 'test2', '#id' => 'edit-test2', ]; $form['fieldset'] = [ @@ -60,7 +58,6 @@ public function testDisplayErrorMessages() { '#type' => 'textfield', '#title' => 'Test 3', '#parents' => ['fieldset', 'test3'], - '#name' => 'test3', '#id' => 'edit-test3', ), ]; @@ -90,7 +87,6 @@ public function testSetElementErrorsFromFormState() { '#type' => 'textfield', '#title' => 'Test', '#parents' => ['test'], - '#name' => 'test', '#id' => 'edit-test', ]; $form_state = new FormState(); diff --git a/core/themes/classy/templates/form/datetime-wrapper.html.twig b/core/themes/classy/templates/form/datetime-wrapper.html.twig index 399dea2..56da173 100644 --- a/core/themes/classy/templates/form/datetime-wrapper.html.twig +++ b/core/themes/classy/templates/form/datetime-wrapper.html.twig @@ -23,6 +23,11 @@