diff --git a/core/lib/Drupal/Core/Field/WidgetBase.php b/core/lib/Drupal/Core/Field/WidgetBase.php index 55c5b1ecd5..35ad9a447c 100644 --- a/core/lib/Drupal/Core/Field/WidgetBase.php +++ b/core/lib/Drupal/Core/Field/WidgetBase.php @@ -111,15 +111,6 @@ public function form(FieldItemListInterface $items, array &$form, FormStateInter $elements = $this->formMultipleElements($items, $form, $form_state); } - // Allow modules to alter the field multi-value widget form element. - // This hook can also be used for single-value fields. - $context = [ - 'form' => $form, - 'widget' => $this, - 'items' => $items, - 'default' => $this->isDefaultValueWidget($form_state), - ]; - // Populate the 'array_parents' information in $form_state->get('field') // after the form is built, so that we catch changes in the form structure // performed in alter() hooks. @@ -175,7 +166,7 @@ protected function formMultipleElements(FieldItemListInterface $items, array &$f switch ($cardinality) { case FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED: $field_state = static::getWidgetState($parents, $field_name, $form_state); - $max = $field_state['items_count']; + $max = (isset($form['#parents'][0]) && $form['#parents'][0] === 'default_value_input') ? max(0, $field_state['items_count'] - 1) : $field_state['items_count']; $is_multiple = TRUE; break; @@ -267,6 +258,28 @@ protected function formMultipleElements(FieldItemListInterface $items, array &$f 'effect' => 'fade', ], ]; + + // By default, the limit quantity is defined by quantity of items. + $optionsAvailable = $items->count(); + if (!$items->getEntity()->isNew()) { + // None options available when editing a field to avoid empty input field. + $optionsAvailable = 0; + $userInput = $form_state->getUserInput(); + $isAddingMore = isset($userInput["_triggering_element_name"]) + && $userInput["_triggering_element_name"] == $field_name . '_add_more'; + // On add more action only one option must appear to the user. + if ($isAddingMore) { + $optionsAvailable = 1; + } + } + + // Remove leftover option. + $emptyValues = $items->count() - count(array_filter($items->getValue())); + if ($emptyValues > $optionsAvailable) { + unset($elements[$max]); + $items->removeItem($max); + $elements["#max_delta"] = $items->count() - 1; + } } }