In my module I am building a page in the settings portion. There is a form on this page, then under it I want a table that will list existing entries belonging to the particular setting.

At the end of each row I want to offer a button that would be used to delete the item in that row. It would also need to confirm that the person wants to delete the item.

I'm seeing some examples on how people are building these tables, but I am confused, plus feeling further bewildered at what appears to be a convoluted way of presenting something as simple as what I have described.

Can someone clarify the steps for what I need to do to make this happen? You don't need to provide code, unless you are so inclined. I just need to know how the steps on how to accomplish this.

Meanwhile, I'll keep coding-away and trying to figure this out. I just hate having to write long code to do the simple stuff. :)

CJ

Comments

pixelsweatshop’s picture

[deleted]

Jaypan’s picture

It's not as easy as you would probably like. You need to create your elements (essentially your table cells) in your form definition, then use a theme function to create your table. You'll also need to register your theme in hook_theme(). Here's a simple example:

function mymodule_myform($form, &$form_state)
{
  $form['table_container'] = array
  (
    '#theme' => 'mymodule_myform_table',
    // Need to set #tree to be able to differentiate
    // between the various delete buttons upon
    // submission.
    '#tree' => TRUE,
  );
  for($i = 0; $i < 10; $i++)
  {
    $form['table_container'][$i]['column1'] = array
    (
      '#markup' => t('Column 1 value !index', array('!index' => $i)),
    );
    $form['table_container'][$i]['column2'] = array
    (
      '#markup' => t('Column 2 value !index', array('!index' => $i)),
    );
    $form['table_container'][$i]['column3'] = array
    (
      '#markup' => t('Column 3 value !index', array('!index' => $i)),
    );
    $form['table_container'][$i]['delete'] = array
    (
      '#type' => 'submit',
      '#value' => t('Delete'),
      // Setting '#name' is required, and must be unique
      '#name' => 'mymodule_myform_delete_' . $i,
    );
  }

  return $form;
}

Need to register the theme 'mymodule_myform_table' in hook_theme():

function mymodule_theme()
{
  $theme['mymodule_myform_table'] = array
  (
    '#render element' => 'form',
  );
  return $theme;
}

Note - clear your cache.

Finally, the theme function:

function theme_mymodule_myform_table($variables)
{
  // Note: $form will be $form['table_container'] from your
  // form definition, as that is the element that #theme was
  // applied to.
  $form = $variables['form'];

  // Define our $header and $rows variables
  $header = array(t('Column 1'), t('Column 2'), t('Column 3'), t('Delete'));
  $rows = array();

  // We need to loop through each of the renderable elements
  // in the $form array. Renderable elements are those that are
  // not prefixed with the # symbol. For example, one of the elements
  // of the $form element will be #theme, but we don't want to loop
  // through that. The function element_children() gives us the renderable
  // elements of an array
  foreach(element_children($form) as $index))
  {
    // Declare a new row
    $row = array();
    // Populate the row
    $row[] = drupal_render($form[$index]['column1']);
    $row[] = drupal_render($form[$index]['column2']);
    $row[] = drupal_render($form[$index]['column3']);
    $row[] = drupal_render($form[$index]['delete']);

    // Add our $row to the $rows array
    $rows[] = $row;
  }

  // Return the themed table:
  return theme('table', array('header' => $header, 'rows' => $rows);
}

Note - not checked. May contain typos.

Dor@’s picture

Can this be changed to work with an unknown number of elements which will be changed possibly after each callback? I'm trying to set a var with 

$form_state['storage']['number_of_results'] = $count;

but it doesn't work as planned.

Jaypan’s picture

Yes, it is possible to make the number of elements dynamic. You just have to store the count as you are doing, and use that as a reference.

Dor@’s picture

..so I return the table from an ajax callback after I query the db 

just_jordan’s picture

is this the only way still?

Clinkk’s picture

Just wondering how you would access the fields within the submit function for each specific button, as there is no way to pass over the specific $i value you need to access the specific button. Is there any fix to this?