10

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?

3
  • 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, 2015 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. Dec 27, 2015 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. Dec 31, 2015 at 11:33

1 Answer 1

18

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.

1
  • That's just what I needed. Dec 30, 2015 at 0:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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