Captcha in multi-step form lost when changing steps

ghiutzu's picture

I'm using the Captcha module in a multi-step form that contains two steps; the Captcha field resides on the second step.
When I hit "Previous" button to navigate to the first step and then go back to the second step of the form, the captcha field disappears.
Can you please advice me how to keep the captcha field all the time on the second step ? I'm not a Drupal programmer, so if someone could share some sample code, it would be great.
Here are the most important methods from the code I'm using:

<?php
function multistep_form($form, &$form_state) {
  if (
$form_state['rebuild']) {
   
$form_state['input'] = array();
  }
  if (empty(
$form_state['storage'])) {
   
$form_state['storage'] = array('step' => 'multistep_form_step1');
  }
 
$function = $form_state['storage']['step'];
 
$form = $function($form, $form_state);
  return
$form;
}

function
multistep_form_submit($form, &$form_state) {
 
$values = $form_state['values'];
  if (isset(
$values['back']) && $values['op'] == $values['back']) {
   
$step = $form_state['storage']['step'];
    if (
function_exists($step . '_submit')) {
     
$function = $step . '_submit';
     
$function($form, $form_state);
    }
   
$last_step = array_pop($form_state['storage']['steps']);
   
$form_state['storage']['step'] = $last_step;
  }
  else {
   
$step = $form_state['storage']['step'];
   
$form_state['storage']['steps'][] = $step;
    if (
function_exists($step . '_submit')) {
     
$function = $step . '_submit';
     
$function($form, $form_state);
    }
  }
  return;
}

function
multistep_form_step1($form, &$form_state) {
 
// ... defining step1
 
$form['step1']['name'] = array(
   
'#type' => 'textfield',
   
'#title' => t('Name'));
   
// ... more fields here
 
$form['submit'] = array(
   
'#type' => 'submit',
   
'#value' => t('Next'));
  return
$form;
}

function
multistep_form_step2($form, &$form_state) {
 
$form['step2'] = array(
   
'#type' => 'fieldset',
   
'#title' => t('Step1'),
   
'#tree' => TRUE);
 
$form['step2']['login'] = array(
   
'#type' => 'textfield',
   
'#title' => t('Login'));
   
// ... more fields here
 
$form['my_captcha_element'] = array(
   
'#type' => 'captcha',
   
'#captcha_type' => 'image_captcha/Image');
 
$form['back'] = array(
   
'#type' => 'submit',
   
'#value' => t('Back'));
 
$form['submit'] = array(
   
'#type' => 'submit',
   
'#value' => t('Next'));
  return
$form;
}

function
multistep_form_step2_submit($form, &$form_state) { 
 
$values = $form_state['values'];
  if (isset(
$values['back']) && $values['op'] == $values['back']) {
   
$form_state['storage']['step2'] = $form_state['values']['step2'];
   
$form_state['rebuild'] = TRUE;
  }
  else {
   
// Process form data ...
 
}
}
?>

Thanks in advance.

Comments

I've found a solution to the problem

ghiutzu's picture

Because I have validation methods on my multi-step form, I can bypass the validation done on the second step, when going from the second step to the first step. For this, a new attribute must be added for the "Back" button; I've called it skip_validation:

<?php
  $form
['back'] = array(
   
'#type' => 'submit',
   
'#value' => t('Back'),
   
'#skip_validation' => TRUE
 
);
?>

After that, in the validation method, if the user clicks the "Back" button and we have the skip_validation property set to TRUE, we clear all the error messages:
<?php
function multistep_form_validate($form, &$form_state) {
 
// Call step validate handler if it exists.
 
if (isset($form_state['clicked_button']) && isset($form_state['clicked_button']['#skip_validation'])) {
    if (
$form_state['clicked_button']['#skip_validation'] == TRUE) {
     
drupal_get_messages();
     
form_clear_error();    
      return;
    }
  }
 
// Call separate validation here, depending on the web-form step ...
}
?>

CAPTCHA

Group organizers

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds: