protected function WidgetBase::formMultipleElements

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
1 call to WidgetBase::formMultipleElements()
WidgetBase::form in drupal/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php
Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::form().
1 method overrides WidgetBase::formMultipleElements()
FileWidget::formMultipleElements in drupal/core/modules/file/lib/Drupal/file/Plugin/field/widget/FileWidget.php
Overrides \Drupal\field\Plugin\Type\Widget\WidgetBase::formMultipleElements().

File

drupal/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php, line 181
Definition of Drupal\field\Plugin\Type\Widget\WidgetBase.

Class

WidgetBase
Base class for 'Field widget' plugin implementations.

Namespace

Drupal\field\Plugin\Type\Widget

Code

protected function formMultipleElements(EntityInterface $entity, array $items, $langcode, array &$form, array &$form_state) {
  $field = $this->field;
  $instance = $this->instance;
  $field_name = $field['field_name'];
  $parents = $form['#parents'];

  // Determine the number of widgets to display.
  switch ($field['cardinality']) {
    case FIELD_CARDINALITY_UNLIMITED:
      $field_state = field_form_get_state($parents, $field_name, $langcode, $form_state);
      $max = $field_state['items_count'];
      $is_multiple = TRUE;
      break;
    default:
      $max = $field['cardinality'] - 1;
      $is_multiple = $field['cardinality'] > 1;
      break;
  }
  $id_prefix = implode('-', array_merge($parents, array(
    $field_name,
  )));
  $wrapper_id = drupal_html_id($id_prefix . '-add-more-wrapper');
  $title = check_plain($instance['label']);
  $description = field_filter_xss(token_replace($instance['description']));
  $elements = array();
  for ($delta = 0; $delta <= $max; $delta++) {

    // For multiple fields, title and description are handled by the wrapping
    // table.
    $element = array(
      '#title' => $is_multiple ? '' : $title,
      '#description' => $is_multiple ? '' : $description,
    );
    $element = $this
      ->formSingleElement($entity, $items, $delta, $langcode, $element, $form, $form_state);
    if ($element) {

      // Input field for the delta (drag-n-drop reordering).
      if ($is_multiple) {

        // We name the element '_weight' to avoid clashing with elements
        // defined by widget.
        $element['_weight'] = array(
          '#type' => 'weight',
          '#title' => t('Weight for row @number', array(
            '@number' => $delta + 1,
          )),
          '#title_display' => 'invisible',
          // Note: this 'delta' is the FAPI #type 'weight' element's property.
          '#delta' => $max,
          '#default_value' => isset($items[$delta]['_weight']) ? $items[$delta]['_weight'] : $delta,
          '#weight' => 100,
        );
      }
      $elements[$delta] = $element;
    }
  }
  if ($elements) {
    $elements += array(
      '#theme' => 'field_multiple_value_form',
      '#field_name' => $field['field_name'],
      '#cardinality' => $field['cardinality'],
      '#required' => $instance['required'],
      '#title' => $title,
      '#description' => $description,
      '#prefix' => '<div id="' . $wrapper_id . '">',
      '#suffix' => '</div>',
      '#max_delta' => $max,
    );

    // Add 'add more' button, if not working with a programmed form.
    if ($field['cardinality'] == FIELD_CARDINALITY_UNLIMITED && empty($form_state['programmed'])) {
      $elements['add_more'] = array(
        '#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,
            $langcode,
          )),
        ),
        '#submit' => array(
          'field_add_more_submit',
        ),
        '#ajax' => array(
          'callback' => 'field_add_more_js',
          'wrapper' => $wrapper_id,
          'effect' => 'fade',
        ),
      );
    }
  }
  return $elements;
}