Multi-page form

Hello guys! I’ve been trying to create a multi-page form for way too long now, with no real success…

What i’m trying to achieve is something like this http://gravitywiz.com/demos/multi-page-navigation/ - the user will be asked several questions over 3 pages and on the 4th page the user can view his/her entries. I also would like the user to be able to go back to a certain page to edit the results.

Once the results appear correct the user will click confirm which will send the results to my database.

I would like it create it in PHP!

If anyone can point me in the right direction it would be much appreciated! I’m no PHP guru so any help at all is useful.

Thanks,
Luke.

I’m in a good mood today and this is my no. 100 post so, here you go, a copy-paste code:
(of course, you may have lots of improvements)


<?php

session_start();

if( false == isset($_SESSION['qStep']) ) {
	$_SESSION['qStep'] = 1;
}

if( false == isset($_SESSION['answers']) ) {
	$_SESSION['answers'] = array();
}

$ERROR = array();

// you may get from database
$questions = array(

	// step 1
	1 => array (
		// questions:
		6 => array(
			'question' => 'How are you?', // text for question
			'answers' => array( 4 => 'posible answer 1', 5 => 'posible answer 2', 6 => 'posible answer 3' ), // idAnswer => answer text
		),
		7 => array(
			'question' => 'Another question with ID 7?',
			'answers' => null, // this is a free text answer
		),
		// ...
	),
	
	// step 2
	2 => array (
		// questions:
		8 => array(
			'question' => 'Another question 8?',
			'answers' => null, // type text
		),
		9 => array(
			'question' => 'Another question 9?',
			'answers' => array( 7 => 'posible answer 5', 8 => 'posible answer 6', 9 => 'posible answer 7' ),
		),
		10 => array(
			'question' => 'Another question 10?',
			'answers' => null, // type text
		),
		// ...
	),
	
	// step 3
	3 => array (
		// questions:
		11 => array(
			'question' => 'How are you - q11?', // text for question
			'answers' => array( 10 => 'posible answer 1', 11 => 'posible answer 2', 12 => 'posible answer 3' ), // idAnswer => answer text
		),
		12 => array(
			'question' => 'Another question with ID 12?',
			'answers' => null, // this is a free text answer
		),
		// ...
	),
	
	// and so on...

);

if( $_SESSION['qStep'] !== 'end' ) {
	$currentSet = $questions[$_SESSION['qStep']];
}

if( isset($_POST['answer']) ) {
	
	foreach ( $currentSet as $qId => $_tmp_q ) {
		$theAnswer = isset($_POST['answer_'.$qId]) && !empty($_POST['answer_'.$qId]) ? $_POST['answer_'.$qId] : null;
		if( is_array($_tmp_q['answers']) && false == in_array($theAnswer, array_keys($_tmp_q['answers'])) ) {
			// validate the answer
			$theAnswer = null;
		}
		if( null === $theAnswer ) {
			$ERROR[] = 'The answer for "'.$_tmp_q['question'].'" is not valid.';
		} else {
			$_SESSION['answers'][$_SESSION['qStep']][$qId] = $theAnswer;
		}
	}
	
	if( empty($ERROR) ) {
		if( $_SESSION['qStep'] < max( array_keys($questions) ) ) {
			$_SESSION['qStep']++;
		} else {
			$_SESSION['qStep'] = 'end';
		}
		header('Location: '.basename(__FILE__));
		exit;
	}
	
}

if( $_SESSION['qStep'] !== 'end' ) {
	$currentSetForForm = $questions[$_SESSION['qStep']];
}

function h($w) { return htmlspecialchars($w); }

?>

<form action="" method="post">
	
	<?php if($_SESSION['qStep'] !== 'end' ) { ?>
	
	<h2>All steps - <?php echo implode(' - ', array_keys($questions) );
	// here you may also have links to passed steps...
	?></h2>
	
	<?php if(!empty($ERROR)) {
		echo '<p style="color:#c00">'.implode('<br />', $ERROR).'</p>';
	} ?>
	
	Your questions for step <?php echo $_SESSION['qStep'] ?>:
	<?php foreach( $currentSetForForm as $questionId => $question ) { ?>
		<p><?php echo $question['question'] ?><br />
		<?php if ( false == is_array($question['answers']) ) { ?>
			<input type="text" name="answer_<?php echo $questionId ?>" value="<?php echo h(isset($_SESSION['answers'][$_SESSION['qStep']][$questionId]) ? $_SESSION['answers'][$_SESSION['qStep']][$questionId] : '') ?>" />
		<?php } else { ?>
		
			<select name="answer_<?php echo $questionId ?>">
				<option value="">&nbsp;</option>
				<?php foreach($question['answers'] as $aId => $aText ) {
					echo "<option value=\\"{$aId}\\"".(isset($_SESSION['answers'][$_SESSION['qStep']][$questionId]) && $_SESSION['answers'][$_SESSION['qStep']][$questionId] == $aId ? ' selected="selected"' : '' ).">{$aText}</option>\
";
				} ?>
			</select>
			
		<?php } ?>
		</p>
	<?php } ?>
	
	<input type="submit" name="answer" value="Go to next" />
	
	<?php } else { ?>
		END OF TEST!
	<?php } ?>
	
</form>

<br />....<br />Current answers:<br />
<pre>
<?php
// here you may have XSS - check your results before you show
print_r($_SESSION['answers']) ?>

Wow that works perfectly, thank you!

One quick question, how do I link back to a specific question?

OK, let’s make it complete :slight_smile:


<?php

session_start();

if( false == isset($_SESSION['qStep']) ) {
	$_SESSION['qStep'] = 1;
}

if( false == isset($_SESSION['answers'][$_SESSION['qStep']]) ) {
	$_SESSION['answers'][$_SESSION['qStep']] = array();
}


$OURFILE = basename(__FILE__);
$ERROR = array();

// you may get from database
$questions = array(

	// step 1
	1 => array (
		// questions:
		6 => array(
			'question' => 'How are you?', // text for question
			'answers' => array( 4 => 'posible answer 1', 5 => 'posible answer 2', 6 => 'posible answer 3' ), // idAnswer => answer text
		),
		7 => array(
			'question' => 'Another question with ID 7?',
			'answers' => null, // this is a free text answer
		),
		// ...
	),
	
	// step 2
	2 => array (
		// questions:
		8 => array(
			'question' => 'Another question 8?',
			'answers' => null, // type text
		),
		9 => array(
			'question' => 'Another question 9?',
			'answers' => array( 7 => 'posible answer 5', 8 => 'posible answer 6', 9 => 'posible answer 7' ),
		),
		10 => array(
			'question' => 'Another question 10?',
			'answers' => null, // type text
		),
		// ...
	),
	
	// step 3
	3 => array (
		// questions:
		11 => array(
			'question' => 'How are you - q11?', // text for question
			'answers' => array( 10 => 'posible answer 1', 11 => 'posible answer 2', 12 => 'posible answer 3' ), // idAnswer => answer text
		),
		12 => array(
			'question' => 'Another question with ID 12?',
			'answers' => null, // this is a free text answer
		),
		// ...
	),
	
	// and so on...

);

if(
	isset($_GET['step']) && // we have a step
	in_array($_GET['step'], array_keys($questions)) && // it's a valid step
	isset($_SESSION['answers'][$_GET['step']]) // we passed, you cannot go directly to 3 if you didn't get there yet
) {
	$_SESSION['qStep'] = (int)$_GET['step'];
}

if( $_SESSION['qStep'] !== 'end' ) {
	$currentSet = $questions[$_SESSION['qStep']];
}

if( isset($_POST['answer']) ) {
	
	foreach ( $currentSet as $qId => $_tmp_q ) {
		$theAnswer = isset($_POST['answer_'.$qId]) && !empty($_POST['answer_'.$qId]) ? $_POST['answer_'.$qId] : null;
		if( is_array($_tmp_q['answers']) && false == in_array($theAnswer, array_keys($_tmp_q['answers'])) ) {
			// validate the answer
			$theAnswer = null;
		}
		if( null === $theAnswer ) {
			$ERROR[] = 'The answer for "'.$_tmp_q['question'].'" is not valid.';
		} else {
			$_SESSION['answers'][$_SESSION['qStep']][$qId] = $theAnswer;
		}
	}
	
	if( empty($ERROR) ) {
		if( $_SESSION['qStep'] < max( array_keys($questions) ) ) {
			$_SESSION['qStep']++;
		} else {
			$_SESSION['qStep'] = 'end';
		}
		header('Location: '.$OURFILE);
		exit;
	}
	
}

if( $_SESSION['qStep'] !== 'end' ) {
	$currentSetForForm = $questions[$_SESSION['qStep']];
}

function h($w) { return htmlspecialchars($w); }

?>

<form action="<?php echo $OURFILE ?>" method="post">
	
	<?php if($_SESSION['qStep'] !== 'end' ) { ?>
	
	<h2>All steps <?php foreach(array_keys($questions) as $STP ) {
		echo ' - <a href="'.$OURFILE.'?step='.$STP.'"'.($STP == $_SESSION['qStep'] ? ' style="color:#c00"' : '' ).'>'.$STP.'</a>';
	} ?></h2>
	
	<?php if(!empty($ERROR)) {
		echo '<p style="color:#c00">'.implode('<br />', $ERROR).'</p>';
	} ?>
	
	Your questions for step <?php echo $_SESSION['qStep'] ?>:
	<?php foreach( $currentSetForForm as $questionId => $question ) { ?>
		<p><?php echo $question['question'] ?><br />
		<?php if ( false == is_array($question['answers']) ) { ?>
			<input type="text" name="answer_<?php echo $questionId ?>" value="<?php echo h(isset($_SESSION['answers'][$_SESSION['qStep']][$questionId]) ? $_SESSION['answers'][$_SESSION['qStep']][$questionId] : '') ?>" />
		<?php } else { ?>
		
			<select name="answer_<?php echo $questionId ?>">
				<option value="">&nbsp;</option>
				<?php foreach($question['answers'] as $aId => $aText ) {
					echo "<option value=\\"{$aId}\\"".(isset($_SESSION['answers'][$_SESSION['qStep']][$questionId]) && $_SESSION['answers'][$_SESSION['qStep']][$questionId] == $aId ? ' selected="selected"' : '' ).">{$aText}</option>\
";
				} ?>
			</select>
			
		<?php } ?>
		</p>
	<?php } ?>
	
	<input type="submit" name="answer" value="Go to next" />
	
	<?php } else { ?>
		END OF TEST!
	<?php } ?>
	
</form>

<br />....<br />Current answers:<br />
<pre>
<?php
// here you may have XSS - check your results before you show
print_r($_SESSION['answers']) ?>

Woohoo! Thank you so much!