2

I've buit a multi-step (3 steps) form in form api, and going from step one to two works fine, but going from 2 to three just brings me back to step one.

function multi_step_menu() {
  $items = array();

  $items['multi-steps'] = array(
    'title' => 'Multi Steps',
    'description' => 'Multi Steps',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('step_one_form'),
    'access callback' => TRUE,
  );

  return $items;
}

function step_one_form($form, &$form_state) {

  // Display page 2 if $form_state['page_num'] == 2
  if (!empty($form_state['page_num']) && $form_state['page_num'] == 2) {
    return step_two_form($form, $form_state);
  }

  // Otherwise we build page 1.
  $form_state['page_num'] = 1;

  $subschoices = array(1 => t('Day'), 2 => t('Month'), 3=> t('Year'));
 $form['subscription_choice'] = array(
   '#type' => 'radios',
   '#title' => t('Subscriptions'),
   '#options' => $subschoices,
  '#description' => t('Choose your subscription type.'),
  '#required' => TRUE,
 );


  $form['next'] = array(
    '#type' => 'submit',
    '#value' => 'Purchase >>',
    '#submit' => array('step_one_next_submit'),
    '#validate' => array('step_one_next_validate'),
  );

  //  syslog(1, print_r($form, true));

  return $form;
}

function step_two_form($form, &$form_state) {

  // Display page 3 if $form_state['page_num'] == 3
  if (!empty($form_state['page_num']) && $form_state['page_num'] == 3) {
    return step_three_form($form, $form_state);
  }

  $form['description'] = array(
    '#type' => 'item',
    '#title' => t('Purchase Subscription'),
  );

  $form['clientReference'] = array(
    '#name' => 'clientReference',
    '#type' => 'hidden',
    '#value' => $account->uid,
  );

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

  $form['recurrentDebitExecutionDate'] = array(
    '#name' => 'recurrentDebitExecutionDate',
    '#type' => 'hidden',
    '#value' => date('m/d/Y'),
    '#attributes' => array(
      'id' => array('recurrentDebitExecutionDate'),
    ),
  );

  $form['recurrentDebitAmount'] = array(
    '#name' => 'recurrentDebitAmount',
    '#type' => 'hidden',
    '#value' => $recurrentDebitAmount,
    '#attributes' => array(
      'id' => array('recurrentDebitAmount'),
    ),
  );

  $form['recurrentDebitLabel'] = array(
    '#name' => 'recurrentDebitLabel',
    '#type' => 'hidden',
    '#value' => $recurrentDebitLabel,
    '#attributes' => array(
      'id' => array('recurrentDebitLabel'),
    ),
  );

  $form['name']['firstName'] = array(
    '#name' => 'firstName',
    '#type' => 'textfield',
    '#title' => t('First Name'),
    '#maxlength' => 20,
    '#size' => 21,
    '#required' => TRUE,
  );

  $form['name']['lastName'] = array(
    '#name' => 'lastName',
    '#type' => 'textfield',
    '#title' => t('Last Name'),
    '#maxlength' => 20,
    '#size' => 21,
    '#required' => TRUE,
  );



  $form['phoneNumber'] = array(
    '#name' => 'phoneNumber',
    '#type' => 'textfield',
    '#title' => t('Phone Number'),
    '#maxlength' => 13,
    '#size' => 13,
    '#required' => TRUE,
  );

  $form['address']['line1'] = array(
    '#name' => 'line1Inv',
    '#type' => 'textfield',
    '#title' => t('Address'),
    '#required' => TRUE,
  );

  $form['address']['line2'] = array(
    '#name' => 'line2Inv',
    '#type' => 'textfield',
  );

  $form['city'] = array(
    '#name' => 'cityInv',
    '#type' => 'textfield',
    '#title' => t('City'),
    '#required' => TRUE,
  );

  $form['postalCode'] = array(
    '#name' => 'postalCodeInv',
    '#type' => 'textfield',
    '#title' => t('Postal Code'),
    '#required' => TRUE,
  );

$form['countryCode'] = array(
    '#name' => 'countryCode',
    '#type' => 'textfield',
    '#title' => t('Country Code'),
    '#required' => TRUE,
  );

  $form['displayedCost'] = array(
    '#title' => t('Cost'),
    '#markup' => $recurrentDebitAmount . "</br>",
  );

  $form['back'] = array(
    '#type' => 'submit',
    '#value' => t('<< Back'),
    '#submit' => array('step_two_back'),
    '#limit_validation_errors' => array(),
  );

  $form['next'] = array(
    '#type' => 'submit',
    '#limit_validation_errors' => array(

    ),
    '#value' => 'Checkout >>',
    '#submit' => array('step_two_next'),
    '#validate' => array('step_two_validate'),
  );

  return $form;
}

function step_three_form($form, &$form_state){

  $form['slimpay'] = array(
    '#type' => 'submit',
    '#value' => t('Slimpay'),
    '#submit' => array('step_three_one_submit'),
  );

  $form['ogone'] = array(
    '#type' => 'submit',
    '#value' => t('Ogone'),
    '#submit' => array('step_three_two_submit'),
  );

  $form['back'] = array(
    '#type' => 'submit',
    '#value' => t('<< Back'),
    '#submit' => array('step_three_back'),
    '#limit_validation_errors' => array(),
  );

  return $form;
}

function step_one_validate($form, &$form_state) {

}

function step_two_validate($form, &$form_state) {

}

function step_one_next_submit($form, &$form_state{
  $form_state['page_values'][1] = $form_state['values'];

  if (!empty($form_state['page_values'][2])) {
    $form_state['values'] = $form_state['page_values'][2];
  }

  // When form rebuilds, it will look at this to figure which page to build.
  $form_state['page_num'] = 2;
  $form_state['rebuild'] = TRUE;
}

function step_two_next_submit($form, &$form_state) {
  syslog(1, $form_state['values']);
  $form_state['page_values'][2] = $form_state['values'];
syslog(1, "page_values" . print_r($form_state['page_values']));
  if (!empty($form_state['page_values'][3])) {
    $form_state['values'] = $form_state['page_values'][3];
  }

  $form_state['page_num'] = 3;
  $form_state['rebuild'] = TRUE;
}

function step_two_back($form, &$form_state) {
  $form_state['values'] = $form_state['page_values'][1];
  $form_state['page_num'] = 1;
  $form_state['rebuild'] = TRUE;
}

function step_three_back($form, &$form_state) {
  $form_state['values'] = $form_state['page_values'][2];
  $form_state['page_num'] = 2;
  $form_state['rebuild'] = TRUE;
}

function step_three_one_submit($form, &$form_state) {

  $page_one_values = $form_state['page_values'][1];
  $page_two_values = $form_state['page_values'][2];

  $form_state['redirect'] = 'node';
}

function step_three_two_submit($form, &$form_state) {

  $page_one_values = $form_state['page_values'][1];
  $page_two_values = $form_state['page_values'][2];

  $form_sate['redirect'] = 'node';//ogone
}
2
  • 1
    where is the step_two_next function?
    – Sibiraj PR
    Jun 17, 2013 at 12:30
  • @SibirajPR It's step_two_next_submit
    – CR47
    Jun 17, 2013 at 12:39

2 Answers 2

3

Once you correct a few of the obvious submit handler names in that code and run it, the issue eventually boils down to checking if your $form_state['page_num'] is 2 in step_one_form(). When you attempt to go to step 3, the condition in step_one_form() fails (because page_num is 3), so step_two_form() never gets called (to eventually call step_three_form).

A few other comments about your code:

  • You should be prefixing all functions in your module with the module name. This is to avoid namespace collisions, which can sometimes be obvious to fix and other times, be very frustrating.
  • With a multistep form, it may be easier to read by having one function that calls the function of each step. See this blog post for an example of a multistep form.
  • instead of using the syslog PHP functions, install the devel module and use dpr(). It's more drupaly, and easier to read the output of arrays and objects with that function.
2
  • Thank you, I didn't realize I had to do this in step one. As for the naming conventions, I edited them because the function names I have are very long due to the module name so I made them smaller to post here. I will look to the dpr() function, thanks.
    – CR47
    Jun 17, 2013 at 12:48
  • @CR47 It's popular here to replace long module names with "mymodule", like function mymodule_step_two_form($form, &$form_state) - it shows you know about prefixing, you care, and you don't want to post module name here ;)
    – Mołot
    Jun 17, 2013 at 12:52
1

In your code you can make a fix with step_one_form function.

function step_one_form($form, &$form_state) {

 // Display page 2 if $form_state['page_num'] == 2
 if (!empty($form_state['page_num']) && $form_state['page_num'] == 2) {
   return step_two_form($form, $form_state);
 }
 if (!empty($form_state['page_num']) && $form_state['page_num'] == 3) {
   return step_three_form($form, $form_state);
 }
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.