diff --git a/core/lib/Drupal/Core/Form/FormHelper.php b/core/lib/Drupal/Core/Form/FormHelper.php index 8ac7266a164..08e2035d259 100644 --- a/core/lib/Drupal/Core/Form/FormHelper.php +++ b/core/lib/Drupal/Core/Form/FormHelper.php @@ -204,11 +204,11 @@ class FormHelper { */ public static function processStates(array &$elements) { $elements['#attached']['library'][] = 'core/drupal.states'; - // Elements of '#type' => 'item' are not actual form input elements, but we - // still want to be able to show/hide them. Since there's no actual HTML - // input element available, setting #attributes does not make sense, but a - // wrapper is available, so setting #wrapper_attributes makes it work. - $key = ($elements['#type'] == 'item') ? '#wrapper_attributes' : '#attributes'; + // Elements that are actual form input elements, use '#attributes'. + // In cases like 'item' that are not actual form input elements or + // those like 'password_confirm' that have child elements, + // use #wrapper_attributes. + $key = (($elements['#markup'] ?? FALSE) === '' && ($elements['#input'] ?? FALSE) === TRUE) ? '#wrapper_attributes' : '#attributes'; $elements[$key]['data-drupal-states'] = Json::encode($elements['#states']); } diff --git a/core/modules/system/tests/modules/form_test/src/Form/JavascriptStatesForm.php b/core/modules/system/tests/modules/form_test/src/Form/JavascriptStatesForm.php index 9da19f41765..fe0a438e9e4 100644 --- a/core/modules/system/tests/modules/form_test/src/Form/JavascriptStatesForm.php +++ b/core/modules/system/tests/modules/form_test/src/Form/JavascriptStatesForm.php @@ -730,6 +730,15 @@ class JavascriptStatesForm extends FormBase { '#title' => 'Enable textarea', ]; + $form['password_confirm'] = [ + '#title' => $this->t('Enter password'), + '#type' => 'password_confirm', + '#states' => [ + 'visible' => [ + ':input[name="checkbox_trigger"]' => ['checked' => FALSE], + ], + ], + ]; $form['test_select_visible_dependence']['select_visible_1'] = [ '#type' => 'select', '#title' => 'Select visible 1', diff --git a/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php index 179886e8b90..50dc03c150d 100644 --- a/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php +++ b/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php @@ -187,6 +187,8 @@ class JavascriptStatesTest extends WebDriverTestBase { $this->assertFalse($radios_some_disabled_value2->hasAttribute('disabled')); // Check if the link is visible. $this->assertTrue($link->isVisible()); + // Check enter password is visible. + $this->assertSession()->pageTextContains('Enter password'); // Change state: check the checkbox. $trigger->check(); @@ -228,6 +230,8 @@ class JavascriptStatesTest extends WebDriverTestBase { $this->assertFalse($radios_some_disabled_value2->hasAttribute('disabled')); // The link shouldn't be visible. $this->assertFalse($link->isVisible()); + // Check enter password is not visible. + $this->assertSession()->pageTextNotContains('Enter password'); // Change state: uncheck the checkbox. $trigger->uncheck(); @@ -263,6 +267,8 @@ class JavascriptStatesTest extends WebDriverTestBase { $this->assertFalse($radios_some_disabled_value2->hasAttribute('disabled')); // Check if the link is turned back to visible state. $this->assertTrue($link->isVisible()); + // Check enter password is visible. + $this->assertSession()->pageTextContains('Enter password'); } /** diff --git a/core/tests/Drupal/Tests/Core/Form/FormHelperTest.php b/core/tests/Drupal/Tests/Core/Form/FormHelperTest.php index 2da73b861e1..7c1e6beca2e 100644 --- a/core/tests/Drupal/Tests/Core/Form/FormHelperTest.php +++ b/core/tests/Drupal/Tests/Core/Form/FormHelperTest.php @@ -120,6 +120,8 @@ class FormHelperTest extends UnitTestCase { ':input[name="foo"]' => ['value' => 'bar'], ], ], + '#markup' => '', + '#input' => TRUE, ], '#wrapper_attributes', ],