Forum Moderators: coopster
another question to a common problem that seems to have many solutions.
I'm going to implement a multi-page form, and am looking for the best and robustest solution. I've looked briefly at HTML_QuickForm_Controller, but I don't want to use PEAR/quickform
What I'm thinking of doing is keeping the state ($array_state) of the form either in a hidden field or in a session variable.
Upon receiving a POST, the script merges $_POST with $array_state
$array_state = unserialize($_POST['state']);
OR
$array_state = $_SESSION['state'];
$array_state = array_merge($array_state, $_POST)
- replacing values of existing fields in the array, if any
Then, outputting the state in hidden field as mentioned
<input type="hidden" name="state" value="<?=htmlspecialchars(serialize($array_state))?>
I've seen others putting *each value* in separate hidden fields, but this seems cumbersome to me, when serialize() is available.
Any thoughts, insights, gotchas I should be aware of?
Thanks!
Merging arrays is fine if you're only validating at the end, but most of my multi-page forms validate at each step, so that the end-user can't proceed off page one until the values are appropriate.
How are you planning to handle validation?
For server side validation, I've made a first attempt to write a simple controller for a multi-page form including validation code:
//** if $_POST, validate page and continue, else display page 1 **
if ($_POST) {
$current_page = $_POST['_current_page_'];
$ary_errors = validate($current_page, $_POST);//** if any errors, display same page with errors **
if ($ary_errors) {
display_page($current_page, $_POST, $ary_errors);
//** else merge data and go back/next/submit **
} else {
//** get current state from hidden field, merge **
$ary_state = unserialize(gzuncompress(base64_decode($_POST['_state_'])));
$ary_state = array_merge($ary_state, $_POST);
//** update state field, might want to compress the data?
$tmp = base64_encode(gzcompress(serialize($ary_state)));
$ary_state['_state_'] = $tmp
//** submit **
if ($_POST['_submit_']) {
submit_form();
//thank you
//** display page according to button pressed **
} elseif ($_POST['_goto_page_1']) {
display_page(1, $ary_state, NULL);
} elseif ($_POST['_goto_page_2']) {
display_page(2, $ary_state, NULL);
} elseif ($_POST['_goto_page_3']) {
display_page(3, $ary_state, NULL);
/** or else first page **
} else {
display_page(1, NULL, NULL);
}
}
/** or else display first page **
} else {
display_page(1, NULL, NULL);
}function display_page($current_page, $ary_state, $ary_errors) {
include('form_page_' . $current_page . '.tpl');
}function validate($current_page, $post_values) {
...
}form_page_1.tpl:
<form>
<input type="hidden" name="_current_page_" value="2" />
<input type="hidden" name="_state_" value="<?=$ary_state['_state_']?>" />
<div class="error"><?=$ary_errors['sometextfield']?></div>
<input type="text" name="sometextfield"
value="<?=$ary_state['sometextfield']?>" />
<input type="submit" name="_goto_page_1_ value="Back" />
<input type="submit" name="_goto_page_2_" value="Next" />
</form>