Posted by ghiutzu on April 26, 2012 at 1:54pm
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
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 ...
}
?>
Thanks. This helped a lot
Thanks. This helped a lot. :)