3

I would like to put form fields and submits inside a table (generated with theme_table) of an existing form (callback of a hook_menu entry).

The form_id (container) :

  // Part of the existing form having a $form_id, 
  // where I want to put form elements into a table : 
  ...
  $data = mymodule_get_content_list();

  $form['mymodule_content_list'] = array(
    '#theme' => 'table',
    '#header' => $header,
    '#rows' => $data,
  );

Table builder function :

function mymodule_content_list() {

  ... Running queries to get a $content_list

  $data = array();
  foreach($content_list as $content_data) {
    $operations = array(
      'update' => array(
        '#type' => 'submit',
        '#value' => 'Update',
        '#submit' => array('mymodule_page_edit'),
      ),
    );
    $content = array(
      '#type' => 'textfield',
      '#value' => $content_data->content,
    );
    $data[] = array(
      'content' => drupal_render($content),
      'operations' => drupal_render($operations),
    );
  }

  return $data;

}

With something similar to the above, I currently get the HTML of content textfields and submit buttons in place, but they aren't used as real form elements:

  • When I click the submit above ('Update'), the submit function used is the first declared within the form container but not the declared array('mymodule_page_edit').

  • Using a debugger, I found out that textfields declared in the table's rows aren't passed as $form_state['values'] within the (wrong) submit function.

So the question is, how to insert form elements (fields and submits) into a drupal table, inside of an existing form (hook_menu callback) ? Is it possible ?

2
  • Did you find a solution for this? I'm facing the exact same problem. Aug 9, 2012 at 19:34
  • 1
    Nope, I conclude that it is impossible because it is bad practice, so better find another functional implementation... I'd be glad if somebody come and say otherwise.
    – B2F
    Aug 16, 2012 at 11:05

3 Answers 3

4

Here is sample example where form and tables are used together.

Step1: Gather whole data, going to use in table.

$sample_data = array
(
  array('id' => 1, 'first_name' => 'jay', 'last_name' => 'chris'),
  array('id' => 2, 'first_name' => 'clo', 'last_name' => 'jason'),
  array('id' => 3, 'first_name' => 'len', 'last_name' => 'ken'),
);

Step2: Create table header.

$sample_header = array
(
  'first_name' => t('First Name'),
  'last_name' => t('Last Name'),
);

Step3: Create table rows and columns data.

$options = array();
foreach($sample_data as $data)
{
  $options[$data['id']] = array 
  (
    'first_name' => $data['first_name'], // 'first_name' was the key used in the header
    'last_name' => $data['last_name'], // 'last_Name' was the key used in the header
  );
}

Your data should be something like this:

Array
(
  [1] => Array
  (
    [first_name] => jay
    [last_name] => chris
  )

  [2] => Array
  (
    [first_name] => clo
    [last_name] => jason
  )

  [3] => Array
  (
    [first_name] => len
    [last_name] => ken
  )
)

Step4: Use drupal function(tableselect) for table

$form['table'] = array
(
  '#type' => 'tableselect',
  '#header' => $header,
  '#options' => $options,
);

Here is complete form for you.

function my_form($form, $form_state)
{
  $sample_data = array
  (
      array('id' => 1, 'first_name' => 'jay', 'last_name' => 'chris'),
      array('id' => 2, 'first_name' => 'clo', 'last_name' => 'jason'),
      array('id' => 3, 'first_name' => 'len', 'last_name' => 'ken'),
  );

  $sample_header = array
  (
    'first_name' => t('First Name'),
    'last_name' => t('Last Name'),
  );
  $options = array();
foreach($sample_data as $data)
{
  $options[$data['id']] = array 
  (
    'first_name' => $data['first_name'], // 'first_name' was the key used in the header
    'last_name' => $data['last_name'], // 'last_Name' was the key used in the header
  );
}

  $form['table'] = array
  (
    '#type' => 'tableselect',
    '#header' => $header,
    '#options' => $options,
  );

  $form['submit'] = array
  (
    '#type' => 'submit',
    '#value' => t('Submit'),
  );
  return $form;
}

There can be some TYPO mistake, so do change in code accordingly.

1
  • Here we need to replace '#header' => $header with '#header' => $sample_header
    – parth.k
    Aug 2, 2016 at 13:10
1

You are going about this in the wrong way.

The output of the form (if it needs to look in a specific way) should be handled by a theme function for the form.

You can specify which theme function should be used, by using

$form['#theme'] = 'my_theme_function';

The form callback should handle structuring the different elements.

In your theme function to can render each form item individually, and thus create a table which contains form elements.

See theme_form for reference on how to create form theme functions and consult the Drupal FAPI for more info on $form['#theme'].

0
0

Drupal doesn't have universal tool for creating tables with inputs/selects/etc.

theme_table is useful only when you want to view static information or links.

Some modules (core modules too) have their own table implementations (as block module), which can have inputs, but these method are individual, and supposed, that each table will be rendered with individual theming function.

Drupal also can't create ajaxed sort/pager links.

So.. I've spent a lot of time to create solution.

https://github.com/player259/ajax_table

Not well documented, but there is a demo module. I'm using this module every time, when I need table element, just for sure that Forms API will work as expected.

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.