When theme_form is used, it removes field values in $form_values as form_submit parameter. Is it a bug? (Drupal 5.1)


<?php

// test.module

function test_info () {
  return array(
    'test' => array(
      'name' => 'test',
      'module' => 'test',
      ),
    );
}

function test_menu ($may_cache) {
    $items[] = array(
      'path' => 'test/myform',
      'title' => 'Testing form API',
      'access' => true,
      'callback' => 'drupal_get_form',
      'callback arguments' => 'test_myform',
      'type' => MENU_NORMAL_ITEM,
    );  
    return $items;
}


function test_myform () {
  $form['email'] = array(
    '#type' => 'textfield',
    '#title' => 'Email', 
    '#required' => true,
    '#maxlength' => 200,
  );'
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'submit',
  );
  return $form;
}


function test_myform_submit ($form_id, $form_values) {
  print_r($form_values); ///// debug
  drupal_message('email ok');
}

// rename to _theme_test_myform and ok, buy no theming :-(
function theme_test_myform ($form) {
  $ret = '<p>This is a test theming forms</p>';
  $ret .= drupal_render($form['email']);
  $ret .= drupal_render($form['submit']);
  return $ret;
}

?>

Comments

caligari’s picture

There is a hidden field in form that causes this problem: form_id. How to render? Any light?

coofercat’s picture

I have forms that theme and submit just fine. I can't immediately see what's wrong, apart from the callback arguments in hook_menu should be array('test_myform') not just 'test_myform' (which does have some weird side-effects, so could be the problem).

I don't know if that's the cause of this...? If not, then check the HTML produced is actually what you think it should be (compare the above when the theme is used to when it isn't).

Theming can be achieved a little differently. I don't know what the preferred method is, but I've used this quite a bit:

function theme_myform($form) {
  $form['item1'] = array('#value' => 'hello ' . drupal_render($form['item1']) . ' there');
  ...
  return drupal_render($form);
}

...in other words, render each element as you want it to be, re-inserting valid form elements into the $form array. Then just hand the whole lot back to Drupal to do it's thing. It sames having to render every element, even if there's nothing you want to do with it. It also takes care of things like form_id (etc).

caligari’s picture

RTFM to me O:-)

The rendering code keeps track of which elements have been rendered, and will only allow them to be rendered once. Notice that drupal_render is called for the entire form array at the very end of the theming function, but it will only render the remaining unrendered element, which in this case is the submit button. calling drupal_render($form) is a common way to end a theming function, as it will then render any submit buttons and/or hidden fields that have been declared in the form in a single call.

in Forms API Quickstart Guide.

Thank you very much :)