May anyone give me an example of rebuilding the form using $form_state['rebuild']
after user's input?
2 Answers
$form_state['rebuild'] is used extensively in multistep forms. Take a look at the more advanced examples in the Form Example module in the Examples project, for example in the form_example_wizard.inc file.
/**
* Submit handler for the "previous" button.
*
* This function:
* - Stores away $form_state['values']
* - Decrements the step counter
* - Replaces $form_state['values'] with the values from the previous state.
* - Forces form rebuild.
*
* You are not required to change this function.
*
* @ingroup form_example
*/
function form_example_wizard_previous_submit($form, &$form_state) {
$current_step = &$form_state['step'];
$form_state['step_information'][$current_step]['stored_values'] = $form_state['input'];
if ($current_step > 1) {
$current_step--;
$form_state['values'] = $form_state['step_information'][$current_step]['stored_values'];
}
$form_state['rebuild'] = TRUE;
}
It's used in AJAX forms, as a special case of multi-step, so you may want to look at the AJAX example.
The following example, lists two textfields for filling passenger names. If the user wants to add one more passenger (one more textfield), the form has to rebuild upon clicking the 'add passenger' button. Hope this helps.
function add_passenger_form($form, &$form_state){
//$form['#tree'] = TRUE;
if(!isset($form_state['num_names'])){
$form_state['num_names'] = 2;
}
$form['passenger_fieldset'] = array(
'#type' => 'fieldset',
'#title' => t('List of Passengers'),
'#prefix' => '<div id="passenger-form-wrapper">',
'#suffix' => '</div>',
);
for ($i = 0; $i < $form_state['num_names']; $i++) {
$form['passenger_fieldset']['passenger_name'][$i] = array(
'#type' => 'textfield',
'#title' => t('Passenger Name'),
'#required' => false,
);
}
$form['passenger_fieldset']['add_button']= array(
'#type' => 'submit',
'#value'=> t('Add passenger'),
'#submit' => array('add_passenger_form_add_one'),
'#ajax' => array(
'callback' => 'add_passenger_form_callback',
'method' => 'replace',
'effect' => 'fade',
'wrapper' => 'passenger-form-wrapper',
),
);
if ($form_state['num_names'] > 2) {
$form['passenger_fieldset']['remove_button'] = array(
'#type' => 'submit',
'#value' => t('Remove Passenger'),
'#submit' => array('remove_passenger_form_remove_one'),
'#ajax' => array(
'callback' => 'add_passenger_form_callback',
'method' => 'replace',
'effect' => 'fade',
'wrapper' => 'passenger-form-wrapper',
),
);
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
return $form;
}
/*
* add a textfield one more
*/
function add_passenger_form_add_one($form, &$form_state) {
$form_state['num_names']++;
// rebuild whole form with new values
$form_state['rebuild'] = true;
}
function remove_passenger_form_remove_one($form, &$form_state) {
if ($form_state['num_names'] > 2) {
$form_state['num_names']--;
}
$form_state['rebuild'] = TRUE;
}
function add_passenger_form_callback($form, $form_state){
return $form['passenger_fieldset'];
}