Same name and namespace in other branches
  1. 8.9.x core/lib/Drupal/Core/Render/Element/Table.php \Drupal\Core\Render\Element\Table::preRenderTable()
  2. 9 core/lib/Drupal/Core/Render/Element/Table.php \Drupal\Core\Render\Element\Table::preRenderTable()

#pre_render callback to transform children of an element of #type 'table'.

This function converts sub-elements of an element of #type 'table' to be suitable for table.html.twig:

  • The first level of sub-elements are table rows. Only the #attributes property is taken into account.
  • The second level of sub-elements is converted into columns for the corresponding first-level table row.

Simple example usage:

$form['table'] = array(
  '#type' => 'table',
  '#header' => array(
    $this
      ->t('Title'),
    array(
      'data' => $this
        ->t('Operations'),
      'colspan' => '1',
    ),
  ),
  // Optionally, to add tableDrag support:
  '#tabledrag' => array(
    array(
      'action' => 'order',
      'relationship' => 'sibling',
      'group' => 'thing-weight',
    ),
  ),
);
foreach ($things as $row => $thing) {
  $form['table'][$row]['#weight'] = $thing['weight'];
  $form['table'][$row]['title'] = array(
    '#type' => 'textfield',
    '#default_value' => $thing['title'],
  );

  // Optionally, to add tableDrag support:
  $form['table'][$row]['#attributes']['class'][] = 'draggable';
  $form['table'][$row]['weight'] = array(
    '#type' => 'textfield',
    '#title' => $this
      ->t('Weight for @title', array(
      '@title' => $thing['title'],
    )),
    '#title_display' => 'invisible',
    '#size' => 4,
    '#default_value' => $thing['weight'],
    '#attributes' => array(
      'class' => array(
        'thing-weight',
      ),
    ),
  );

  // The amount of link columns should be identical to the 'colspan'
  // attribute in #header above.
  $form['table'][$row]['edit'] = array(
    '#type' => 'link',
    '#title' => $this
      ->t('Edit'),
    '#url' => Url::fromRoute('entity.test_entity.edit_form', [
      'test_entity' => $row,
    ]),
  );
}

Parameters

array $element: A structured array containing two sub-levels of elements. Properties used:

  • #tabledrag: The value is a list of $options arrays that are passed to drupal_attach_tabledrag(). The HTML ID of the table is added to each $options array.

Return value

array

See also

template_preprocess_table()

\Drupal\Core\Render\AttachmentsResponseProcessorInterface::processAttachments()

drupal_attach_tabledrag()

File

core/lib/Drupal/Core/Render/Element/Table.php, line 391

Class

Table

Namespace

Drupal\Core\Render\Element

Code

public static function preRenderTable($element) {
  foreach (Element::children($element) as $first) {
    $row = [
      'data' => [],
    ];

    // Apply attributes of first-level elements as table row attributes.
    if (isset($element[$first]['#attributes'])) {
      $row += $element[$first]['#attributes'];
    }

    // Turn second-level elements into table row columns.
    // @todo Do not render a cell for children of #type 'value'.
    // @see https://www.drupal.org/node/1248940
    foreach (Element::children($element[$first]) as $second) {

      // Assign the element by reference, so any potential changes to the
      // original element are taken over.
      $column = [
        'data' => &$element[$first][$second],
      ];

      // Apply wrapper attributes of second-level elements as table cell
      // attributes.
      if (isset($element[$first][$second]['#wrapper_attributes'])) {
        $column += $element[$first][$second]['#wrapper_attributes'];
      }
      $row['data'][] = $column;
    }
    $element['#rows'][] = $row;
  }

  // Take over $element['#id'] as HTML ID attribute, if not already set.
  Element::setAttributes($element, [
    'id',
  ]);

  // Add sticky headers, if applicable.
  if (count($element['#header']) && $element['#sticky']) {
    $element['#attached']['library'][] = 'core/drupal.tableheader';

    // Add 'sticky-enabled' class to the table to identify it for JS.
    // This is needed to target tables constructed by this function.
    $element['#attributes']['class'][] = 'sticky-enabled';
  }

  // If the table has headers and it should react responsively to columns hidden
  // with the classes represented by the constants RESPONSIVE_PRIORITY_MEDIUM
  // and RESPONSIVE_PRIORITY_LOW, add the tableresponsive behaviors.
  if (count($element['#header']) && $element['#responsive']) {
    $element['#attached']['library'][] = 'core/drupal.tableresponsive';

    // Add 'responsive-enabled' class to the table to identify it for JS.
    // This is needed to target tables constructed by this function.
    $element['#attributes']['class'][] = 'responsive-enabled';
  }

  // If the custom #tabledrag is set and there is an HTML ID, add the table's
  // HTML ID to the options and attach the behavior.
  if (!empty($element['#tabledrag']) && isset($element['#attributes']['id'])) {
    foreach ($element['#tabledrag'] as $options) {
      $options['table_id'] = $element['#attributes']['id'];
      drupal_attach_tabledrag($element, $options);
    }
  }
  return $element;
}