You are here

function ctools_wizard_wrapper in Chaos Tool Suite (ctools) 7

Same name and namespace in other branches
  1. 6 includes/wizard.inc \ctools_wizard_wrapper()

Provide a wrapper around another form for adding multi-step information.

1 string reference to 'ctools_wizard_wrapper'
ctools_wizard_multistep_form in includes/wizard.inc
Display a multi-step form.

File

includes/wizard.inc, line 229
CTools' multi-step form wizard tool.

Code

function ctools_wizard_wrapper($form, &$form_state) {
  $form_info =& $form_state['form_info'];
  $info = $form_info['forms'][$form_state['step']];

  // Determine the next form from this step.
  // Create a form trail if we're supposed to have one.
  $trail = array();
  $previous = TRUE;
  foreach ($form_info['order'] as $id => $title) {
    if ($id == $form_state['step']) {
      $previous = FALSE;
      $class = 'wizard-trail-current';
    }
    elseif ($previous) {
      $not_first = TRUE;
      $class = 'wizard-trail-previous';
      $form_state['previous'] = $id;
    }
    else {
      $class = 'wizard-trail-next';
      if (!isset($form_state['next'])) {
        $form_state['next'] = $id;
      }
      if (empty($form_info['show trail'])) {
        break;
      }
    }
    if (!empty($form_info['show trail'])) {
      if (!empty($form_info['free trail'])) {

        // ctools_wizard_get_path() returns results suitable for
        // $form_state['redirect] which can only be directly used in
        // drupal_goto. We have to futz a bit with it.
        $path = ctools_wizard_get_path($form_info, $id);
        $options = array();
        if (!empty($path[1])) {
          $options = $path[1];
        }
        $title = l($title, $path[0], $options);
      }
      $trail[] = '<span class="' . $class . '">' . $title . '</span>';
    }
  }

  // Display the trail if instructed to do so.
  if (!empty($form_info['show trail'])) {
    ctools_add_css('wizard');
    $form['ctools_trail'] = array(
      '#markup' => theme(array(
        'ctools_wizard_trail__' . $form_info['id'],
        'ctools_wizard_trail',
      ), array(
        'trail' => $trail,
        'form_info' => $form_info,
      )),
      '#weight' => -1000,
    );
  }
  if (empty($form_info['no buttons'])) {

    // Ensure buttons stay on the bottom.
    $form['buttons'] = array(
      '#type' => 'actions',
      '#weight' => 1000,
    );
    $button_attributes = array();
    if (!empty($form_state['ajax']) && empty($form_state['modal'])) {
      $button_attributes = array(
        'class' => array(
          'ctools-use-ajax',
        ),
      );
    }
    if (!empty($form_info['show back']) && isset($form_state['previous'])) {
      $form['buttons']['previous'] = array(
        '#type' => 'submit',
        '#value' => $form_info['back text'],
        '#next' => $form_state['previous'],
        '#wizard type' => 'next',
        '#weight' => -2000,
        '#limit_validation_errors' => array(),
        // Hardcode the submit so that it doesn't try to save data.
        '#submit' => array(
          'ctools_wizard_submit',
        ),
        '#attributes' => $button_attributes,
      );
      if (isset($form_info['no back validate']) || isset($info['no back validate'])) {
        $form['buttons']['previous']['#validate'] = array();
      }
    }

    // If there is a next form, place the next button.
    if (isset($form_state['next']) || !empty($form_info['free trail'])) {
      $form['buttons']['next'] = array(
        '#type' => 'submit',
        '#value' => $form_info['next text'],
        '#next' => !empty($form_info['free trail']) ? $form_state['step'] : $form_state['next'],
        '#wizard type' => 'next',
        '#weight' => -1000,
        '#attributes' => $button_attributes,
      );
    }

    // There are two ways the return button can appear. If this is not the
    // end of the form list (i.e, there is a next) then it's "update and return"
    // to be clear. If this is the end of the path and there is no next, we
    // call it 'Finish'.
    // Even if there is no direct return path (some forms may not want you
    // leaving in the middle) the final button is always a Finish and it does
    // whatever the return action is.
    if (!empty($form_info['show return']) && !empty($form_state['next'])) {
      $form['buttons']['return'] = array(
        '#type' => 'submit',
        '#value' => $form_info['return text'],
        '#wizard type' => 'return',
        '#attributes' => $button_attributes,
      );
    }
    elseif (empty($form_state['next']) || !empty($form_info['free trail'])) {
      $form['buttons']['return'] = array(
        '#type' => 'submit',
        '#value' => $form_info['finish text'],
        '#wizard type' => 'finish',
        '#attributes' => $button_attributes,
      );
    }

    // If we are allowed to cancel, place a cancel button.
    if (isset($form_info['cancel path']) && !isset($form_info['show cancel']) || !empty($form_info['show cancel'])) {
      $form['buttons']['cancel'] = array(
        '#type' => 'submit',
        '#value' => $form_info['cancel text'],
        '#wizard type' => 'cancel',
        // Hardcode the submit so that it doesn't try to save data.
        '#limit_validation_errors' => array(),
        '#submit' => array(
          'ctools_wizard_submit',
        ),
        '#attributes' => $button_attributes,
      );
    }

    // Set up optional validate handlers.
    $form['#validate'] = array();
    if (function_exists($info['form id'] . '_validate')) {
      $form['#validate'][] = $info['form id'] . '_validate';
    }
    if (isset($info['validate']) && function_exists($info['validate'])) {
      $form['#validate'][] = $info['validate'];
    }

    // Set up our submit handler after theirs. Since putting something here will
    // skip Drupal's autodetect, we autodetect for it.
    // We make sure ours is after theirs so that they get to change #next if
    // the want to.
    $form['#submit'] = array();
    if (function_exists($info['form id'] . '_submit')) {
      $form['#submit'][] = $info['form id'] . '_submit';
    }
    if (isset($info['submit']) && function_exists($info['submit'])) {
      $form['#submit'][] = $info['submit'];
    }
    $form['#submit'][] = 'ctools_wizard_submit';
  }
  if (!empty($form_state['ajax'])) {
    $params = ctools_wizard_get_path($form_state['form_info'], $form_state['step']);
    if (count($params) > 1) {
      $url = array_shift($params);
      $options = array();
      $keys = array(
        0 => 'query',
        1 => 'fragment',
      );
      foreach ($params as $key => $value) {
        if (isset($keys[$key]) && isset($value)) {
          $options[$keys[$key]] = $value;
        }
      }
      $params = array(
        $url,
        $options,
      );
    }
    $form['#action'] = call_user_func_array('url', $params);
  }
  if (isset($info['wrapper']) && function_exists($info['wrapper'])) {
    $form = $info['wrapper']($form, $form_state);
  }
  if (isset($form_info['wrapper']) && function_exists($form_info['wrapper'])) {
    $form = $form_info['wrapper']($form, $form_state);
  }
  return $form;
}