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

yangke - November 9, 2009 - 03:28

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

nevets - November 9, 2009 - 03:32

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

yangke - November 9, 2009 - 03:48

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)

yangke - November 9, 2009 - 04:46

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

 
 

Drupal is a registered trademark of Dries Buytaert.