You are here

protected function EntityqueueDragtableWidget::formMultipleElements in Entityqueue 8

Special handling to create form elements for multiple values.

Handles generic features for multiple fields:

  • number of widgets
  • AHAH-'add more' button
  • table display and drag-n-drop value reordering

Overrides WidgetBase::formMultipleElements

File

src/Plugin/Field/FieldWidget/EntityqueueDragtableWidget.php, line 220

Class

EntityqueueDragtableWidget
Plugin implementation of the 'entityqueue_dragtable' widget.

Namespace

Drupal\entityqueue\Plugin\Field\FieldWidget

Code

protected function formMultipleElements(FieldItemListInterface $items, array &$form, FormStateInterface $form_state) {
  $field_name = $this->fieldDefinition
    ->getName();
  $cardinality = $this->fieldDefinition
    ->getFieldStorageDefinition()
    ->getCardinality();
  $parents = $form['#parents'];

  // Assign a unique identifier to each widget.
  $id_prefix = implode('-', array_merge($parents, [
    $field_name,
  ]));
  $wrapper_id = Html::getUniqueId($id_prefix . '-wrapper');
  $this
    ->setWrapperId($wrapper_id);

  // Determine the number of widgets to display.
  $field_state = static::getWidgetState($parents, $field_name, $form_state);
  $max = $field_state['items_count'];
  $elements = [];
  if ($max > 0) {
    for ($delta = 0; $delta < $max; $delta++) {

      // For multiple fields, title and description are handled by the wrapping
      // table.
      $element = [
        '#title' => $this
          ->t('@title (value @number)', [
          '@title' => $this->fieldDefinition
            ->getLabel(),
          '@number' => $delta + 1,
        ]),
        '#title_display' => 'invisible',
        '#description' => '',
      ];
      $element = $this
        ->formSingleElement($items, $delta, $element, $form, $form_state);
      if ($element) {

        // We name the element '_weight' to avoid clashing with elements
        // defined by widget.
        $element['_weight'] = [
          '#type' => 'weight',
          '#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,
        ];
        $elements[$delta] = $element;
      }
    }
  }
  $elements += [
    '#theme' => 'field_multiple_value_form',
    '#field_name' => $field_name,
    '#cardinality' => $cardinality,
    '#cardinality_multiple' => TRUE,
    '#required' => $this->fieldDefinition
      ->isRequired(),
    '#title' => $this->fieldDefinition
      ->getLabel(),
    '#description' => FieldFilteredMarkup::create(\Drupal::token()
      ->replace($this->fieldDefinition
      ->getDescription())),
    '#max_delta' => count($items) - 1,
    '#prefix' => '<div id="' . $this
      ->getWrapperId() . '">',
    '#suffix' => '</div>',
  ];

  // Add 'add more' button, if not working with a programmed form.
  if (($cardinality === FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED || $field_state['items_count'] < $cardinality) && !$form_state
    ->isProgrammed()) {
    $elements['add_more'] = [
      '#type' => 'container',
      '#tree' => TRUE,
      '#attributes' => [
        'class' => [
          'form--inline',
        ],
      ],
      'new_item' => parent::formElement($items, -1, [], $form, $form_state),
      'submit' => [
        '#type' => 'submit',
        '#name' => strtr($id_prefix, '-', '_') . '_add_more',
        '#value' => $this
          ->t('Add item'),
        '#attributes' => [
          'class' => [
            'field-add-more-submit',
          ],
        ],
        '#limit_validation_errors' => [
          array_merge($parents, [
            $field_name,
          ]),
        ],
        '#submit' => [
          [
            get_class($this),
            'addItemSubmit',
          ],
        ],
        '#ajax' => [
          'callback' => [
            get_class($this),
            'addItemAjax',
          ],
          'wrapper' => $this
            ->getWrapperId(),
          'effect' => 'fade',
        ],
      ],
    ];
  }
  return $elements;
}