Greetings all

I have lately stumbled upon this bookpage Dynamic and Multipage forms with Forms API

I have tried my best getting it working but it seems that I just can't get it working.

As soon as I add a hook_submit() function my submit button disapears.

Is there anyone here maybe willing to share some basic code using a multipage submit form.

The code snippets in the above example isn't complete and I have difficulty getting the whole idea.

I'm quite a noob when it comes to coding but I have coded a few projects in Drupal 4.7 without too much hassle.

Please if anyone can help me it would be greatly appreciated. I will also post my source code if anyone is interested.

Kind Regards Julz

Comments

pobster’s picture

Try looking at this instead; http://cvs.drupal.org/viewcvs/drupal/contributions/docs/developer/exampl...

Else, yeah - post your code, it'll be easier to give you a proper answer that way rather than give you some generic answer which may not make sense to you.

Pobster

scrypter’s picture

I found looking at other v5 modules that use multipage the most help. Quickfile uses it for paypal integration so that is worth a look. Also found that the name of your data entry function seems to make a difference, it may have to be yourmodule_node_form not just yourmodule_form (if your module is node based!). I experimented with it months ago then got sidetracked. I would love to see a V5 example as v5 introduced the #multistep property for forms and the example in the handbook just did not work for me.

www.scryptik.com - Javascript editor with syntax error checking
www.purpleoar.co.nz - Web development, Drupal consultancy

www.purpleoar.co.nz/scryptik - Javascript editor with syntax error checking
www.purpleoar.co.nz - Web development, Drupal consultancy

jlab’s picture

I will have a look through Quickfile as well...

Will post my code when I'm finnished...

Artificial Intelligence is no match against Natural Stupidity

jlab’s picture

This looks like exactly what I wanted...

I'll browse through the code and check it out if I still fail I will upload my code.

Thanks for the link I really appreciate it.

Artificial Intelligence is no match against Natural Stupidity

jlab’s picture

"In the validation code for your form, you can check the 'step' field to see which set of fields you need to check, and display any errors."

The quote above was taken from the "Dynamic and Multipage forms with Forms API" page http://drupal.org/node/101707

It does not make sense to me... Since it looks like the 'step' field which is a hidden field does not get passed to the "form_validate" function.

I tried reading through the forms API over the weekend and still could not quite figure out how to validate a hidden field.

And it seems useless building multistep forms in Drupal 5 if it is so difficult to validate the form.

Example of my form I'm working with:

/* $ID$ */


/**
* Display help and module information
* @param section which section of the site we're displaying help
* @return help text for section
*/
function testmod_help($section='') {
  $output='';

  switch($section) {
    case "admin/help#testmod":
      $output = t("Multipage Form Test");
    break;
  }

  return $output;
} // funtion testmod_help

/**
* Menu Hooks
*/
function testmod_menu() {
  $items = array();

  // Entry Form
  $items[] = array(
      'path' => 'testmod',
      'title' => t('Multipage Test Form'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array('testmod_entry_form'),
      'access' => TRUE,
      'type' => MENU_CALLBACK,
  );

  return $items;
} // function testmod_menu


/**
* Valid permissions for this module
* @return array An array of valid permissions for the testmod module
*/
function testmod_perm() {
  return array('access testmod', 'administer testmod');
} // funtion testmod_perm


/**
* Generate a entry form
*/
// function testmod_entry_form($nid, $form_values = NULL) {
function testmod_entry_form($form_values = NULL) {

  // In a multistep form, drupal_get_form() will always
  // pass the incoming form values to you after any other
  // parameters that you specify manually. Do this instead
  // of looking at the incoming $_POST variable manually.
  if (!isset($form_values)) {
    $step = 1;
  }

  if($form_values['op'] == 'Back') {
    $step = $form_values['step'] - 1;
  }
  if($form_values['op'] == 'Next') {
    $step = $form_values['step'] + 1;
  }

  $form['step'] = array(
    '#type' => 'hidden',
    '#value' => $step,
  );

  switch($step) {
    case 1: // ----------------------------------------------------------------
      // Create hidden fields
      $form['testfield3'] = array(
        '#type' => 'hidden',
        '#value' => $form_values['testfield3'],
      );
      
      $form['testfield4'] = array(
        '#type' => 'hidden',
        '#value' => $form_values['testfield4'],
      );
      
      $form['testfield5'] = array(
        '#type' => 'hidden',
        '#value' => $form_values['testfield5'],
      );

      $form['testfield6'] = array(
        '#type' => 'hidden',
        '#value' => $form_values['testfield6'],
      );
      
      $form['testfield7'] = array(
        '#type' => 'hidden',
        '#value' => $form_values['testfield7'],
      );

      $form['testfield8'] = array(
        '#type' => 'hidden',
        '#value' => $form_values['testfield8'],
      );
      
      // Form Elements
      $form['step1'] = array(
        '#type' => 'fieldset',
        '#title' => t('Step 1'),
        '#weight' => 0,
        '#collapsible' => TRUE,
        '#collapsed' => FALSE,
      );
      
      $form['step1']['testfield1'] = array(
        '#type' => 'textfield',
        '#title' => 'Test field 1',
        '#description' => 'Test field 1',
      );
      
      $form['step1']['testfield2'] = array(
        '#type' => 'textfield',
        '#title' => 'Test field 2',
        '#description' => 'Test field 2',
        '#required' => FALSE,
      );
      
      $form['step1']['back'] = array(
        '#type' => 'hidden',
        '#value' => 'Back',
      );

      $form['step1']['next'] = array(
        '#type' => 'submit',
        '#value' => 'Next',
      );
    break;
    
    case 2: // ----------------------------------------------------------------
      // Create hidden fields
      $form['testfield1'] = array(
        '#type' => 'hidden',
        '#value' => $form_values['testfield1'],
      );

      $form['testfield2'] = array(
        '#type' => 'hidden',
        '#value' => $form_values['testfield2'],
      );

      $form['testfield5'] = array(
        '#type' => 'hidden',
        '#value' => $form_values['testfield5'],
      );

      $form['testfield6'] = array(
        '#type' => 'hidden',
        '#value' => $form_values['testfield6'],
      );
      
      $form['testfield7'] = array(
        '#type' => 'hidden',
        '#value' => $form_values['testfield7'],
      );

      $form['testfield8'] = array(
        '#type' => 'hidden',
        '#value' => $form_values['testfield8'],
      );
      
      // Form Elements
      $form['step2'] = array(
        '#type' => 'fieldset',
        '#title' => t('Step 2'),
        '#weight' => 0,
        '#collapsible' => TRUE,
        '#collapsed' => FALSE,
      );

      $form['step2']['testfield3'] = array(
        '#type' => 'textfield',
        '#title' => 'Test field 3',
        '#description' => 'Test field 3',
        '#required' => FALSE,
      );
      
      $form['step2']['testfield4'] = array(
        '#type' => 'textfield',
        '#title' => 'Test field 4',
        '#description' => 'Test field 4',
        '#required' => FALSE,
      );
      
      $form['step2']['back'] = array(
        '#type' => 'button',
        '#value' => 'Back',
      );

      $form['step2']['next'] = array(
        '#type' => 'submit',
        '#value' => 'Next',
      );
    break;
    
    case 3: // ----------------------------------------------------------------
      // Create hidden fields
      $form['testfield1'] = array(
        '#type' => 'hidden',
        '#value' => $form_values['testfield1'],
      );

      $form['testfield2'] = array(
        '#type' => 'hidden',
        '#value' => $form_values['testfield2'],
      );

      $form['testfield3'] = array(
        '#type' => 'hidden',
        '#value' => $form_values['testfield3'],
      );

      $form['testfield4'] = array(
        '#type' => 'hidden',
        '#value' => $form_values['testfield4'],
      );
      
      $form['testfield7'] = array(
        '#type' => 'hidden',
        '#value' => $form_values['testfield7'],
      );

      $form['testfield8'] = array(
        '#type' => 'hidden',
        '#value' => $form_values['testfield8'],
      );
      
      // Form Elements
      $form['step3'] = array(
        '#type' => 'fieldset',
        '#title' => t('Step 3'),
        '#weight' => 5,
        '#collapsible' => TRUE,
        '#collapsed' => FALSE,
      );
      
      $form['step3']['testfield5'] = array(
        '#type' => 'textfield',
        '#title' => 'Test field 5',
        '#description' => 'Test field 5',
        '#required' => FALSE,
      );
      
      $form['step3']['testfield6'] = array(
        '#type' => 'textfield',
        '#title' => 'Test field 6',
        '#description' => 'Test field 6',
        '#required' => FALSE,
      );
      
      $form['step3']['back'] = array(
        '#type' => 'button',
        '#value' => 'Back',
      );

      $form['step3']['next'] = array(
        '#type' => 'submit',
        '#value' => 'Next',
      );
    break;

    case 4: // ----------------------------------------------------------------
       // Create hidden fields
      $form['testfield1'] = array(
        '#type' => 'hidden',
        '#value' => $form_values['testfield1'],
      );

      $form['testfield2'] = array(
        '#type' => 'hidden',
        '#value' => $form_values['testfield2'],
      );

      $form['testfield3'] = array(
        '#type' => 'hidden',
        '#value' => $form_values['testfield3'],
      );

      $form['testfield4'] = array(
        '#type' => 'hidden',
        '#value' => $form_values['testfield4'],
      );

      $form['testfield5'] = array(
        '#type' => 'hidden',
        '#value' => $form_values['testfield5'],
      );

      $form['testfield6'] = array(
        '#type' => 'hidden',
        '#value' => $form_values['testfield6'],
      );
      
      // Form values
      $form['step4'] = array(
        '#type' => 'fieldset',
        '#title' => t('Step 4'),
        '#weight' => 0,
        '#collapsible' => TRUE,
        '#collapsed' => FALSE,
      );

      $form['step4']['testfield7'] = array(
        '#type' => 'textfield',
        '#title' => 'Test field 7',
        '#description' => 'Test field 7',
        '#required' => FALSE,
      );

      $form['step4']['testfield8'] = array(
        '#type' => 'textfield',
        '#title' => 'Test field 8',
        '#description' => 'Test field 8',
        '#required' => FALSE,
      );
      
      $form['step4']['back'] = array(
        '#type' => 'button',
        '#value' => 'Back',
      );
    break;
  }
  
  // This part is important!
  $form['#multistep'] = TRUE;
  $form['#redirect'] = FALSE;

  return $form;
} // function testmod_entryform

function testmod_entry_form_validate($form_values) {
  $errors = array();
  
  foreach ($errors as $name => $message) {
    form_set_error($name, $message);
  }
}

/**
*
*/
function testmod_entry_form_submit($form_values) {
  $final_step = 4;

  if ($form_values['step'] == $final_step) {
    drupal_set_message(t('Submited'));
  }
} // function testmod_entry_form_submit

How would I go about adding validation to this form?
Can I use external functions to generate the hidden form fields?

Artificial Intelligence is no match against Natural Stupidity

jlab’s picture

I solved the problem by adding '#base' attribute to my form.

and adding $form_id, $form_values parameters to my validate and submit functions.

If anyone wants example code please let me know and I will post it.

Since I was struggling a bit I was wondering if I could upload my my module somewhere for people to download and have a look at the example code.

Artificial Intelligence is no match against Natural Stupidity

rp9’s picture

Example code would be fantastic. I've been banging my head against this for a few weeks now, each time I think I've solved it I get a different error so if you've cracked it that would be brilliant!

Cheers,
Rich

scrypter’s picture

I took your code and added a submit button for the final step. Also made a validation for field3 on step 2 and it does not let you proceed until field is valid. Here are snippets of what I did:

  if (!isset($form_values)) {
    $step = 1;
  }

  if($form_values['op'] == 'Back') {
    $step = $form_values['step'] - 1;
  }
  if($form_values['op'] == 'Next') {
    $step = $form_values['step'] + 1;
  }
  
  $form['step'] = array(
    '#type' => 'hidden',
    '#value' => $step,
  );

  if (isset($step)) {  
    $form["step$step"] = array(
      '#type' => 'fieldset',
      '#title' => t("Step $step of 4"),
      '#weight' => 0,
      '#collapsible' => FALSE,
      '#collapsed' => FALSE,
    );
  }

  switch($step) {
    case 1: // ----------------------------------------------------------------
      // Create hidden fields
.
.
.

      $form['step2']['testfield3'] = array(
        '#type' => 'textfield',
        '#title' => 'Test field 3',
        '#description' => 'Test field 3, must be 1 char only',
        '#required' => FALSE,
      );
.
.
.
      $form['step4']['back'] = array(
        '#type' => 'button',
        '#value' => 'Back',
      );
      
      $form['step4']['submit'] = array(
        '#type' => 'submit',
        '#value' => 'Submit',
      );
    break;
  }
 
  // This part is important!
  $form['#multistep'] = TRUE;
  $form['#redirect'] = FALSE;
  $form['#base'] = 'testmod_entry_form';

  return $form;
.
.
.
function testmod_entry_form_validate($form_id, $form_values) {
  if ($form_values['step'] == 2) { // step 2 field3 needs validating
    if (strlen($form_values['testfield3']) != 1) {
	    form_set_error('testfield3', 'Must be one char only');
    }	  
  }	

I could put the code on my web dev site if that would help, but ideally it should be in the handbook here after getting a polish from a Drupal guru.

www.purpleoar.co.nz/scryptik - Javascript editor with syntax error checking
www.purpleoar.co.nz - Web development, Drupal consultancy

www.purpleoar.co.nz/scryptik - Javascript editor with syntax error checking
www.purpleoar.co.nz - Web development, Drupal consultancy

wanghl165’s picture

I tried this code,It's working well when all the input data are valid.But If the input data is not valid, I must click next button twice, then go to next form.And if I click back button instead of next button the page would go back to form step 1.

bostonou’s picture

I'm new to Drupal, so I don't know if this is a known issue, new issue, or (probably) just something I am missing. When filling in the forms (using the code given), if the user presses the back button, the next time he/she presses the "Next" button the form will go back to step 1 of the form. I've had that problem with all three of the examples I've used and haven't found any discussions about it.