diff --git a/core/misc/states.js b/core/misc/states.js index 3109e1f1bdb0b02437c6c429cfdc3657e40dec53..6db3494cd7b4937c359ffee5630300068e62dd14 100644 --- a/core/misc/states.js +++ b/core/misc/states.js @@ -93,15 +93,16 @@ */ Drupal.behaviors.states = { attach(context, settings) { - const $states = $(context).find('[data-drupal-states]'); - const il = $states.length; + // Uses once to avoid duplicates if attach is called multiple times. + const elements = once('states', '[data-drupal-states]', context); + const il = elements.length; for (let i = 0; i < il; i++) { const config = JSON.parse( - $states[i].getAttribute('data-drupal-states'), + elements[i].getAttribute('data-drupal-states'), ); Object.keys(config || {}).forEach((state) => { new states.Dependent({ - element: $($states[i]), + element: $(elements[i]), state: states.State.sanitize(state), constraints: config[state], }); 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 0677df3bd06e3a2be32510d7208f670e6cba5ab7..9da19f417659a606077e47599cca464b6bec742a 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,30 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#title' => 'Enable textarea', ]; + $form['test_select_visible_dependence']['select_visible_1'] = [ + '#type' => 'select', + '#title' => 'Select visible 1', + '#options' => [0 => 0, 1 => 1], + '#default_value' => 0, + ]; + $form['test_select_visible_dependence']['select_visible_2'] = [ + '#type' => 'select', + '#title' => 'Select visible 2', + '#options' => [0 => 0, 1 => 1], + '#default_value' => 0, + ]; + $form['test_select_visible_dependence']['select_visible_3'] = [ + '#type' => 'select', + '#title' => 'Select should show when 0 and 1 are selected', + '#options' => [0 => 0, 1 => 1], + '#states' => [ + 'visible' => [ + ':input[name="select_visible_1"]' => ['value' => 0], + ':input[name="select_visible_2"]' => ['value' => 1], + ], + ], + ]; + return $form; } diff --git a/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php index b5c0d9178906e38fc19aa3f067d3c9d6ae4325f7..3fb9f8feac8716b1f7556799b7e7e8618e17ddd5 100644 --- a/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php +++ b/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php @@ -443,6 +443,15 @@ protected function doSelectTriggerTests() { $this->assertFalse($item_visible_value2->isVisible()); $this->assertTrue($textfield_visible_value3->isVisible()); $this->assertTrue($textfield_visible_value2_or_value3->isVisible()); + + $this->container->get('module_installer')->install(['big_pipe']); + $this->drupalGet('form-test/javascript-states-form'); + $select_visible_2 = $this->assertSession()->elementExists('css', 'select[name="select_visible_2"]'); + $select_visible_3 = $this->assertSession()->elementExists('css', 'select[name="select_visible_3"]'); + $this->assertFalse($select_visible_3->isVisible()); + + $select_visible_2->setValue('1'); + $this->assertTrue($select_visible_3->isVisible()); } /**