custom_field-1.0.x-dev/src/Plugin/CustomField/FieldWidget/MapWidgetBase.php

src/Plugin/CustomField/FieldWidget/MapWidgetBase.php
<?php

declare(strict_types=1);

namespace Drupal\custom_field\Plugin\CustomField\FieldWidget;

use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\InvokeCommand;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\custom_field\Plugin\CustomFieldTypeInterface;
use Drupal\custom_field\Plugin\CustomFieldWidgetBase;

/**
 * Base plugin class for map custom field widgets.
 */
class MapWidgetBase extends CustomFieldWidgetBase {

  /**
   * Default new item.
   *
   * @return string|int|array<string|int, mixed>
   *   The default value for new items.
   */
  protected static function newItem(): string|int|array {
    return '';
  }

  /**
   * {@inheritdoc}
   */
  public function widget(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state, CustomFieldTypeInterface $field): array {
    $element = parent::widget($items, $delta, $element, $form, $form_state, $field);
    $element['#type'] = 'item';

    return $element;
  }

  /**
   * Submit handler for the "add item" button.
   */
  public static function addItem(array &$form, FormStateInterface $form_state): void {
    $trigger = $form_state->getTriggeringElement();
    $wrapper_id = $trigger['#ajax']['wrapper'];
    $items = $form_state->get($wrapper_id);
    $items[] = static::newItem();
    $form_state->set($wrapper_id, $items);
    $form_state->setRebuild();
  }

  /**
   * Submit handler for the "remove item" button.
   */
  public static function removeItem(array &$form, FormStateInterface $form_state): void {
    $trigger = $form_state->getTriggeringElement();
    $key = $trigger['#attributes']['data-key'];
    $wrapper_id = $trigger['#ajax']['wrapper'];
    $items = $form_state->get($wrapper_id);
    // Only unset if the key exists.
    if (isset($items[$key])) {
      unset($items[$key]);
    }
    $form_state->set($wrapper_id, $items);
    $form_state->setRebuild();
  }

  /**
   * Callback for both ajax-enabled buttons.
   *
   * Selects and returns the fieldset with the names in it.
   */
  public function actionCallback(array &$form, FormStateInterface $form_state): AjaxResponse {
    // Get the triggering element's wrapper ID.
    $trigger = $form_state->getTriggeringElement();
    $wrapper_id = $trigger['#ajax']['wrapper'];

    // Get the current parent array for this widget.
    $parents = $trigger['#array_parents'];
    $length = -1;
    if (isset($trigger['#attributes']['data-key'])) {
      $length = -3;
    }
    $sliced_parents = array_slice($parents, 0, $length, TRUE);

    // Get the updated element from the form structure.
    $updated_element = NestedArray::getValue($form, $sliced_parents)['data'];

    $focus_input = NULL;
    $children = Element::children($updated_element);
    $last_child_key = end($children);
    if ($last_child_key !== FALSE && isset($updated_element[$last_child_key])) {
      $last_child = $updated_element[$last_child_key];
      // For key/value widget.
      if (array_key_exists('key', $last_child)) {
        $focus_input = $last_child['key']['#name'];
      }
      // For text widget.
      elseif (array_key_exists('value', $last_child)) {
        $focus_input = $last_child['value']['#name'];
      }
    }

    // Create an AjaxResponse.
    $response = new AjaxResponse();
    // Add a ReplaceCommand to replace the content inside the widget's wrapper.
    $response->addCommand(new ReplaceCommand('#' . $wrapper_id, $updated_element));
    // Set the focus to the newly added item if applicable.
    if (!empty($focus_input)) {
      $response->addCommand(new InvokeCommand('input[name="' . $focus_input . '"]', 'focus'));
    }

    return $response;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc