diff --git a/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php b/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php index 6cce573..9c5c8ea 100644 --- a/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php +++ b/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php @@ -522,10 +522,20 @@ public static function getSelected(FormStateInterface $form_state, array $parent if ($key_exists) { $option_exists = in_array($submitted, array_keys($element['#options'])); // If this value is invalid or if the user-submitted value has changed, - // remove all other options in that set of values. - if (!$option_exists || $submitted !== $default_value) { - array_pop($parents); + // remove all other options in that set of values. Only manipulate the + // user input during the initial form build, not during any subsequent + // rebuild. + if ((!$option_exists || $submitted !== $default_value) && !$form_state->isRebuilding()) { + // If this is a not a top-level element, traverse up one level. + $original_parents = $parents; + if (count($parents) > 1) { + array_pop($parents); + } NestedArray::unsetValue($user_input, $parents); + // Restore the submitted value to the input. + if ($option_exists) { + NestedArray::setValue($user_input, $original_parents, $submitted); + } } if ($option_exists) { diff --git a/core/modules/views/src/Tests/Wizard/TaggedWithTest.php b/core/modules/views/src/Tests/Wizard/TaggedWithTest.php index caf95be..ce26716 100644 --- a/core/modules/views/src/Tests/Wizard/TaggedWithTest.php +++ b/core/modules/views/src/Tests/Wizard/TaggedWithTest.php @@ -196,11 +196,11 @@ function testTaggedWithByNodeType() { $this->drupalPostForm('admin/structure/views/add', $view, t('Update "of type" choice')); $this->assertFieldByXpath($tags_xpath); $view['show[type]'] = $this->nodeTypeWithoutTags->id(); - $this->drupalPostForm(NULL, $view, t('Update "of type" choice')); + $this->drupalPostForm(NULL, $view, t('Update "of type" choice (2)')); $this->assertNoFieldByXpath($tags_xpath); // If we add an instance of the tagging field to the second node type, the - // "tagged with" form element should not appear for it too. + // "tagged with" form element should now appear for it too. entity_create('field_config', array( 'field_name' => $this->tagFieldName, 'entity_type' => 'node', @@ -225,7 +225,7 @@ function testTaggedWithByNodeType() { $this->drupalPostForm('admin/structure/views/add', $view, t('Update "of type" choice')); $this->assertFieldByXpath($tags_xpath); $view['show[type]'] = $this->nodeTypeWithoutTags->id(); - $this->drupalPostForm(NULL, $view, t('Update "of type" choice')); + $this->drupalPostForm(NULL, $view, t('Update "of type" choice (2)')); $this->assertFieldByXpath($tags_xpath); } diff --git a/core/modules/views/tests/src/Unit/WizardPluginBaseTest.php b/core/modules/views/tests/src/Unit/WizardPluginBaseTest.php index 1145ef0..ed30219 100644 --- a/core/modules/views/tests/src/Unit/WizardPluginBaseTest.php +++ b/core/modules/views/tests/src/Unit/WizardPluginBaseTest.php @@ -37,18 +37,21 @@ public function testGetSelected($expected, $element = [], $parents = [], $user_i */ public function providerTestGetSelected() { $data = []; + // A form element with an invalid #type. $data[] = [ 'the_default_value', [ '#type' => 'checkbox', ], ]; + // A form element with no #options. $data[] = [ 'the_default_value', [ '#type' => 'select', ], ]; + // A valid form element with no user input. $data[] = [ 'the_default_value', [ @@ -58,6 +61,7 @@ public function providerTestGetSelected() { ], ], ]; + // A valid form element with user input that doesn't correspond to it. $data[] = [ 'the_default_value', [ @@ -70,6 +74,7 @@ public function providerTestGetSelected() { ['foo' => ['foo' => 'value1']], ['foo' => ['foo' => 'value1']], ]; + // A valid form element that is at the top-level of the form. $data[] = [ 'the_default_value', [ @@ -80,8 +85,9 @@ public function providerTestGetSelected() { ], ['foo'], ['foo' => ['bar' => 'value1']], - ['foo' => ['bar' => 'value1']], ]; + // A valid form element that has multiple invalid values with the same + // parent. $data[] = [ 'the_default_value', [ @@ -91,8 +97,10 @@ public function providerTestGetSelected() { ], ], ['foo', 'bar'], - ['foo' => ['bar' => 'value1']], + ['foo' => ['bar' => 'value1', 'baz' => 'value2']], ]; + // A valid form element with a valid dynamic value that matches the default + // value. $data[] = [ 'the_default_value', [ @@ -105,6 +113,8 @@ public function providerTestGetSelected() { ['foo' => ['bar' => 'the_default_value']], ['foo' => ['bar' => 'the_default_value']], ]; + // A valid form element with a valid dynamic value that does not match the + // default value. $data[] = [ 'option1', [ @@ -115,6 +125,7 @@ public function providerTestGetSelected() { ], ['foo', 'bar'], ['foo' => ['bar' => 'option1']], + ['foo' => ['bar' => 'option1']], ]; return $data; }