Last updated December 12, 2012. Created by druderman on December 12, 2012.
Log in to edit this page.

If you have several repeating fields in fieldsets in your webform, you may want to render these in a HTML table with the header along the first row or first column.

Here's a recipe to do so adapted from this post http://1013.fi/cms/theming-drupal-web-forms

Declare your formatting functions in a file called 'form-formatting-helpers.php' which you should copy to a subdirectory under your themes directory. For example:

/sites/default/themes/mytheme/webform_templates/form-formatting-helpers.php

<?php
// By David Ruderman druderman@admin.umass.edu
// adapted from http://1013.fi/cms/theming-drupal-web-forms
/**
* Replace a form fieldset (group) by a table formatted as:
* +----------+--------------+--------------+
* |          | name         | ssn          |
* +----------+--------------+--------------+
* | spouse   | [input /]    | [input /]    |
* +----------+--------------+--------------+
* | another  | [input /]    | [input /]    |
* | fieldset |              |              |
* +----------+--------------+--------------+
*
*
* @param $group - reference to the fieldset
* @param $label_rows - if true, rows have leading label column
*/
function fieldset_subfieldsets_to_table( &$group, $label_rows=FALSE ) {
   
// confirm we get fieldsets, not form elements nor type-less elements behind page break
   
if( empty( $group['#type'] ) || $group['#type'] != 'fieldset' ) {
        return;
    }
   
$rows = array();
   
$header = array();
    if (
$label_rows) {
       
$header[] = '';
    }
   
$children = element_children( $group );
   
// use label of first child as source for table headers
   
foreach ($children as $child){
       
$first_child = $child;
        break;
    }
    if (!empty(
$first_child) && isset($group[$first_child])) {
        foreach(
element_children($group[$first_child]) as $form_field_name) {
           
$header[] = $group[$first_child][$form_field_name]['#title'];
        }
    }
    foreach(
$children as $group_name ) { // for each subfieldset
       
$row = array( 'data' => array() );
        if (
$label_rows) {
            if (
'none' === $group[$group_name]['#title_display']) {
               
$row['data'][0] = array();
            } else {
               
$row['data'][0] = array( // header cell's content lives in data
                   
'data' => $group[$group_name]['#title'],
                   
'class' => 'label_cell'
               
);
            }
        }
        foreach(
element_children( $group[$group_name] ) as $form_field_name ) {
           
$row['data'][] = render_titleless( $group[$group_name][$form_field_name] );
        }
       
drupal_render($group[$group_name]); //  sub-fieldset rendered it into void
       
$rows[] = $row;
    }
   
$group['table'] = array(
       
'#type' => 'markup',
       
'#markup' => theme('table', array('header'=>$header, 'rows'=>$rows)),
    );
}
/**
* Replace a form fieldset (group) by a table formatted as:
* +----------+--------------+--------------+--------------+
* |          | Person 1     | Person 2     | Person 3     |
* +----------+--------------+--------------+--------------+
* | name     | [input /]    | [input /]    | [input /]    |
* +----------+--------------+--------------+--------------+
* | ssn      | [input /]    | [input /]    | [input /]    |
* +----------+--------------+--------------+--------------+
*
*
* @param $group - reference to the fieldset
*/
function fieldset_subfieldsets_to_table_vertical( &$group) {
   
// confirm we get fieldsets, not form elements nor type-less elements behind page break
   
if( empty( $group['#type'] ) || $group['#type'] != 'fieldset' ) {
        return;
    }
   
$rows = array();
   
$header = array('');
   
$children = element_children( $group );
   
// foreach child fieldset
   
foreach( $children as $group_name ) { // for each subfieldset
        // append fieldset name to header
       
if ('none' === $group[$group_name]['#title_display']) {
           
$header[] = array();
        } else {
           
$header[] = array( // header cell's content lives in data
               
'data' => $group[$group_name]['#title'],
               
'class' => 'label_cell'
           
);
        }
    }
   
// find first child
   
foreach ($children as $child){
       
$first_child = $child;
        break;
    }   
    if (!empty(
$first_child) && isset($group[$first_child])) {
       
// foreach field in first child fieldset
       
foreach(element_children($group[$first_child]) as $form_field_name) {
           
// create row
           
$row = array( 'data' => array() );
           
// append field name to row
           
$row['data'][0] = array( // header cell's content lives in data
               
'data' => $group[$group_name][$form_field_name]['#title'],
               
'class' => 'label_cell'
           
);
           
// foreach child
           
foreach( $children as $child ) {
               
// append rendered field to row
               
$row['data'][] = render_titleless( $group[$child][$form_field_name] );
               
drupal_render($group[$child][$form_field_name]); //  sub-fieldset rendered it into void
           
}
           
// append row to rows
           
$rows[] = $row;
        }
    }
   
// foreach child
   
foreach( $children as $child ) {
       
drupal_render($group[$child]); //  sub-fieldset rendered it into void
   
}
   
// theme rows as table
   
$group['table'] = array(
       
'#type' => 'markup',
       
'#markup' => theme('table', array('header'=>$header, 'rows'=>$rows)),
    );
}
// helper function to remove header prior rendering form element
function render_titleless( $el ) {
    unset(
$el['#title'] ); // title already in header, don't repeat in cell
   
return drupal_render( $el ); // returns field without label
}
?>

In this same directory you can copy the default webform-form.tpl.php file from the webform module directory. Rename it to include the ID of your webform. For example here the webform ID is '12'.:

/sites/default/themes/mytheme/webform_templates/webform-form-12.tpl.php

Assuming that the parent field you wish to render as a table on your webform has machine name of 'section_information', edit the new template file and modify as below.

<?php
include_once( 'form-formatting-helpers.php' );
// If editing or viewing submissions, display the navigation at the top.
if (isset($form['section_information']) || isset($form['navigation'])) {
    print
drupal_render($form['navigation']);
    print
drupal_render($form['section_information']);
}
// Print out the main part of the form.
fieldset_subfieldsets_to_table( $form['submitted']['section_information']);
// Print out the main part of the form.
// Feel free to break this up and move the pieces within the array.
print drupal_render($form['submitted']);
// Always print out the entire $form. This renders the remaining pieces of the
// form that haven't yet been rendered above.
print drupal_render_children($form);
// Print out the navigation again at the bottom.
if (isset($form['section_information']) || isset($form['navigation'])) {
    unset(
$form['navigation']['#printed']);
    print
drupal_render($form['navigation']);
}
?>

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.