diff --git a/core/lib/Drupal/Core/Field/WidgetBase.php b/core/lib/Drupal/Core/Field/WidgetBase.php index 5f7ce3c..5dbf58c 100644 --- a/core/lib/Drupal/Core/Field/WidgetBase.php +++ b/core/lib/Drupal/Core/Field/WidgetBase.php @@ -161,7 +161,7 @@ protected function formMultipleElements(FieldItemListInterface $items, array &$f $title = $this->fieldDefinition->getLabel(); $description = FieldFilteredMarkup::create(\Drupal::token()->replace($this->fieldDefinition->getDescription())); - $elements = array(); + $elements = []; for ($delta = 0; $delta <= $max; $delta++) { // Add a new empty item if it doesn't exist yet at this delta. @@ -193,15 +193,38 @@ protected function formMultipleElements(FieldItemListInterface $items, array &$f if ($is_multiple) { // We name the element '_weight' to avoid clashing with elements // defined by widget. - $element['_weight'] = array( + $element['_weight'] = [ '#type' => 'weight', - '#title' => $this->t('Weight for row @number', array('@number' => $delta + 1)), + '#title' => $this->t('Weight for row @number', ['@number' => $delta + 1]), '#title_display' => 'invisible', // Note: this 'delta' is the FAPI #type 'weight' element's property. '#delta' => $max, '#default_value' => $items[$delta]->_weight ?: $delta, '#weight' => 100, - ); + ]; + + $remove_wrapper = array_merge($parents, [ + $field_name, + $delta, + 'remove', + 'item' + ]); + $remove_wrapper_id = Html::getUniqueId(implode('-', $remove_wrapper)); + $element['#prefix'] = "
"; + $element['#suffix'] = '
'; + $element['remove_item'] = [ + '#type' => 'submit', + '#value' => $this->t('Remove item'), + '#submit' => [[get_class($this), 'removeItemSubmit']], + '#ajax' => [ + 'callback' => [$this, 'removeItemAjax'], + 'wrapper' => $remove_wrapper_id, + 'effect' => 'fade', + ], + '#name' => implode('_', $remove_wrapper), + '#attributes' => ['class' => ['field-remove-item-submit']], + '#limit_validation_errors' => [array_merge($parents, [$field_name])], + ]; } $elements[$delta] = $element; @@ -209,7 +232,7 @@ protected function formMultipleElements(FieldItemListInterface $items, array &$f } if ($elements) { - $elements += array( + $elements += [ '#theme' => 'field_multiple_value_form', '#field_name' => $field_name, '#cardinality' => $cardinality, @@ -218,28 +241,28 @@ protected function formMultipleElements(FieldItemListInterface $items, array &$f '#title' => $title, '#description' => $description, '#max_delta' => $max, - ); + ]; // 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))); + $id_prefix = implode('-', array_merge($parents, [$field_name])); $wrapper_id = Html::getUniqueId($id_prefix . '-add-more-wrapper'); $elements['#prefix'] = '
'; $elements['#suffix'] = '
'; - $elements['add_more'] = array( + $elements['add_more'] = [ '#type' => 'submit', '#name' => strtr($id_prefix, '-', '_') . '_add_more', '#value' => t('Add another item'), - '#attributes' => array('class' => array('field-add-more-submit')), - '#limit_validation_errors' => array(array_merge($parents, array($field_name))), - '#submit' => array(array(get_class($this), 'addMoreSubmit')), - '#ajax' => array( - 'callback' => array(get_class($this), 'addMoreAjax'), + '#attributes' => ['class' => ['field-add-more-submit']], + '#limit_validation_errors' => [array_merge($parents, [$field_name])], + '#submit' => [[get_class($this), 'addMoreSubmit']], + '#ajax' => [ + 'callback' => [get_class($this), 'addMoreAjax'], 'wrapper' => $wrapper_id, 'effect' => 'fade', - ), - ); + ], + ]; } } @@ -263,6 +286,34 @@ 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']); + unset($field_values[$delta]); + + // Increment the items count. + $field_state = static::getWidgetState($field_parents, $field_name, $form_state); + $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) { + return [ + '#type' => 'hidden', + '#attributes' => [ + 'data-description' => 'It is a requirement to return something to make an ajax call hide the entire element.' + ] + ]; + } /** * Submission handler for the "Add another item" button. */