I'm upgrading a custom module from 4.6 to 4.7.6, and am encountering problems when I try to apply themes to a form function using drupal_get_form().

My hook_form and theme code looks like this:

function album_item_form(&$node) {
  $form['title'] = array(
    '#type' => 'textfield',
    '#title' => 'Title',
    '#default_value' => $node->title,
    '#size' => 60,
    '#maxlength' => 128,
    '#required' => TRUE,
  );
  ...
  more form elements
  ...
  return $form;
}

function theme_album_item_form($form) {
  $output = '';
  $output .= form_render($form['name']);
  ...
  more form elements
  ...
  $output .= form_render($form);
  return $output;
}

Everything is fine as long as I return the form like this...

return $form;

...but I want to apply a custom theme to my form.

If I try this...

$output = drupal_get_form('album_item_form', $form);
return $output;

... then I get the following error messages:

Warning: Invalid argument supplied for foreach() in /var/www/html/drupal_4.7.6/includes/form.inc on line 360
Warning: array_shift() [function.array-shift]: The argument should be an array in /var/www/html/drupal_4.7.6/includes/form.inc on line 500
Warning: array_shift() [function.array-shift]: The argument should be an array in /var/www/html/drupal_4.7.6/includes/form.inc on line 500
Warning: array_shift() [function.array-shift]: The argument should be an array in /var/www/html/drupal_4.7.6/includes/form.inc on line 500
...

The first error points to the following code in form.inc at line 360. This error then causes the rest of the errors.

foreach ($form['#parents'] as $parent) {
  $edit = isset($edit[$parent]) ? $edit[$parent] : NULL;
}

I'm not using $form['#parents'] anywhere in my form, though if I print out the $form object here I can see that Drupal has added it in.

This doesn't seem to be related to the code in my module. I see this behaviour even if I take all the code out of my form (except for drupal_get_form and the return statement, of course), and it happens with another module I'm upgrading on a separate Drupal site.

What's going on here? I'd love to be able to theme my form but it just doesn't seem possible.

Please don't just refer me to the Forms API Quickstart Guide, the Forms API Reference, or Form generation. I've spent lots of time with all of these and none has been helpful with this issue.

Comments

heine’s picture

1. This seems to be a custom node module for the node type album_item.
2. If true, then you are implementing hook_form and you should return the form array without calling drupal_get_form (node.module will handle that).
3. To theme the resulting node form you need to know the form id. If all of the above is true, the form_id for your form would be album_item_node_form, and the correct theme function theme_album_item_node_form.

--
The Manual | Troubleshooting FAQ | Tips for posting | How to report a security issue.

gjost’s picture

This advice seems to work - my form and theme function correctly now.

The documentation doesn't state anywhere that you don't need to use (or shouldn't use) drupal_get_form with hook_form. In fact, the forms API give examples that use drupal_get_form. This is confusing. It would help if the documentation could be revised to make this clearer.

Thank you for your help!

heine’s picture

Glad it works.

From the hook_form api doc:

Return value: An array containing the form elements to be displayed in the node edit form.

There's an example on that page as well.

The FAPI quickstart guide doesn't talk about hook_form at all (as far as I can see), but does contain this section:

Generally speaking, you will return a form with the drupal_get_form function.

In some cases, code may be written in such a way that form elements themselves (and not a fully themed form) need to be returned to a calling function. This is the case with many Drupal core hooks. in this case, simply return the constructed $form array, and let the calling code handle the form rendering.

--
The Manual | Troubleshooting FAQ | Tips for posting | How to report a security issue.