You are here

protected static function WebformMultiple::buildElementRow in Webform 8.5

Same name and namespace in other branches
  1. 6.x src/Element/WebformMultiple.php \Drupal\webform\Element\WebformMultiple::buildElementRow()

Build a single element row.

Parameters

string $table_id: The element's table id.

int $row_index: The row index.

array $element: The element.

string $default_value: The default value.

int $weight: The weight.

array $ajax_settings: An array containing Ajax callback settings.

Return value

array A render array containing inputs for an element's value and weight.

1 call to WebformMultiple::buildElementRow()
WebformMultiple::processWebformMultiple in src/Element/WebformMultiple.php
Process items and build multiple elements widget.

File

src/Element/WebformMultiple.php, line 572

Class

WebformMultiple
Provides a webform element to assist in creation of multiple elements.

Namespace

Drupal\webform\Element

Code

protected static function buildElementRow($table_id, $row_index, array $element, $default_value, $weight, array $ajax_settings) {
  if ($element['#child_keys']) {
    static::setElementRowDefaultValueRecursive($element['#element'], (array) $default_value);
  }
  else {
    static::setElementDefaultValue($element['#element'], $default_value);
  }
  $hidden_elements = [];
  $row = [];
  if ($element['#sorting']) {
    $row['_handle_'] = [
      '#wrapper_attributes' => [
        'class' => [
          'webform-multiple-table--handle',
        ],
      ],
    ];
  }
  if ($element['#child_keys'] && !empty($element['#header'])) {

    // Set #parents which is used for nested elements.
    // @see \Drupal\webform\Element\WebformMultiple::setElementRowParentsRecursive
    $parents = array_merge($element['#parents'], [
      'items',
      $row_index,
    ]);
    $hidden_parents = array_merge($element['#parents'], [
      'items',
      $row_index,
      '_hidden_',
    ]);
    foreach ($element['#child_keys'] as $child_key) {

      // Store hidden element in the '_handle_' column.
      // @see \Drupal\webform\Element\WebformMultiple::convertValuesToItems
      if (static::isHidden($element['#element'][$child_key])) {
        $hidden_elements[$child_key] = $element['#element'][$child_key];

        // ISSUE:
        // All elements in _handle_ with #access: FALSE are losing
        // their values.
        //
        // Moving these #access: FALSE and value elements outside of the
        // table does not work. What is even move baffling is manually adding
        // a 'value' element does work.
        //
        // $element['hidden'][$row_index][$child_key] = $element['#element'][$child_key];
        // $element['hidden'][1000]['test'] = ['#type' => 'value', '#value' => 'test'];
        //
        // WORKAROUND:
        // Convert element to rendered hidden element.
        if (Element::isVisibleElement($element)) {
          $hidden_elements[$child_key]['#type'] = 'hidden';

          // Unset #access, #element_validate, and #pre_render.
          // @see \Drupal\webform\Plugin\WebformElementBase::prepare()
          // Unset #options to prevent An illegal choice has been detected.
          // @see \Drupal\Core\Form\FormValidator::performRequiredValidation
          unset($hidden_elements[$child_key]['#access'], $hidden_elements[$child_key]['#element_validate'], $hidden_elements[$child_key]['#pre_render'], $hidden_elements[$child_key]['#options']);
        }
        static::setElementRowParentsRecursive($hidden_elements[$child_key], $child_key, $hidden_parents);
      }
      else {
        $row[$child_key] = $element['#element'][$child_key];
        static::setElementRowParentsRecursive($row[$child_key], $child_key, $parents);
      }
    }
  }
  else {
    $row['_item_'] = $element['#element'];
  }
  if ($element['#sorting']) {
    $row['weight'] = [
      '#type' => 'weight',
      '#delta' => 1000,
      '#title' => t('Item weight'),
      '#title_display' => 'invisible',
      '#attributes' => [
        'class' => [
          'webform-multiple-sort-weight',
        ],
      ],
      '#wrapper_attributes' => [
        'class' => [
          'webform-multiple-table--weight',
        ],
      ],
      '#default_value' => $weight,
    ];
  }

  // Allow users to add & remove rows if cardinality is not set.
  if ($element['#operations']) {
    $row['_operations_'] = [
      '#wrapper_attributes' => [
        'class' => [
          'webform-multiple-table--operations',
        ],
      ],
    ];
    if ($element['#add'] && $element['#remove']) {
      $row['_operations_']['#wrapper_attributes']['class'][] = 'webform-multiple-table--operations-two';
    }
    if ($element['#add']) {
      $row['_operations_']['add'] = [
        '#type' => 'image_button',
        '#title' => t('Add new @item after @item @number', [
          '@number' => $row_index + 1,
          '@item' => $element['#item_label'],
        ]),
        '#src' => drupal_get_path('module', 'webform') . '/images/icons/plus.svg',
        '#limit_validation_errors' => [],
        '#submit' => [
          [
            get_called_class(),
            'addItemSubmit',
          ],
        ],
        '#ajax' => $ajax_settings,
        // Issue #1342066 Document that buttons with the same #value need a unique
        // #name for the Form API to distinguish them, or change the Form API to
        // assign unique #names automatically.
        '#row_index' => $row_index,
        '#name' => $table_id . '_add_' . $row_index,
      ];
    }
    if ($element['#remove']) {
      $row['_operations_']['remove'] = [
        '#type' => 'image_button',
        '#title' => t('Remove @item @number', [
          '@number' => $row_index + 1,
          '@item' => $element['#item_label'],
        ]),
        '#src' => drupal_get_path('module', 'webform') . '/images/icons/minus.svg',
        '#limit_validation_errors' => [],
        '#submit' => [
          [
            get_called_class(),
            'removeItemSubmit',
          ],
        ],
        '#ajax' => $ajax_settings,
        // Issue #1342066 Document that buttons with the same #value need a unique
        // #name for the Form API to distinguish them, or change the Form API to
        // assign unique #names automatically.
        '#row_index' => $row_index,
        '#name' => $table_id . '_remove_' . $row_index,
      ];
    }
  }

  // Add hidden element as a hidden row.
  if ($hidden_elements) {
    $row['_hidden_'] = $hidden_elements + [
      '#wrapper_attributes' => [
        'style' => 'display: none',
      ],
    ];
  }
  if ($element['#sorting']) {
    $row['#attributes']['class'][] = 'draggable';
    $row['#weight'] = $weight;
  }
  return $row;
}