I made this tiny module that defines a new 'bean' node type. I made a form for it. Now I am trying to provide an additional path to return the form html. But it does not call the hook_form() with the right parameters, in fact, the parameters seem to be reversed.

Anyone see the problem in this code? Why are the parameters to hook_form() reversed depending on whether I am adding it using node/add/bean or pulling it through drupal_get_form() ?

Thanks!

Code:


function coolbeans_menu()
{
  $items = array();
  $items['ajaxbean'] = array(
    'title' => '',
    'page callback' => 'coolbeans_ajax',
    'access arguments' => user_access('create content'),
  );
  return $items;
}

function coolbeans_ajax()
{
    if (!isset($_GET['nid'])) { echo "Missing nid"; die(); }
    $node = node_load($_GET['nid']);
    echo htmlentities(drupal_get_form("coolbeans_form", $node));
    exit;
}

function coolbeans_node_info()
{
  return array(
    'bean' => array(
      'name' => t('Bean'),
      'module' => 'coolbeans',
      'description' => t("A bean is a small thing."),
      'help' => t("How can I help you?"),
      'has_body' => FALSE,
      'has_title' => FALSE,
    ),
    );
}

function coolbeans_form($param1, $param2)
{
    /**
     * When I access /node/add/bean
     *       param1 is the node, param2 is the form_state.
     * When I access /ajaxbean?nid=69
     *       param1 is the form_state, param2 is the node.
     * Why are these two reversed?
    */
    var_dump($param1);
    var_dump($param2);
    $form = array();
    $form['bean'] = array(
        '#type' => 'textfield',
        '#title' => 'Bean',
        );
    return $form;
}

Comments

thorie79’s picture

http://drupal.org/node/219604#comment-727435

But that doesn't work either: I get a form with only the hidden fields and the coolbeans_form() function never gets called. It makes me wonder, though, how node_form() is able to figure out that a request for form id "coolbeans_node_form" eventually calls coolbeans_form(). I will probably take a closer look at node_form() to see how it's accomplished.

thorie79’s picture

I found that eventually the difference between the node/69/edit page and my custom ajaxbean page is that the drupal_get_form() eventually calls drupal_retrieve_form() in form.inc which does a callback to node_form().

In the case of node/69/edit, the node_form() function is defined.
In the case of ajaxbean, the node_form() function is not defined.

And, it silently returns null and causes an empty form, without any warning or error.

The reason why it's not defined is that in D6, as part of an effort to load less code, form.pages.inc is loaded with the menu handler, and not in the custom ajaxbean page I made.

So the final solution to the problem is, at the top of my coolbeans.module I added:

require_once './' . drupal_get_path('module', 'node') . '/node.pages.inc';

And voila, like magic, drupal_get_form("bean_node_form") actually works and returns the form with the hidden keys and everything I need.

Thanks to merlinofchaos