diff --git a/core/includes/theme.inc b/core/includes/theme.inc index f180cbd..781529d 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -1146,6 +1146,12 @@ function template_preprocess_container(&$variables) { $variables['children'] = $element['#children']; $variables['attributes'] = $element['#attributes']; + + // Display any error messages. + $variables['errors'] = NULL; + if (!empty($element['#errors']) && empty($element['#error_no_message'])) { + $variables['errors'] = $element['#errors']; + } } /** diff --git a/core/modules/system/src/Tests/Form/ElementTest.php b/core/modules/system/src/Tests/Form/ElementTest.php index 0ae2edc..d14658a 100644 --- a/core/modules/system/src/Tests/Form/ElementTest.php +++ b/core/modules/system/src/Tests/Form/ElementTest.php @@ -176,11 +176,18 @@ public function testFormAutocomplete() { } /** - * Tests form element error messages. + * Tests form details element error messages. */ - public function testFormElementErrors() { + public function testFormDetailsErrors() { $this->drupalPostForm('form_test/details-form', [], 'Submit'); $this->assertText('I am an error on the details element.'); } + /** + * Tests form container element error messages. + */ + public function testFormContainerErrors() { + $this->drupalPostForm('form_test/container-form', [], 'Submit'); + $this->assertText('I am an error on the container element.'); + } } diff --git a/core/modules/system/templates/container.html.twig b/core/modules/system/templates/container.html.twig index 6cb299b..02fe98c 100644 --- a/core/modules/system/templates/container.html.twig +++ b/core/modules/system/templates/container.html.twig @@ -12,6 +12,7 @@ * * Available variables: * - attributes: HTML attributes for the containing element. + * - errors: (optional) Any errors for this container element, may not be set. * - children: The rendered child elements of the container. * - has_parent: A flag to indicate that the container has one or more parent containers. @@ -27,4 +28,11 @@ has_parent ? 'form-wrapper', ] %} -{{ children }} + +{% if errors %} +
+ {{ errors }} +
+{% endif %} +{{ children }} + diff --git a/core/modules/system/tests/modules/form_test/form_test.routing.yml b/core/modules/system/tests/modules/form_test/form_test.routing.yml index 2250a0b..9a4bc06 100644 --- a/core/modules/system/tests/modules/form_test/form_test.routing.yml +++ b/core/modules/system/tests/modules/form_test/form_test.routing.yml @@ -417,6 +417,14 @@ form_test.details_form: requirements: _access: 'TRUE' +form_test.container_form: + path: '/form_test/container-form' + defaults: + _form: '\Drupal\form_test\Form\FormTestContainerForm' + _title: 'Form container form test' + requirements: + _access: 'TRUE' + form_test.description_display: path: '/form_test/form-descriptions' defaults: diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestContainerForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestContainerForm.php new file mode 100644 index 0000000..db0481f --- /dev/null +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestContainerForm.php @@ -0,0 +1,51 @@ + 'container', + '#attributes' => array( + 'class' => 'accommodation', + ), + ]; + $form['meta']['child'] = [ + '#type' => 'textfield', + '#title' => 'A textfield in a container', + ]; + $form['submit'] = ['#type' => 'submit', '#value' => 'Submit']; + return $form; + } + + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, FormStateInterface $form_state) { + $form_state->setErrorByName('meta', 'I am an error on the container element.'); + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + } + +} diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestDetailsForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestDetailsForm.php index 5949679..55fcbfd 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/FormTestDetailsForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestDetailsForm.php @@ -6,7 +6,7 @@ use Drupal\Core\Form\FormStateInterface; /** - * Builds a simple form to test the #group property on #type 'container'. + * Builds a simple form to test the #group property on #type 'details'. */ class FormTestDetailsForm extends FormBase { diff --git a/core/themes/classy/templates/form/container.html.twig b/core/themes/classy/templates/form/container.html.twig index 0da6c38..caafe73 100644 --- a/core/themes/classy/templates/form/container.html.twig +++ b/core/themes/classy/templates/form/container.html.twig @@ -12,6 +12,7 @@ * * Available variables: * - attributes: HTML attributes for the containing element. + * - errors: (optional) Any errors for this container element, may not be set. * - children: The rendered child elements of the container. * - has_parent: A flag to indicate that the container has one or more parent containers. @@ -25,4 +26,11 @@ has_parent ? 'form-wrapper', ] %} -{{ children }} + +{% if errors %} +
+ {{ errors }} +
+{% endif %} +{{ children }} + diff --git a/core/themes/stable/templates/form/container.html.twig b/core/themes/stable/templates/form/container.html.twig index 0da6c38..72646ce 100644 --- a/core/themes/stable/templates/form/container.html.twig +++ b/core/themes/stable/templates/form/container.html.twig @@ -25,4 +25,12 @@ has_parent ? 'form-wrapper', ] %} -{{ children }} + + {% if errors %} +
+ {{ errors }} +
+ {% endif %} + + {{ children }} +