function 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
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;
}