I am trying to build a multi-step node form using hook_form, hook_validate, hook_submit and hook_form_alter and I am very confused. In the Drupal 6.x changes post it talks about the merits of using $form_state['storage'], but I can't figure out how to get information into the storage variable and have it carry to the next step. Hook_validate doesn't work because it doesn't actually take $form_state into the function (as per http://api.drupal.org). And believe me, I have tried. Hook_nodeapi doesn't seem to have anything to do with $form_state so I don't think I can use that.

I have found this post: http://drupal.org/node/277055 which works using hidden values, but it doesn't make use of $form_state['storage'].

I guess my question is: can you use $form_state['storage'] with a node form? If so, can you please tell me how, or direct me to the instructions? If not, then do I just go ahead and use hidden fields?

Thanks for any help, I have been combing this site for two days trying to figure this out.

alynner

Comments

dnewkerk’s picture

I'm a newbie with Forms API myself, though I'm reading the forms chapter in Pro Drupal Development and it's been very helpful. There's a multi-step form example starting page 247 that uses $form_state['storage']

Though I can't post the pages of course, the code snippets can be found on the book's website: http://www.drupalbook.com/node/2 (make sure to get the single .zip file at the top, not the Drupal 5 versions listed below from the book's first edition). Look in the Chapter 10 folder for the formwizard example.

I do highly recommend getting the book though... there's an ebook version available at http://www.apress.com/book/view/1430209895

Code sample #10 on this guide also contains a multi-step form: http://drupal.org/node/262422

Hope this helps, and if anyone else has extra feedback feel free, as I don't understand it all myself yet either :D

dww’s picture

Multistep node forms are hell. ;) You think it's bad writing one from scratch? Try altering a single-step node form into a multi-step form via another module. ;) (That's what happens to project_release nodes when you enable the cvs integration module -- one of the cornerstones of the drupal.org release system).

More to the point, they're currently broken in core. See #382634: Previewing multiselect taxonomy fields lose value on multistep node forms for details... There's example code in there of a module I wrote to demonstrate the bug. That should give you a rough framework to start from.

Join us in the issue to help get that patch accepted in core (and backported to D6).

Thanks!
-Derek

___________________
3281d Consulting

alynner’s picture

Thank you both for your answers!

Keys - this book is very handy, thank you, I haven't looked at it before and will be using it from now on. However it doesn't give any examples for multistep node form, just custom forms unfortunately.

Dww - I tried out the change to form.inc as they talked about here but it doesn't seem to make a difference. I tried using hook_validate to change $form_state['storage'] and found that it is still empty in that function of form.inc anyway. According to the book that Keys showed me, hook_validate takes only the $node variable, not $form_state, so I am still confused as to where I would even set $form_state['storage'], it seems as though this was not set up at all for node forms to me.

I do have several modules calling hook_form_alter and I would like these form additions to appear on different steps of the form process. One of these is Organic Groups and I don't want to hack the og.module. It doesn't seem that this has been officially worked out anywhere yet, so if I come up with a solution I will post it here. I have so far created my own hook that automatically puts any field that I need to save throughout the form into a hidden field, I can post my code for that if anyone is interested.

alynner

alynner’s picture

I just realized everything is being saved along the way in $form_state['node'] automatically so I don't need to worry about $form_state['storage']. Perhaps this is written somewhere and I missed it, or perhaps one is just supposed to realize this sooner, but it is very handy to now know.

[edit] it is getting put in $form_state['node']; however hook_insert doesn't receive it from $node, so I still went with hidden fields to be able to enter data into my custom tables.

jaypan’s picture

You shouldn't try to do anything with the data in the _validate() function, other than validate it (the data), and set error messages if it's wrong. You can add the data to $form_state['storage'] in the _submit() function. Doing this will automatically cause the form to rebuild, rather than submitting, but will process whatever code you have inside the _submit() function.

By the way - and _submit is not a hook. hook_validate() exists, but it is only called after hook_form(), so if you are calling your form through drupal_get_form, hook_validate() will not be called. This may also be part of your problem if you are trying to use these as hooks.

Contact me to contract me for D7 -> D10/11 migrations.

drupaul.z’s picture

Did you solve it now?
Could you please tell me how?

sylvain lecoy’s picture