7

I'm using the Drupal 8 #table element to populate a table on my form, and it's working great for displaying static data.

foreach ($entries = getData() as $entry) {
  $row = array_map('Drupal\Component\Utility\SafeMarkup::checkPlain', $entry);
  $rows[] = $row;
}
$form['table'] = array(
  '#type' => 'table',
  '#header' => $headers,
  '#rows' => $rows,
  '#attributes' => array('id' => 'my-module-list'),
  '#empty' => t('No entries available.'),
);

However, I would like to embed a control in each row of the table, for example:

foreach ($entries = getData() as $entry) {
  $row = array_map('Drupal\Component\Utility\SafeMarkup::checkPlain', $entry);
  $row["field_name"] = array(
    '#type' => 'textbox',
  );
  $rows[] = $row;
}
//dpm($rows);
$form['table'] = array(
  '#type' => 'table',
  '#header' => $headers,
  '#rows' => $rows,
  '#attributes' => array('id' => 'my-module-list'),
  '#empty' => t('No entries available.'),
);  

However, the #textbox field is currently being ignored, and an empty cell is shown in its place.

Is there a way I can embed fields in a Drupal generated table, or do I need to build my own table from scratch?

  • a) do not use #rows in form. Each child element of #table element is a row and each child element of that row is a table cell. b) #textbox does not exist in Drupal core. Maybe you mean #textfield? – user21641 Dec 27 '15 at 10:14
  • Thanks for the comments. a) The function getData reads a database table and returns an array of objects. The array_map converts the object into an array of safely marked up data, so $rows is an array of arrays. b) My mistake. I've tried several element types, but they just become attributes of the td tag. For example "<td #type="textfield"></td>". My suspicion is that embedding form controls in the table isn't supported. – James Shields Dec 27 '15 at 15:00
  • 1
    I understand what you're saying now. The #rows element gets converted into a table of plain text cells when the table is rendered. To put controls in the table, put the rows as direct elements of the #table array. Everything in the table then gets treated as a control, so plain text cells have to have a #markup entry. – James Shields Dec 31 '15 at 11:33
12

It is no problem to put form elements in a table. See the example in core/lib/Drupal/Core/Render/Element/Table.php:

$form['contacts'] = array(
    '#type' => 'table',
    '#title' => 'Sample Table',
    '#header' => array('Name', 'Phone'),
  );

  for ($i=1; $i<=4; $i++) {
    $form['contacts'][$i]['name'] = array(
      '#type' => 'textfield',
      '#title' => t('Name'),
      '#title_display' => 'invisible',
    );

    $form['contacts'][$i]['phone'] = array(
      '#type' => 'tel',
      '#title' => t('Phone'),
      '#title_display' => 'invisible',
    );
  }

Maybe you should start from here and then put step by step your code in this example and see when it breaks.

  • That's just what I needed. – James Shields Dec 30 '15 at 0:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.