Loading core/lib/Drupal/Core/Render/Element/Link.php +7 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Component\Utility\Html as HtmlUtility; use Drupal\Core\Form\FormHelper; use Drupal\Core\Render\BubbleableMetadata; use Drupal\Core\Render\Element; use Drupal\Core\Url as CoreUrl; Loading Loading @@ -57,6 +58,12 @@ public function getInfo() { * The passed-in element containing a rendered link in '#markup'. */ public static function preRenderLink($element) { // As the preRenderLink() method is executed before Renderer::doRender(), // call processStates() to make sure that states are added to link elements. if (!empty($element['#states'])) { FormHelper::processStates($element); } // By default, link options to pass to the link generator are normally set // in #options. $element += ['#options' => []]; Loading core/misc/states.js +8 −3 Original line number Diff line number Diff line Loading @@ -724,9 +724,14 @@ $document.on('state:visible', (e) => { if (e.trigger) { $(e.target) .closest('.js-form-item, .js-form-submit, .js-form-wrapper') .toggle(e.value); let $element = $(e.target).closest( '.js-form-item, .js-form-submit, .js-form-wrapper', ); // For links, update the state of itself instead of the wrapper. if (e.target.tagName === 'A') { $element = $(e.target); } $element.toggle(e.value); } }); Loading core/modules/system/tests/modules/form_test/src/Form/JavascriptStatesForm.php +13 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Url; /** * Builds a simple form to test states. Loading Loading @@ -544,6 +545,18 @@ public function buildForm(array $form, FormStateInterface $form_state) { ], ], ]; $form['link'] = [ '#type' => 'link', '#title' => 'Link states test', '#url' => Url::fromRoute('<front>'), '#states' => [ 'visible' => [ ':input[name="checkbox_trigger"]' => ['checked' => FALSE], ], ], ]; return $form; } Loading core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php +7 −0 Original line number Diff line number Diff line Loading @@ -102,6 +102,7 @@ protected function doCheckboxTriggerTests() { $this->assertNotEmpty($text_format_invisible_value); $text_format_invisible_format = $page->findField('text_format_invisible_when_checkbox_trigger_checked[format]'); $this->assertNotEmpty($text_format_invisible_format); $link = $page->findLink('Link states test'); $checkboxes_all_checked_element_value1 = $page->findField('checkboxes_all_checked_when_checkbox_trigger_checked[value1]'); $this->assertNotEmpty($checkboxes_all_checked_element_value1); Loading Loading @@ -180,6 +181,8 @@ protected function doCheckboxTriggerTests() { $this->assertFalse($radios_all_disabled_value2->hasAttribute('disabled')); $this->assertFalse($radios_some_disabled_value1->hasAttribute('disabled')); $this->assertFalse($radios_some_disabled_value2->hasAttribute('disabled')); // Check if the link is visible. $this->assertTrue($link->isVisible()); // Change state: check the checkbox. $trigger->check(); Loading Loading @@ -219,6 +222,8 @@ protected function doCheckboxTriggerTests() { // Only value1 should be disabled, value 2 should remain enabled. $this->assertTrue($radios_some_disabled_value1->hasAttribute('disabled')); $this->assertFalse($radios_some_disabled_value2->hasAttribute('disabled')); // The link shouldn't be visible. $this->assertFalse($link->isVisible()); // Change state: uncheck the checkbox. $trigger->uncheck(); Loading Loading @@ -252,6 +257,8 @@ protected function doCheckboxTriggerTests() { $this->assertFalse($radios_all_disabled_value2->hasAttribute('disabled')); $this->assertFalse($radios_some_disabled_value1->hasAttribute('disabled')); $this->assertFalse($radios_some_disabled_value2->hasAttribute('disabled')); // Check if the link is turned back to visible state. $this->assertTrue($link->isVisible()); } /** Loading Loading
core/lib/Drupal/Core/Render/Element/Link.php +7 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Component\Utility\Html as HtmlUtility; use Drupal\Core\Form\FormHelper; use Drupal\Core\Render\BubbleableMetadata; use Drupal\Core\Render\Element; use Drupal\Core\Url as CoreUrl; Loading Loading @@ -57,6 +58,12 @@ public function getInfo() { * The passed-in element containing a rendered link in '#markup'. */ public static function preRenderLink($element) { // As the preRenderLink() method is executed before Renderer::doRender(), // call processStates() to make sure that states are added to link elements. if (!empty($element['#states'])) { FormHelper::processStates($element); } // By default, link options to pass to the link generator are normally set // in #options. $element += ['#options' => []]; Loading
core/misc/states.js +8 −3 Original line number Diff line number Diff line Loading @@ -724,9 +724,14 @@ $document.on('state:visible', (e) => { if (e.trigger) { $(e.target) .closest('.js-form-item, .js-form-submit, .js-form-wrapper') .toggle(e.value); let $element = $(e.target).closest( '.js-form-item, .js-form-submit, .js-form-wrapper', ); // For links, update the state of itself instead of the wrapper. if (e.target.tagName === 'A') { $element = $(e.target); } $element.toggle(e.value); } }); Loading
core/modules/system/tests/modules/form_test/src/Form/JavascriptStatesForm.php +13 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Url; /** * Builds a simple form to test states. Loading Loading @@ -544,6 +545,18 @@ public function buildForm(array $form, FormStateInterface $form_state) { ], ], ]; $form['link'] = [ '#type' => 'link', '#title' => 'Link states test', '#url' => Url::fromRoute('<front>'), '#states' => [ 'visible' => [ ':input[name="checkbox_trigger"]' => ['checked' => FALSE], ], ], ]; return $form; } Loading
core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php +7 −0 Original line number Diff line number Diff line Loading @@ -102,6 +102,7 @@ protected function doCheckboxTriggerTests() { $this->assertNotEmpty($text_format_invisible_value); $text_format_invisible_format = $page->findField('text_format_invisible_when_checkbox_trigger_checked[format]'); $this->assertNotEmpty($text_format_invisible_format); $link = $page->findLink('Link states test'); $checkboxes_all_checked_element_value1 = $page->findField('checkboxes_all_checked_when_checkbox_trigger_checked[value1]'); $this->assertNotEmpty($checkboxes_all_checked_element_value1); Loading Loading @@ -180,6 +181,8 @@ protected function doCheckboxTriggerTests() { $this->assertFalse($radios_all_disabled_value2->hasAttribute('disabled')); $this->assertFalse($radios_some_disabled_value1->hasAttribute('disabled')); $this->assertFalse($radios_some_disabled_value2->hasAttribute('disabled')); // Check if the link is visible. $this->assertTrue($link->isVisible()); // Change state: check the checkbox. $trigger->check(); Loading Loading @@ -219,6 +222,8 @@ protected function doCheckboxTriggerTests() { // Only value1 should be disabled, value 2 should remain enabled. $this->assertTrue($radios_some_disabled_value1->hasAttribute('disabled')); $this->assertFalse($radios_some_disabled_value2->hasAttribute('disabled')); // The link shouldn't be visible. $this->assertFalse($link->isVisible()); // Change state: uncheck the checkbox. $trigger->uncheck(); Loading Loading @@ -252,6 +257,8 @@ protected function doCheckboxTriggerTests() { $this->assertFalse($radios_all_disabled_value2->hasAttribute('disabled')); $this->assertFalse($radios_some_disabled_value1->hasAttribute('disabled')); $this->assertFalse($radios_some_disabled_value2->hasAttribute('disabled')); // Check if the link is turned back to visible state. $this->assertTrue($link->isVisible()); } /** Loading