You are here

public static function YamlFormMultiple::processYamlFormMultiple in YAML Form 8

Process items and build multiple elements widget.

File

src/Element/YamlFormMultiple.php, line 62

Class

YamlFormMultiple
Provides a form element to assist in creation of multiple elements.

Namespace

Drupal\yamlform\Element

Code

public static function processYamlFormMultiple(&$element, FormStateInterface $form_state, &$complete_form) {
  $element['#tree'] = TRUE;

  // Add validate callback that extracts the array of items.
  $element['#element_validate'] = [
    [
      get_called_class(),
      'validateYamlFormMultiple',
    ],
  ];

  // Wrap this $element in a <div> that handle #states.
  YamlFormElementHelper::fixStatesWrapper($element);
  if ($element['#cardinality']) {

    // If the cardinality is set limit number of items to this value.
    $number_of_items = $element['#cardinality'];
  }
  else {

    // Get unique key used to store the current number of items.
    $number_of_items_storage_key = self::getStorageKey($element, 'number_of_items');

    // Store the number of items which is the number of
    // #default_values + number of empty_items.
    if ($form_state
      ->get($number_of_items_storage_key) === NULL) {
      if (empty($element['#default_value']) || !is_array($element['#default_value'])) {
        $number_of_default_values = 0;
        $number_of_empty_items = (int) $element['#empty_items'];
      }
      else {
        $number_of_default_values = count($element['#default_value']);
        $number_of_empty_items = 1;
      }
      $form_state
        ->set($number_of_items_storage_key, $number_of_default_values + $number_of_empty_items);
    }
    $number_of_items = $form_state
      ->get($number_of_items_storage_key);
  }
  $table_id = implode('_', $element['#parents']) . '_table';

  // DEBUG: Disable AJAX callback by commenting out the below callback and
  // wrapper.
  $ajax_settings = [
    'callback' => [
      get_called_class(),
      'ajaxCallback',
    ],
    'wrapper' => $table_id,
  ];
  $element['#child_keys'] = Element::children($element['#element']);

  // Build (single) element header.
  $header = self::buildElementHeader($element);

  // Build (single) element rows.
  $row_index = 0;
  $weight = 0;
  $rows = [];
  if (!$form_state
    ->isProcessingInput() && isset($element['#default_value']) && is_array($element['#default_value'])) {
    foreach ($element['#default_value'] as $default_value) {
      $rows[$row_index] = self::buildElementRow($table_id, $row_index, $element, $default_value, $weight++, $ajax_settings);
      $row_index++;
    }
  }
  while ($row_index < $number_of_items) {
    $rows[$row_index] = self::buildElementRow($table_id, $row_index, $element, NULL, $weight++, $ajax_settings);
    $row_index++;
  }

  // Build table.
  $element['items'] = [
    '#prefix' => '<div id="' . $table_id . '" class="yamlform-multiple-table">',
    '#suffix' => '</div>',
    '#type' => 'table',
    '#header' => $header,
    '#tabledrag' => [
      [
        'action' => 'order',
        'relationship' => 'sibling',
        'group' => 'yamlform-multiple-sort-weight',
      ],
    ],
  ] + $rows;

  // Build add items actions.
  if (empty($element['#cardinality'])) {
    $element['add'] = [
      '#prefix' => '<div class="container-inline">',
      '#suffix' => '</div>',
    ];
    $element['add']['submit'] = [
      '#type' => 'submit',
      '#value' => t('Add'),
      '#limit_validation_errors' => [],
      '#submit' => [
        [
          get_called_class(),
          'addItemsSubmit',
        ],
      ],
      '#ajax' => $ajax_settings,
      '#name' => $table_id . '_add',
    ];
    $element['add']['more_items'] = [
      '#type' => 'number',
      '#min' => 1,
      '#max' => 100,
      '#default_value' => $element['#add_more'],
      '#field_suffix' => t('more @labels', [
        '@labels' => $element['#labels'],
      ]),
    ];
  }
  $element['#attached']['library'][] = 'yamlform/yamlform.element.multiple';
  return $element;
}