diff --git a/core/lib/Drupal/Core/Field/WidgetBase.php b/core/lib/Drupal/Core/Field/WidgetBase.php index 5f7ce3c..ffc837e 100644 --- a/core/lib/Drupal/Core/Field/WidgetBase.php +++ b/core/lib/Drupal/Core/Field/WidgetBase.php @@ -144,6 +144,9 @@ protected function formMultipleElements(FieldItemListInterface $items, array &$f $cardinality = $this->fieldDefinition->getFieldStorageDefinition()->getCardinality(); $parents = $form['#parents']; + $id_prefix = implode('-', array_merge($parents, array($field_name))); + $wrapper_id = Html::getUniqueId($id_prefix . '-add-more-wrapper'); + // Determine the number of widgets to display. switch ($cardinality) { case FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED: @@ -202,6 +205,22 @@ protected function formMultipleElements(FieldItemListInterface $items, array &$f '#default_value' => $items[$delta]->_weight ?: $delta, '#weight' => 100, ); + + if ($cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED && !$form_state->isProgrammed() && $field_state['items_count'] > 0) { + $element['remove_item'] = array( + '#type' => 'submit', + '#value' => $this->t('Remove item'), + '#submit' => array(array(get_class($this), 'removeItemSubmit')), + '#ajax' => array( + 'callback' => array(get_class($this), 'removeItemAjax'), + 'wrapper' => $wrapper_id, + 'effect' => 'fade', + ), + '#name' => implode('_', array_merge($parents, array($field_name, $delta, 'remove_item'))), + '#attributes' => array('class' => array('field-remove-item-submit')), + '#limit_validation_errors' => array(array_merge($parents, array($field_name))), + ); + } } $elements[$delta] = $element; @@ -222,8 +241,6 @@ protected function formMultipleElements(FieldItemListInterface $items, array &$f // Add 'add more' button, if not working with a programmed form. if ($cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED && !$form_state->isProgrammed()) { - $id_prefix = implode('-', array_merge($parents, array($field_name))); - $wrapper_id = Html::getUniqueId($id_prefix . '-add-more-wrapper'); $elements['#prefix'] = '
'; $elements['#suffix'] = '
'; @@ -263,6 +280,41 @@ public static function afterBuild(array $element, FormStateInterface $form_state return $element; } + public static function removeItemSubmit(array $form, FormStateInterface $form_state) { + $button = $form_state->getTriggeringElement(); + + // Go one level up in the form, to the widgets container. + $element = NestedArray::getValue($form, array_slice($button['#array_parents'], 0, -1)); + $container_element = NestedArray::getValue($form, array_slice($button['#array_parents'], 0, -2)); + $field_name = $container_element['#field_name']; + $field_parents = $element['#field_parents']; + $delta = $element['#delta']; + $field_values = &$form_state->getValue($container_element['#parents']); + $field_input = &NestedArray::getValue($form_state->getUserInput(), $container_element['#parents']); + $field_state = static::getWidgetState($field_parents, $field_name, $form_state); + + for ($i = $delta; $i < $field_state['items_count']; $i++) { + $field_values[$i] = $field_values[$i+1]; + $field_input[$i] = $field_input[$i+1]; + } + unset($field_values[$field_state['items_count']]); + unset($field_input[$field_state['items_count']]); + + // Increment the items count. + $field_state['items_count']--; + static::setWidgetState($field_parents, $field_name, $form_state, $field_state); + + $form_state->setRebuild(); + } + + public static function removeItemAjax(array $form, FormStateInterface $form_state) { + $button = $form_state->getTriggeringElement(); + + // Go two levels up in the form, to the widgets container. + $element = NestedArray::getValue($form, array_slice($button['#array_parents'], 0, -2)); + + return $element; + } /** * Submission handler for the "Add another item" button. */