diff --git a/core/includes/common.inc b/core/includes/common.inc
index 037c5b0..51b717f 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -568,7 +568,7 @@ function drupal_js_defaults($data = NULL) {
* @param $elements
* A renderable array element having a #states property as described above.
*
- * @see form_example_states_form()
+ * @see \Drupal\form_test\Form\JavascriptStatesForm
*/
function drupal_process_states(&$elements) {
$elements['#attached']['library'][] = 'core/drupal.states';
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 42a6ba4..716d984 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
@@ -479,3 +479,10 @@ form_test.get_form:
_form: '\Drupal\form_test\Form\FormTestGetForm'
requirements:
_access: 'TRUE'
+
+form_test.javascript_states_form:
+ path: '/form-test/javascript-states-form'
+ defaults:
+ _form: '\Drupal\form_test\Form\JavascriptStatesForm'
+ requirements:
+ _access: 'TRUE'
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
new file mode 100644
index 0000000..6816a95
--- /dev/null
+++ b/core/modules/system/tests/modules/form_test/src/Form/JavascriptStatesForm.php
@@ -0,0 +1,181 @@
+ 'checkbox',
+ '#title' => 'Checkbox trigger',
+ ];
+ $form['textfield_trigger'] = [
+ '#type' => 'textfield',
+ '#title' => 'Textfield trigger',
+ ];
+ $form['radios_trigger'] = [
+ '#type' => 'radios',
+ '#title' => 'Radios trigger',
+ '#options' => [
+ 'value1' => 'Value 1',
+ 'value2' => 'Value 2',
+ 'value3' => 'Value 3',
+ ],
+ ];
+ $form['checkboxes_trigger'] = [
+ '#type' => 'checkboxes',
+ '#title' => 'Checkboxes trigger',
+ '#options' => [
+ 'value1' => 'Value 1',
+ 'value2' => 'Value 2',
+ 'value3' => 'Value 3',
+ ],
+ ];
+ $form['select_trigger'] = [
+ '#type' => 'select',
+ '#title' => 'Select trigger',
+ '#options' => [
+ 'value1' => 'Value 1',
+ 'value2' => 'Value 2',
+ 'value3' => 'Value 3',
+ ],
+ ];
+
+ $form['separator'] = [
+ '#markup' => '
',
+ ];
+
+ // Tested fields.
+ $form['textfield_invisible_when_checkbox_trigger_checked'] = [
+ '#type' => 'textfield',
+ '#title' => 'Texfield invisible when checkbox trigger checked',
+ '#states' => [
+ 'invisible' => [
+ ':input[name="checkbox_trigger"]' => ['checked' => TRUE],
+ ],
+ ],
+ ];
+ $form['checkbox_unchecked_when_textfield_trigger_filled'] = [
+ '#type' => 'checkbox',
+ '#title' => 'Checkbox unchecked when textfield trigger filled',
+ '#default_value' => '1',
+ '#states' => [
+ 'unchecked' => [
+ ':input[name="textfield_trigger"]' => ['filled' => TRUE],
+ ],
+ ],
+ ];
+ $form['textfield_visible_when_checkboxes_trigger_value2_checked'] = [
+ '#type' => 'textfield',
+ '#title' => 'Texfield visible when checkboxes trigger value2 checked',
+ '#states' => [
+ 'visible' => [
+ ':input[name="checkboxes_trigger[value2]"]' => ['checked' => TRUE],
+ ],
+ ],
+ ];
+ $form['textfield_visible_when_checkboxes_trigger_value3_checked'] = [
+ '#type' => 'textfield',
+ '#title' => 'Texfield visible when checkboxes trigger value3 checked',
+ '#states' => [
+ 'visible' => [
+ ':input[name="checkboxes_trigger[value3]"]' => ['checked' => TRUE],
+ ],
+ ],
+ ];
+ $form['item_visible_when_select_trigger_has_given_value'] = [
+ '#type' => 'item',
+ '#title' => 'Item visible when select trigger has given value',
+ '#states' => [
+ 'visible' => [
+ ':input[name="select_trigger"]' => ['value' => 'value2'],
+ ],
+ ],
+ ];
+ $form['textfield_visible_when_select_trigger_has_given_value'] = [
+ '#type' => 'textfield',
+ '#title' => 'Textfield visible when select trigger has given value',
+ '#states' => [
+ 'visible' => [
+ ':input[name="select_trigger"]' => ['value' => 'value3'],
+ ],
+ ],
+ ];
+ $form['item_visible_when_select_trigger_has_given_value_and_textfield_trigger_filled'] = [
+ '#type' => 'item',
+ '#title' => 'Item visible when select trigger has given value and textfield trigger filled',
+ '#states' => [
+ 'visible' => [
+ ':input[name="select_trigger"]' => ['value' => 'value2'],
+ ':input[name="textfield_trigger"]' => ['filled' => TRUE],
+ ],
+ ],
+ ];
+ $form['textfield_visible_when_select_trigger_has_given_value_or_another'] = [
+ '#type' => 'textfield',
+ '#title' => 'Textfield visible when select trigger has given value or another',
+ '#states' => [
+ 'visible' => [
+ ':input[name="select_trigger"]' => [
+ ['value' => 'value2'],
+ ['value' => 'value3'],
+ ],
+ ],
+ ],
+ ];
+ $form['fieldset_visible_when_radios_trigger_has_given_value'] = [
+ '#type' => 'fieldset',
+ '#title' => 'Fieldset visible when radio trigger has given value',
+ '#states' => [
+ 'visible' => [
+ ':input[name="radios_trigger"]' => ['value' => 'value2'],
+ ],
+ ],
+ ];
+ $form['fieldset_visible_when_radios_trigger_has_given_value']['textfield_in_fieldset'] = [
+ '#type' => 'textfield',
+ '#title' => 'Textfield in fieldset',
+ ];
+ $form['details_expanded_when_checkbox_trigger_checked'] = [
+ '#type' => 'details',
+ '#title' => 'Details expanded when checkbox trigger checked',
+ '#states' => [
+ 'expanded' => [
+ ':input[name="checkbox_trigger"]' => ['checked' => TRUE],
+ ],
+ ],
+ ];
+ $form['details_expanded_when_checkbox_trigger_checked']['textfield_in_details'] = [
+ '#type' => 'textfield',
+ '#title' => 'Textfield in details',
+ ];
+
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitForm(array &$form, FormStateInterface $form_state) {
+ }
+
+}
diff --git a/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php b/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php
new file mode 100644
index 0000000..c6d76c8
--- /dev/null
+++ b/core/tests/Drupal/FunctionalJavascriptTests/Core/Form/JavascriptStatesTest.php
@@ -0,0 +1,208 @@
+drupalGet('form-test/javascript-states-form');
+ $page = $this->getSession()->getPage();
+
+ // Checkbox triggered states.
+ $this->assertTrue(
+ $page->findField('textfield_invisible_when_checkbox_trigger_checked')->isVisible(),
+ 'Field "textfield_invisible_when_checkbox_trigger_checked" is visible'
+ );
+ $this->assertFalse(
+ $page->findField('textfield_in_details')->isVisible(),
+ 'Field "textfield_in_details" is not visible (details element collapsed)'
+ );
+
+ $page->checkField('checkbox_trigger');
+
+ $this->assertFalse(
+ $page->findField('textfield_invisible_when_checkbox_trigger_checked')->isVisible(),
+ 'Field "textfield_invisible_when_checkbox_trigger_checked" is not visible'
+ );
+ $this->assertTrue(
+ $page->findField('textfield_in_details')->isVisible(),
+ 'Field "textfield_in_details" is visible (details element open)'
+ );
+
+ $page->uncheckField('checkbox_trigger');
+
+ // Textfield triggered states.
+ $this->assertTrue(
+ $page->findField('checkbox_unchecked_when_textfield_trigger_filled')->isChecked(),
+ 'Field "checkbox_unchecked_when_textfield_trigger_filled" is checked'
+ );
+
+ $page->fillField('textfield_trigger', 'filled');
+
+ $this->assertFalse(
+ $page->findField('checkbox_unchecked_when_textfield_trigger_filled')->isChecked(),
+ 'Field "checkbox_unchecked_when_textfield_trigger_filled" is not checked'
+ );
+
+ $page->fillField('textfield_trigger', '');
+
+ // Radios triggered states.
+ $this->assertFalse(
+ $page->findField('textfield_in_fieldset')->isVisible(),
+ 'Field "textfield_in_fieldset" is not visible (parent fieldset invisible)'
+ );
+
+ $page->selectFieldOption('radios_trigger', 'value2');
+
+ $this->assertTrue(
+ $page->findField('textfield_in_fieldset')->isVisible(),
+ 'Field "textfield_in_fieldset" is visible (parent fieldset visible)'
+ );
+
+ $page->selectFieldOption('radios_trigger', 'value1');
+
+ // Checkboxes triggered states.
+ $this->assertFalse(
+ $page->findField('textfield_visible_when_checkboxes_trigger_value2_checked')->isVisible(),
+ 'Field "textfield_visible_when_checkboxes_trigger_value2_checked" is not visible'
+ );
+ $this->assertFalse(
+ $page->findField('textfield_visible_when_checkboxes_trigger_value3_checked')->isVisible(),
+ 'Field "textfield_visible_when_checkboxes_trigger_value3_checked" is not visible'
+ );
+
+ $page->checkField('checkboxes_trigger[value1]');
+
+ $this->assertFalse(
+ $page->findField('textfield_visible_when_checkboxes_trigger_value2_checked')->isVisible(),
+ 'Field "textfield_visible_when_checkboxes_trigger_value2_checked" is not visible'
+ );
+ $this->assertFalse(
+ $page->findField('textfield_visible_when_checkboxes_trigger_value3_checked')->isVisible(),
+ 'Field "textfield_visible_when_checkboxes_trigger_value3_checked" is not visible'
+ );
+
+ $page->checkField('checkboxes_trigger[value2]');
+
+ $this->assertTrue(
+ $page->findField('textfield_visible_when_checkboxes_trigger_value2_checked')->isVisible(),
+ 'Field "textfield_visible_when_checkboxes_trigger_value2_checked" is visible'
+ );
+ $this->assertFalse(
+ $page->findField('textfield_visible_when_checkboxes_trigger_value3_checked')->isVisible(),
+ 'Field "textfield_visible_when_checkboxes_trigger_value3_checked" is not visible'
+ );
+
+ $page->checkField('checkboxes_trigger[value3]');
+
+ $this->assertTrue(
+ $page->findField('textfield_visible_when_checkboxes_trigger_value2_checked')->isVisible(),
+ 'Field "textfield_visible_when_checkboxes_trigger_value2_checked" is visible'
+ );
+ $this->assertTrue(
+ $page->findField('textfield_visible_when_checkboxes_trigger_value3_checked')->isVisible(),
+ 'Field "textfield_visible_when_checkboxes_trigger_value3_checked" is visible'
+ );
+
+ $page->uncheckField('checkboxes_trigger[value2]');
+
+ $this->assertFalse(
+ $page->findField('textfield_visible_when_checkboxes_trigger_value2_checked')->isVisible(),
+ 'Field "textfield_visible_when_checkboxes_trigger_value2_checked" is not visible'
+ );
+ $this->assertTrue(
+ $page->findField('textfield_visible_when_checkboxes_trigger_value3_checked')->isVisible(),
+ 'Field "textfield_visible_when_checkboxes_trigger_value3_checked" is visible'
+ );
+
+ $page->uncheckField('checkboxes_trigger[value1]');
+ $page->uncheckField('checkboxes_trigger[value2]');
+ $page->uncheckField('checkboxes_trigger[value3]');
+
+ // Select triggered states.
+ $this->assertFalse(
+ $page->find('css', '#edit-item-visible-when-select-trigger-has-given-value')->isVisible(),
+ 'Field "edit-item-visible-when-select-trigger-has-given-value" is not visible'
+ );
+ $this->assertFalse(
+ $page->findField('textfield_visible_when_select_trigger_has_given_value')->isVisible(),
+ 'Field "textfield_visible_when_select_trigger_has_given_value" is not visible'
+ );
+ $this->assertFalse(
+ $page->findField('textfield_visible_when_select_trigger_has_given_value_or_another')->isVisible(),
+ 'Field "textfield_visible_when_select_trigger_has_given_value_or_another" is not visible'
+ );
+
+ $page->selectFieldOption('select_trigger', 'value2');
+
+ $this->assertTrue(
+ $page->find('css', '#edit-item-visible-when-select-trigger-has-given-value')->isVisible(),
+ 'Field "#edit-item-visible-when-select-trigger-has-given-value" is visible'
+ );
+ $this->assertFalse(
+ $page->findField('textfield_visible_when_select_trigger_has_given_value')->isVisible(),
+ 'Field "textfield_visible_when_select_trigger_has_given_value" is not visible'
+ );
+ $this->assertTrue(
+ $page->findField('textfield_visible_when_select_trigger_has_given_value_or_another')->isVisible(),
+ 'Field "textfield_visible_when_select_trigger_has_given_value_or_another" is visible'
+ );
+
+ $page->selectFieldOption('select_trigger', 'value3');
+
+ $this->assertFalse(
+ $page->find('css', '#edit-item-visible-when-select-trigger-has-given-value')->isVisible(),
+ 'Field "#edit-item-visible-when-select-trigger-has-given-value" is not visible'
+ );
+ $this->assertTrue(
+ $page->findField('textfield_visible_when_select_trigger_has_given_value')->isVisible(),
+ 'Field "textfield_visible_when_select_trigger_has_given_value" is visible'
+ );
+ $this->assertTrue(
+ $page->findField('textfield_visible_when_select_trigger_has_given_value_or_another')->isVisible(),
+ 'Field "textfield_visible_when_select_trigger_has_given_value_or_another" is visible'
+ );
+
+ $page->selectFieldOption('select_trigger', 'value1');
+
+ // Select + textfield triggered states.
+ // @todo Figure out why it's not working
+ $this->assertFalse(
+ $page->find('css', '#edit-item-visible-when-select-trigger-has-given-value-and-textfield-trigger-filled')->isVisible(),
+ 'Field "#edit-item-visible-when-select-trigger-has-given-value-and-textfield-trigger-filled" is not visible'
+ );
+
+ $page->selectFieldOption('select_trigger', 'value2');
+
+ $this->assertFalse(
+ $page->find('css', '#edit-item-visible-when-select-trigger-has-given-value-and-textfield-trigger-filled')->isVisible(),
+ 'Field "#edit-item-visible-when-select-trigger-has-given-value-and-textfield-trigger-filled" is not visible'
+ );
+
+ $page->fillField('textfield_trigger', 'filled');
+
+ $this->assertTrue(
+ $page->find('css', '#edit-item-visible-when-select-trigger-has-given-value-and-textfield-trigger-filled')->isVisible(),
+ 'Field "#edit-item-visible-when-select-trigger-has-given-value-and-textfield-trigger-filled" is visible'
+ );
+
+ $page->selectFieldOption('select_trigger', 'value1');
+ $page->fillField('textfield_trigger', '');
+ }
+
+}