Loading core/lib/Drupal/Core/Field/WidgetBase.php +10 −2 Original line number Diff line number Diff line Loading @@ -68,8 +68,7 @@ public function form(FieldItemListInterface $items, array &$form, FormStateInter $field_name = $this->fieldDefinition->getName(); $parents = $form['#parents']; // Store field information in $form_state. if (!static::getWidgetState($parents, $field_name, $form_state)) { if (!$field_state = static::getWidgetState($parents, $field_name, $form_state)) { $field_state = [ 'items_count' => count($items), 'array_parents' => [], Loading @@ -77,6 +76,13 @@ public function form(FieldItemListInterface $items, array &$form, FormStateInter static::setWidgetState($parents, $field_name, $form_state, $field_state); } // Remove deleted items from the field item list. if (isset($field_state['deleted_item']) && $items->get($field_state['deleted_item'])) { $items->removeItem($field_state['deleted_item']); unset($field_state['deleted_item']); static::setWidgetState($parents, $field_name, $form_state, $field_state); } // Collect widget elements. $elements = []; Loading Loading @@ -384,6 +390,8 @@ public static function deleteSubmit(&$form, FormStateInterface $form_state) { $form_state->setUserInput($user_input); } $field_state['deleted_item'] = $delta; unset($parent_element[$delta]); NestedArray::setValue($form, $array_parents, $parent_element); Loading core/modules/field/tests/src/FunctionalJavascript/MultipleValueWidgetTest.php +15 −0 Original line number Diff line number Diff line Loading @@ -150,6 +150,21 @@ public function testFieldMultipleValueWidget() { // Assert that the wrapper exists and isn't nested. $this->assertSession()->elementsCount('css', '[data-drupal-selector="edit-field-unlimited-wrapper"]', 1); // Test removing items/values on saved entities resets to initial value. $this->submitForm([], 'Save'); $field_2_remove_button->click(); $this->assertSession()->assertWaitOnAjaxRequest(); $field_1_remove_button->click(); $this->assertSession()->assertWaitOnAjaxRequest(); $field_0_remove_button->click(); $this->assertSession()->assertWaitOnAjaxRequest(); $add_more_button->click(); $this->assertSession()->assertWaitOnAjaxRequest(); $this->assertSame('', $field_0->getValue()); $add_more_button->click(); $this->assertSession()->assertWaitOnAjaxRequest(); $this->assertSame('', $field_1->getValue()); } } core/tests/Drupal/FunctionalTests/Entity/ContentEntityFormCorrectUserInputMappingOnFieldDeltaElementsTest.php +20 −2 Original line number Diff line number Diff line Loading @@ -77,10 +77,10 @@ protected function setUp(): void { * Tests the correct user input mapping on complex fields. */ public function testCorrectUserInputMappingOnComplexFields() { /** @var ContentEntityStorageInterface $storage */ /** @var \Drupal\Core\Entity\ContentEntityStorageInterface $storage */ $storage = $this->container->get('entity_type.manager')->getStorage($this->entityTypeId); /** @var ContentEntityInterface $entity */ /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ $entity = $storage->create([ $this->fieldName => [ ['shape' => 'rectangle', 'color' => 'green'], Loading Loading @@ -118,6 +118,24 @@ public function testCorrectUserInputMappingOnComplexFields() { ['shape' => 'circle', 'color' => 'blue'], ['shape' => 'rectangle', 'color' => 'green'], ], $entity->get($this->fieldName)->getValue()); $this->drupalGet($this->entityTypeId . '/manage/' . $entity->id() . '/edit'); // Delete one of the field items and ensure that the user input is mapped on // the correct delta field items. $edit = [ "$this->fieldName[0][_weight]" => 0, "$this->fieldName[1][_weight]" => -1, ]; $this->submitForm($edit, "{$this->fieldName}_0_remove_button"); $this->submitForm([], 'Save'); $storage->resetCache([$entity->id()]); $entity = $storage->load($entity->id()); $this->assertEquals([ ['shape' => 'rectangle', 'color' => 'green'], ], $entity->get($this->fieldName)->getValue()); } } Loading
core/lib/Drupal/Core/Field/WidgetBase.php +10 −2 Original line number Diff line number Diff line Loading @@ -68,8 +68,7 @@ public function form(FieldItemListInterface $items, array &$form, FormStateInter $field_name = $this->fieldDefinition->getName(); $parents = $form['#parents']; // Store field information in $form_state. if (!static::getWidgetState($parents, $field_name, $form_state)) { if (!$field_state = static::getWidgetState($parents, $field_name, $form_state)) { $field_state = [ 'items_count' => count($items), 'array_parents' => [], Loading @@ -77,6 +76,13 @@ public function form(FieldItemListInterface $items, array &$form, FormStateInter static::setWidgetState($parents, $field_name, $form_state, $field_state); } // Remove deleted items from the field item list. if (isset($field_state['deleted_item']) && $items->get($field_state['deleted_item'])) { $items->removeItem($field_state['deleted_item']); unset($field_state['deleted_item']); static::setWidgetState($parents, $field_name, $form_state, $field_state); } // Collect widget elements. $elements = []; Loading Loading @@ -384,6 +390,8 @@ public static function deleteSubmit(&$form, FormStateInterface $form_state) { $form_state->setUserInput($user_input); } $field_state['deleted_item'] = $delta; unset($parent_element[$delta]); NestedArray::setValue($form, $array_parents, $parent_element); Loading
core/modules/field/tests/src/FunctionalJavascript/MultipleValueWidgetTest.php +15 −0 Original line number Diff line number Diff line Loading @@ -150,6 +150,21 @@ public function testFieldMultipleValueWidget() { // Assert that the wrapper exists and isn't nested. $this->assertSession()->elementsCount('css', '[data-drupal-selector="edit-field-unlimited-wrapper"]', 1); // Test removing items/values on saved entities resets to initial value. $this->submitForm([], 'Save'); $field_2_remove_button->click(); $this->assertSession()->assertWaitOnAjaxRequest(); $field_1_remove_button->click(); $this->assertSession()->assertWaitOnAjaxRequest(); $field_0_remove_button->click(); $this->assertSession()->assertWaitOnAjaxRequest(); $add_more_button->click(); $this->assertSession()->assertWaitOnAjaxRequest(); $this->assertSame('', $field_0->getValue()); $add_more_button->click(); $this->assertSession()->assertWaitOnAjaxRequest(); $this->assertSame('', $field_1->getValue()); } }
core/tests/Drupal/FunctionalTests/Entity/ContentEntityFormCorrectUserInputMappingOnFieldDeltaElementsTest.php +20 −2 Original line number Diff line number Diff line Loading @@ -77,10 +77,10 @@ protected function setUp(): void { * Tests the correct user input mapping on complex fields. */ public function testCorrectUserInputMappingOnComplexFields() { /** @var ContentEntityStorageInterface $storage */ /** @var \Drupal\Core\Entity\ContentEntityStorageInterface $storage */ $storage = $this->container->get('entity_type.manager')->getStorage($this->entityTypeId); /** @var ContentEntityInterface $entity */ /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ $entity = $storage->create([ $this->fieldName => [ ['shape' => 'rectangle', 'color' => 'green'], Loading Loading @@ -118,6 +118,24 @@ public function testCorrectUserInputMappingOnComplexFields() { ['shape' => 'circle', 'color' => 'blue'], ['shape' => 'rectangle', 'color' => 'green'], ], $entity->get($this->fieldName)->getValue()); $this->drupalGet($this->entityTypeId . '/manage/' . $entity->id() . '/edit'); // Delete one of the field items and ensure that the user input is mapped on // the correct delta field items. $edit = [ "$this->fieldName[0][_weight]" => 0, "$this->fieldName[1][_weight]" => -1, ]; $this->submitForm($edit, "{$this->fieldName}_0_remove_button"); $this->submitForm([], 'Save'); $storage->resetCache([$entity->id()]); $entity = $storage->load($entity->id()); $this->assertEquals([ ['shape' => 'rectangle', 'color' => 'green'], ], $entity->get($this->fieldName)->getValue()); } }