From 3e49eeb716eb609ebb9a8c35df1ee9c90b699859 Mon Sep 17 00:00:00 2001
From: Lee Rowlands <lee.rowlands@previousnext.com.au>
Date: Fri, 22 Dec 2023 14:48:27 +1000
Subject: [PATCH] Issue #3071143 by KarimB, samsylve, smustgrave, quietone:
 Table Render Array Documention Is incomplete and confusing

---
 core/lib/Drupal/Core/Render/Element/Table.php | 76 ++++++++++++++++---
 1 file changed, 64 insertions(+), 12 deletions(-)

diff --git a/core/lib/Drupal/Core/Render/Element/Table.php b/core/lib/Drupal/Core/Render/Element/Table.php
index ef650c9df619..f55572e5f225 100644
--- a/core/lib/Drupal/Core/Render/Element/Table.php
+++ b/core/lib/Drupal/Core/Render/Element/Table.php
@@ -24,34 +24,86 @@
  *   providing responsive tables.  Defaults to TRUE.
  * - #sticky: Indicates whether to add the drupal.tableheader library that makes
  *   table headers always visible at the top of the page. Defaults to FALSE.
+ * - #footer: Table footer rows, in the same format as the #rows property.
+ * - #caption: A localized string for the <caption> tag.
  *
- * Usage example:
+ * Usage example 1: A simple form with an additional information table which
+ * doesn't include any other form field.
  * @code
- * $form['contacts'] = array(
+ * // Table header.
+ * $header = [
+ *   'name' => $this->t('Name'),
+ *   'age' => $this->t('Age'),
+ *   'email' => $this->t('Email'),
+ * ];
+ *
+ * // Default data rows (these can be fetched from the database or any other
+ * // source).
+ * $default_rows = [
+ *   ['name' => 'John', 'age' => 28, 'email' => 'john@example.com'],
+ *   ['name' => 'Jane', 'age' => 25, 'email' => 'jane@example.com'],
+ * ];
+ *
+ * // Prepare rows for the table element. We just display the information with
+ * // #markup.
+ * $rows = [];
+ * foreach ($default_rows as $default_row) {
+ *   $rows[] = [
+ *     'name' => ['data' => ['#markup' => $default_row['name']]],
+ *     'age' => ['data' => ['#markup' => $default_row['age']]],
+ *     'email' => ['data' => ['#markup' => $default_row['email']]],
+ *   ];
+ * }
+ *
+ * // Now set the table element.
+ * $form['information'] = [
+ *   '#type' => 'table',
+ *   '#header' => $header,
+ *   '#rows' => $rows,  // Add the prepared rows here.
+ *   '#empty' => $this->t('No entries available.'),
+ * ];
+ * @endcode
+ *
+ * Usage example 2: A table of form fields without the #rows property defined.
+ * @code
+ * // Set the contact element as a table render element with no #rows property.
+ * // Next add five rows as sub-elements (or children) that will populate
+ * // automatically the #rows property in preRenderTable().
+ * $form['contacts'] = [
  *   '#type' => 'table',
  *   '#caption' => $this->t('Sample Table'),
- *   '#header' => array($this->t('Name'), $this->t('Phone')),
- * );
+ *   '#header' => [$this->t('Name'), $this->t('Phone')],
+ *   '#rows' => [],
+ *   '#empty' => $this->t('No entries available.'),
+ * ];
  *
+ * // Add arbitrarily four rows to the table. Each row contains two fields
+ * // (name and phone). The preRenderTable() method will add each sub-element
+ * // (or children) of the table element to the #rows property.
  * for ($i = 1; $i <= 4; $i++) {
- *   $form['contacts'][$i]['#attributes'] = array('class' => array('foo', 'baz'));
- *   $form['contacts'][$i]['name'] = array(
+ *    // Add foo and baz classes for each row.
+ *   $form['contacts'][$i]['#attributes'] = ['class' => ['foo', 'baz']];
+ *
+ *   // Set the first column.
+ *   $form['contacts'][$i]['name'] = [
  *     '#type' => 'textfield',
  *     '#title' => $this->t('Name'),
  *     '#title_display' => 'invisible',
- *   );
+ *   ];
  *
- *   $form['contacts'][$i]['phone'] = array(
+ *    // Set the second column.
+ *   $form['contacts'][$i]['phone'] = [
  *     '#type' => 'tel',
  *     '#title' => $this->t('Phone'),
  *     '#title_display' => 'invisible',
- *   );
+ *   ];
  * }
  *
- * $form['contacts'][]['colspan_example'] = array(
+ * // Add the fifth row as a colspan of two columns.
+ * $form['contacts'][]['colspan_example'] = [
  *   '#plain_text' => 'Colspan Example',
- *   '#wrapper_attributes' => array('colspan' => 2, 'class' => array('foo', 'bar')),
- * );
+ *   '#wrapper_attributes' => ['colspan' => 2, 'class' => ['foo', 'bar']],
+ * ];
  * @endcode
  * @see \Drupal\Core\Render\Element\Tableselect
  *
-- 
GitLab