Wizard form.

This example is a classic wizard, where a different and sequential form is presented on each step of the form.

In the AJAX version, the form is replaced for each wizard section. In the multistep version, it causes a new page load.

Parameters

array $form: Form API form.

array $form_state: Form API form.

bool $no_js_use: Used for this demonstration only. If true means that the form should be built using a simulated no-javascript approach (ajax.js will not be loaded.)

Return value

array Form array.

Related topics

1 string reference to 'ajax_example_wizard'
ajax_example_menu in ajax_example/ajax_example.module
Implements hook_menu().

File

ajax_example/ajax_example_graceful_degradation.inc, line 360
Demonstrations of AJAX with graceful degradation.

Code

function ajax_example_wizard($form, &$form_state, $no_js_use = FALSE) {

  // Provide a wrapper around the entire form, since we'll replace the whole
  // thing with each submit.
  $form['#prefix'] = '<div id="wizard-form-wrapper">';
  $form['#suffix'] = '</div>';

  // We want to deal with hierarchical form values.
  $form['#tree'] = TRUE;
  $form['description'] = array(
    '#markup' => '<div>' . t('This example is a step-by-step wizard. The <a href="!ajax">AJAX version</a> does it without page reloads; the <a href="!multistep">multistep version</a> is the same code but simulates a non-javascript environment, showing it with page reloads.', array(
      '!ajax' => url('examples/ajax_example/wizard'),
      '!multistep' => url('examples/ajax_example/wizard_no_js'),
    )) . '</div>',
  );

  // $form_state['storage'] has no specific drupal meaning, but it is
  // traditional to keep variables for multistep forms there.
  $step = empty($form_state['storage']['step']) ? 1 : $form_state['storage']['step'];
  $form_state['storage']['step'] = $step;
  switch ($step) {
    case 1:
      $form['step1'] = array(
        '#type' => 'fieldset',
        '#title' => t('Step 1: Personal details'),
      );
      $form['step1']['name'] = array(
        '#type' => 'textfield',
        '#title' => t('Your name'),
        '#default_value' => empty($form_state['values']['step1']['name']) ? '' : $form_state['values']['step1']['name'],
        '#required' => TRUE,
      );
      break;
    case 2:
      $form['step2'] = array(
        '#type' => 'fieldset',
        '#title' => t('Step 2: Street address info'),
      );
      $form['step2']['address'] = array(
        '#type' => 'textfield',
        '#title' => t('Your street address'),
        '#default_value' => empty($form_state['values']['step2']['address']) ? '' : $form_state['values']['step2']['address'],
        '#required' => TRUE,
      );
      break;
    case 3:
      $form['step3'] = array(
        '#type' => 'fieldset',
        '#title' => t('Step 3: City info'),
      );
      $form['step3']['city'] = array(
        '#type' => 'textfield',
        '#title' => t('Your city'),
        '#default_value' => empty($form_state['values']['step3']['city']) ? '' : $form_state['values']['step3']['city'],
        '#required' => TRUE,
      );
      break;
  }
  if ($step == 3) {
    $form['submit'] = array(
      '#type' => 'submit',
      '#value' => t("Submit your information"),
    );
  }
  if ($step < 3) {
    $form['next'] = array(
      '#type' => 'submit',
      '#value' => t('Next step'),
      '#ajax' => array(
        'wrapper' => 'wizard-form-wrapper',
        'callback' => 'ajax_example_wizard_callback',
      ),
    );
  }
  if ($step > 1) {
    $form['prev'] = array(
      '#type' => 'submit',
      '#value' => t("Previous step"),
      // Since all info will be discarded, don't validate on 'prev'.
      '#limit_validation_errors' => array(),
      // #submit is required to use #limit_validation_errors
      '#submit' => array(
        'ajax_example_wizard_submit',
      ),
      '#ajax' => array(
        'wrapper' => 'wizard-form-wrapper',
        'callback' => 'ajax_example_wizard_callback',
      ),
    );
  }

  // This simply allows us to demonstrate no-javascript use without
  // actually turning off javascript in the browser. Removing the #ajax
  // element turns off AJAX behaviors on that element and as a result
  // ajax.js doesn't get loaded.
  // For demonstration only! You don't need this.
  if ($no_js_use) {

    // Remove the #ajax from the above, so ajax.js won't be loaded.
    // For demonstration only.
    unset($form['next']['#ajax']);
    unset($form['prev']['#ajax']);
  }
  return $form;
}