🇮🇱Israel @Eyal Shalev

Account created on 12 July 2011, almost 13 years ago
#

Recent comments

🇮🇱Israel Eyal Shalev

Same as #74. I didn't patch against 8.1.x

🇮🇱Israel Eyal Shalev
  • Fixed the cause of the test fail.
  • Only add the remove button when the field cardinality is unlimited and it is not programmed.
🇮🇱Israel Eyal Shalev

I've found some bugs with the first patch.

The changes are:

  • The ajax callback no longer return an empty element but the whole container.
  • The id_prefix and wrapper_id variables are moved up in the formMultipleElements method.
  • The submit method will now affect both the form_state values and the form_state user_input.
  • The submit method will now only unset the choosen item but move all the items after it one delta lower.
🇮🇱Israel Eyal Shalev

I tried to replace all the [] arrays to array(). This was done manually so it could fail.

🇮🇱Israel Eyal Shalev

I created a working remove item button in a custom field widget using the following code:



  /**
   * {@inheritdoc}
   */
  protected function formMultipleElements(FieldItemListInterface $items, array &$form, FormStateInterface $form_state) {
    $elements = parent::formMultipleElements($items,$form,$form_state);
    $field_name = $this->fieldDefinition->getName();
    $parents = $form['#parents'];

    foreach (Element::children($elements) as $element_key) {
      if (is_int($element_key)) {
        $delta = $element_key;

        $wrapper_array = array_merge($parents, [
          $field_name,
          $delta,
          'remove',
          'item'
        ]);
        $wrapper_id = Html::getUniqueId(implode('-', $wrapper_array));
        $elements[$delta]['#prefix'] = "<div id={$wrapper_id}>";
        $elements[$delta]['#suffix'] = '</div>';
        $elements[$delta]['remove_item'] = [
          '#type' => 'submit',
          '#value' => $this->t('Remove item'),
          '#submit' => [[$this, 'removeItemSubmit']],
          '#ajax' => [
            'callback' => [$this, 'removeItemAjax'],
            'wrapper' => $wrapper_id,
            'effect' => 'fade',
          ],
          '#name' => implode('_', $wrapper_array),
          '#attributes' => ['class' => ['field-remove-item-submit']],
          '#limit_validation_errors' => [array_merge($parents, [$field_name])],
        ];
      }
    }


    return $elements;
  }

  public 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 = $this->fieldDefinition->getName();
    $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 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.'
      ]
    ];
  }
Production build 0.69.0 2024