I am trying to setup my form to be in a table layout. It is has some layers of collapsible fieldsets, so I am not able to get the theme function to work. Perhaps someone can help me.

...//function theme_course_type_form
  This is what my header should have in it.
  $form['header'] = array(
    '#type' => 'value',
    '#value' => array(
      array('data' => t('Name)),
      array('data' => t('Radio 1')),
      array('data' => t('Radio 2')),
      array('data' => t('Radio 3')),
    )
  );
  //Here are the radio buttons and the title information that I need
  $form['foo'][$bar][$foobar] = array(
     '#type' => 'radios',
     '#default_value' => $default,
     '#title' => t($name),
     '#options' => $options,
   );
...

function theme_course_type_form($form) {
  $output = '';
  foreach (element_children($form['foo']) as $key) {
    $rows = null;
    foreach(element_children($form['foo'][$key]) as $child) {
      $row = array();
      $row['data'][0] = drupal_render($form['foo'][$key][$child]['#title']);
      $row['data'][1] = drupal_render($form['foo'][$key][$child][0]);
      $row['data'][2] = drupal_render($form['foo'][$key][$child][1]);
      $row['data'][3] = drupal_render($form['foo'][$key][$child][2]);
      $rows[] = $row;
    }
    $output .= drupal_render(theme('table', $form['header']['#value'], $rows));
  }
  $output .= drupal_render($form);
  return $output;
}

The problem here is that I am getting the '#title' value to appear, but none of the radio buttons are appearing. Also, the menu values are not appearing. I am not sure what the problem is and I can't seem to figure out what is going on. I am definitely grabbing the radio buttons and they are getting placed in the array, but for some reason they are not being put in the table, and in the end not being placed on the screen. Any suggestions on how to correct this would be much appreciated. Let me know if you have any questions as well.

Comments

nevets’s picture

First there is no reason to place the table header in the form, you can more simply just create the approriate array in the theme function.

If you disable the theme function (either comment out or change the name temporyly does the form show correctly?

Lines that start like $row['data'][0] are wrong. They can simply start with $row[] (the 'data' will cause problems and ther e is no need for explicit indexs)

It would also appear you are trying to split up the radio buttons into multiple table cells and that is not going to work the way you are doing it. While $form['foo'][$key][$child] is an array it does not have elements indexed by 0, 1 or 2 but '#type' ect.

j_ten_man’s picture

The form does show up correctly when the theme function is turned off.

Regarding the indexes, $form['foo'][$key][$child][0], etc, that is working because those are radio buttons that have the values 0, 1, and 2. It is grabbing those radio buttons and using them as I'd expect.

Here is the code that I now have in the theme function:

function theme_course_type_form($form) {
  $output = '';
  foreach (element_children($form['foo']) as $key) {
    $rows = null;
    foreach(element_children($form['foo'][$key]) as $child) {
      $row = array();
      $row['data'][0] = $form['foo'][$key][$child]['#title'];
      $row['data'][1] = drupal_render($form['foo'][$key][$child][0]);
      $row['data'][2] = drupal_render($form['foo'][$key][$child][1]);
      $row['data'][3] = drupal_render($form['foo'][$key][$child][2]);
      $rows[] = $row;
      drupal_render($form['foo'][$key][$child]);
    }
    $output .= theme('table', $form['header']['#value'], $rows);
  }
  $output.= drupal_render($form);
  return $output;
}

This is almost working. It is creating the tables as needed. The problem is that each table should be in a collapsible fieldset. They are not. All of the collapsible fieldsets are at the bottom of the page, and they are all empty. I have tried different things, but I can't get the table in the fieldset. I will try some of your suggesstions, but I am beginning to think that it is not possible to put tables inside of collapsible fields.

nevets’s picture

The last call to drupal_render($form) is what renders the fieldsets and what makes them last. They are empty because you have all ready rendered the form elements that where inside them (effectively removing them from the fieldset). So what I think you want to do is change this line

$output .= theme('table', $form['header']['#value'], $rows);

to something like

$form['foo'][$key][???] = theme('table', $form['header']['#value'], $rows);

The point being to output the table to the "value" part of the fieldset. Using '#value' may work, but I am not sure.

j_ten_man’s picture

That is a good thought. I tried that, but it doesn't work. I printed out the $form['foo'][$key] element and it is an array (obviously) I thus tried to do the following to get it to work:

$form['foo'][$key] = array (
	  '#type' => $form['foo'][$key]['#type'],
	  '#collapsible' => $form['foo'][$key]['#collapsible'],
	  '#collapsed' => $form['foo'][$key]['#collapsed'],
	  '#title' => $form['foo'][$key]['#title'],
	  theme('table', $header, $rows)
	  );
    $output .= drupal_render($form['foo'][$key]);

The problem is that the tables don't show up. The reason I created the array like this is because that is exactly how it showed up when I printed it up. Does someone know how to add the value to the fieldset?

nevets’s picture

Change the current $output .= theme('table', $form['header']['#value'], $rows); line to

$form['foo'][$key]['table'] = array(
  '#type' => 'markup',
  '#value' =>theme('table', $form['header']['#value'], $rows)
);

(no need to add any calls to drupal_render(), the call at the end of the function will handle rendering the fieldsets)

j_ten_man’s picture

Thank you so much. That worked perfect. Here is the final theme function:

function theme_course_type_form($form) {
  $output = '';
  $header = array(
          array('data' => t('Title')),
          array('data' => t('Radio 1')),
          array('data' => t('Radio 2')),
          array('data' => t('Radio 3')),
        );
  foreach (element_children($form['foo']) as $key) {
    $rows = null;
    foreach(element_children($form['foo'][$key]) as $child) {
      $row = array();
      $row['data'][0] = $form['foo'][$key][$child]['#title'];
      $row['data'][1] = drupal_render($form['foo'][$key][$child][0]);
      $row['data'][2] = drupal_render($form['foo'][$key][$child][1]);
      $row['data'][3] = drupal_render($form['foo'][$key][$child][2]);
      $rows[] = $row;
      drupal_render($form['foo'][$key][$child]);
    }
    $form['foo'][$key]['table'] = array(
      '#type' => 'markup',
      '#value' =>theme('table', $header, $rows)
    );
  }
  $output.= drupal_render($form); 
  return $output;
}
fmitchell’s picture

The formtable module (5.x); build your form as needed.

--
Fredric
http://brightplum.com

fngatia’s picture

@j_ten_man I can confirm that this works.