Professional javascript and node.js engineering for functional websites.

nid in $form_state

December 7, 2010

The other day I had an interesting "chicken-and-egg" problem. I'm creating a new module that does the following:

  1. A user creates a node
  2. The node creation generates a list of follow-up nodes (with references to itself) to be created by the user at a later date
  3. When the user goes to create these follow-up nodes, the list should be updated to include the nid of both nodes, and which follow-up sequence this was for

This all [mostly] worked well, with one exception: if I add a $form['#submit'][] = 'my_submit_function';, it runs before the node_form_submit() happens, in which case I don't have the node ID to store. But I also needed to pass the follow-up sequence as a hidden variable in the form, URL, or anywhere.

So, if I use the submit function, I have the $form_state, but not the node ID. If I use the hook_nodeapi(), I have the node ID, but not the form state.

One workaround I found was to use then $form['buttons']['submit']['#submit'][] = 'my_submit_function'; and that worked wonderfully!

I wasn't satisfied, though.

My intention is to make this module as generic as possible, which means that someone using it might decide to, say, remove the submit button!, in which case my plan to take over the node fails.

I was left with backtracking the node_form_submit() until where it's actually saved. Surprise! I realized that at some point something like this happens: $node = $form_state['values']; <-- WARNING: that's not what happens for real!

But you get the idea.

What that means is that $form_state['values'] is actually the $node object during node insert/update. Victory! The entire thing worked as follows:

function my_form_alter(&$form, &$form_state, $form_id) {
  $form['hiddenvalue'] = array(
    '#type' => 'value',
    '#value' => 'some value here',
function my_nodeapi(&$node, $op, $a3, $a4) {
  switch ($op) {
    case 'insert':
    case 'update':
      dpm($node->hiddenvalue); // prints 'some value here' ... Yay!

Keep in mind that this $node->hiddenvalue will only exist within the context of the node submission. Mainly during hook_nodeapi, where $op is either insert or update. If you load the node from the database, that hiddenvalue won't be there, of course.

  • What other scenarios can you think where this would be useful?
  • What other ways have you found to get the nid from within the submit function?