Hooray, figured out Drupal 5 multi-step registration form with validation and invites

The validation of multi-step forms in Drupal 5 was much less scary than I thought it would be, or maybe I lucked out by basing my code on something that already worked. =)

I had spent last Thursday and Friday searching the Internet for people’s blog posts about the topic. I came across exact descriptions of the problems I encountered, but no solutions–only notes about critical bugs in Drupal 5. Asking the developers in #drupal didn’t yield any tips, either. They told me to get ready for a world of pain.

Then I remembered that the password-reset module used a multi-step form, and validation actually worked. I had already incorporated part of the source code into one of my modules, and it was easy to extend that example. I defined a new multi-step form in my PHP code as a replacement for the system form in user/register. There were some complications around the fact that other modules modify the behavior of user_register, but I got the code to validate and submit the data. And it worked!

No code snippet, sorry. Too many interactions for me to explain neatly. Some hints:

  • You can use logic to set the value of $step.
  • Pass information to the next step using hidden fields.
  • Make sure the step field is included in your form template. Watch out for this if you’ve got a form template that specifies all the fields explicitly.
  • Captcha uses hook_form_alter to add a captcha based on the form_id. It doesn’t know about steps. You’ll need your own hook_form_alter to unset the captcha if you don’t need it on the other steps. Make sure your module runs after captcha by changing the weights in the system table.

So now I have a multi-step form that can skip step 1 (employee verification) if a valid invite code is provided, asks for CAPTCHA once, and does all the validation and user registration magic. Hooray!

  • gary

    kudos

  • mrc

    sounds cool, can you share the code? I would like to take a look at it.

  • Harry

    Nice tip. I have been trying to break this logic for the past 2 weeks, still not succeeded.

    Will you able to provide some code..so i can take a look.

  • http://sachachua.com Sacha Chua

    The password-reset module has a nice, small example of this. The code that I ended up writing had a lot of site-specific hacks (validation before registration, things like that) and I’m not sure how much I need to scrub out of it first, but you can check out password-reset and base your code on that. =)

    Good luck and have fun!

  • ulfk

    Example code? Nothing like sharing the code …

  • Kamlesh

    I want to theme my user registration page with node profile..I want 2- page user registration form. On very first page user will fill out Basic Info with some other field, which is defined by node profile module. On second page user will submit another content type which is not a Node profile page. user will render to second page from first page via a continue button. can i do this? I just want your valuable guidance. Please guide me. For attachment please visit
    http://drupal.org/node/360150
    kamlesh

    • http://sachachua.com Sacha Chua

      Good luck figuring it out! You can probably find a freelance Drupal programmer to help you with that, or find solutions on drupal.org.

  • http://blog.cashwilliams.com @CashWilliams

    Thanks for the info and what direction to head. This is literally the ONLY page I can find that talks about captcha on a multi-step form.

    Do you have any specifics on what all you unset in hook_form_alter?

    • http://sachachua.com Sacha Chua

      @CashWilliams:

      Something like this goes into your _form at the appropriate step(s),

            if ($form_values['recaptcha_response_field']) {
              $form['captcha_done'] = array(
                '#type' => 'value',
                '#value' => true,
              );
            }
            unset($form['captcha']['captcha_answer']['#title']);
            unset($form['captcha']['captcha_answer']['#description']);
            unset($form['captcha']['captcha_answer']['#required']);
      

      and something like this goes into your _form_alter:

        if ($step > 2 || ($step == 2 && $form['captcha_done'])) {
          unset($form['captcha']);
        }
      

      There’s probably some cleanup you can do there. Hope that helps!