theme('table', $headers, $rows) problem in node form
yangke - November 9, 2009 - 03:21
I'm trying to theme a node form with <?php theme('table', $headers, $rows); ?>
the relevant part of hook_form
<?php
foreach ($nodes as $error){ // for each error found in the layout table we create 2 fields;
// Define a fieldset which will contain the form fields for each row/error of the sheet
$iter_error++; // increment the iteration by 1
$form['sheet_wrapper'][$error->nid] = array(
//'#type' => 'fieldset',
'#tree' => TRUE,
'#description' => t($error->title),
'#weight' => $iter_error,
'#theme' => 'sheet_table_edit', // use this theme function to theme this part of the form
//'#prefix' => '<div class="clear-block" id="sheet-error">',
//'#suffix' => '</div>',
);
// create the link
$form['sheet_wrapper'][$error->nid]['name'] = array(
'#prefix' => '<a href="../' .$error->nid .'">',
'#value' => t($error->title),
'#suffix' => '</a>',
);
$form['sheet_wrapper'][$error->nid]['amount'] = array(
'#type' => 'textfield',
'#title' => t('amount'),
'#size' => 3,
'#maxlength' => 3,
'#description' => t('amount of errors'),
'#default_value' => isset($node->sheet_wrapper[$error->nid]['amount'] ) ? $node->sheet_wrapper[$error->nid]['amount'] : '', // default value
'#attributes' => array('tabindex' => $iter_error),
);
$form['sheet_wrapper'][$error->nid]['remarks'] = array(
'#type' => 'textfield',
'#title' => t('remarks'),
'#size' => 50,
'#maxlength' => 127,
'#description' => t('remarks concerning the error'),
'#default_value' => isset($node->sheet_wrapper[$error->nid]['remarks']) ? $node->sheet_wrapper[$error->nid]['remarks'] : '',
'#attributes' => array('tabindex' => $size_error + $iter_error),
);
}
}
return $form;
}
?>and the theme function that uses theme('table',...
<?php
function theme_sheet_table_edit($form) {
$rows = array();
$headers = array(
t('Error'),
t('Amount'),
t('Remarks'), // Blank header title for the remove link.
);
foreach ($form['sheet_wrapper'] as $nid=>$error) { <<---- error here
// No need to print the field title every time.
unset(
$error['name']['#title'],
$error['amount']['#title'],
$error['remarks']['#title']
);
// Build the table row.
$row = array(
'data' => array(
array('data' => drupal_render($error['name'])),
array('data' => drupal_render($error['amount'])),
array('data' => drupal_render($error['remarks'])),
),
);
$rows[] = $row;
}
$output = theme('table', $headers, $rows);
$output .= drupal_render($form);
return $output;
}
?>i get this error:
warning: Invalid argument supplied for foreach() in D:\xampp\htdocs\drupal\sites\default\modules\sheet\sheet.module on line 341.

my output (what you see) is
my output (what you see) is an empty table (only headers) for every error that is defined by sheet_wrapper. which is not good because i should have 1 table and 1 row for every error.
This line foreach ($nodes as
This line
foreach ($nodes as $error){lacks context. Where does $nodes come from, I would guess it's an empty array.my form displays a table of
my form displays a table of errors. The user can input the amount for each. The errors come from a database table (number of errors and order can be changed). $nodes is an array containing the different errors (they are the nid of different error nodes (a cck content type) )
<?php
//title and bodyfields get setup here
// create a wrapper around the errorsheet part
// the form tree looks like this: sheet_wrapper -> errornid (one for every error) -> amount
// -> remarks
// -> othererrornid -> amount
// -> remarks
// -> and another errornid -> ...
$form['sheet_wrapper'] = array(
'#tree' => TRUE,
'#weight' => 5,
//'#prefix' => '<div class="clear-block" id="sheet-wrapper">',
//'#suffix' => '</div>',
'#prefix' => '<table>',
'#suffix' => '</table>',
'#theme' => 'sheet_table_edit', // use this theme function to theme this part of the form
);
// code to create formfields based on a layout array (which is a content type)
$layout=36; // this value should be assigned on settings page: variable_get('sheet_layout', array('36'))
// a query to get all the errors listed in the chosen layout
$query=db_query("SELECT * FROM {content_field_sheetlayout_error} WHERE {nid}=%d",$layout);
if ($query != FALSE) { // only continue if the query was successful
while($row = db_fetch_array($query)) { // assign the rows to a variable called row
$nodes[] = node_load($row['field_sheetlayout_error_nid']); // load the error nodes and put them in an array
}
$size_error=sizeof($nodes);
$iter_error=0; // define an iteration variable
?>
note: i moved '#theme' => 'sheet_table_edit', to $form['sheet_wrapper']
still have an error with foreach, maybe some variablename that isn't known anymore in the theme function??
SOLVED (but question)
my theme function (working):
<?php
function theme_sheet_table_edit($form) {
$rows = array();
$headers = array(
t('Category'),
t('Error'),
t('Amount'),
t('Remarks'),
);
foreach (element_children($form) as $error) {
// No need to print the field title every time.
unset(
$form[$error]['name']['#title'],
$form[$error]['amount']['#title'],
$form[$error]['remarks']['#title']
);
// Build the table row.
$row = array(
'data' => array(
array('data' => 'abc '.$error),
array('data' => drupal_render($form[$error]['name'])),
array('data' => drupal_render($form[$error]['amount'])),
array('data' => drupal_render($form[$error]['remarks'])),
),
);
$rows[] = $row;
}
$output = theme('table', $headers, $rows);
$output .= drupal_render($form);
return $output;
}
?>
my tree structure is however:
sheet_wrapper -> 'some_error_nid'(from a table) -> name
-> amount
-> remarks
QUESTION:
TREE is TRUE,
so why do i have to leave the sheet_wrapper.
Why is it $form[$error]['name'] and not $form['sheet_wrapper'][$error]['name'] ??
thanks