Easy Multi Page Forms (or Wizards) with CakePHP
February 16, 2010 by Adam · Leave a Comment
There is a wizard component available for CakePHP that’s been around for a very long time, however it uses a lot of code to something that doesn’t really need it. Today I needed to spread a single form across multiple pages for an app I am writing.
Here is the very simple controller action I used to achieve it:
<?php
function add($step = 'account') { // $step is your first page
$order = array(
'contact_name' => $this->Auth->user('contact_name'),
'company_name' => $this->Auth->user('company_name'),
'account_number' => $this->Auth->user('account_number'),
'delivery_address' => $this->Auth->user('delivery_address'),
'invoice_address' => $this->Auth->user('invoice_address'),
'promotional_discount' => $this->Auth->user('promotional_discount'),
'extra_ordinary_discount' => $this->Auth->user('extra_ordinary_discount')
); // your defaults
if($this->Session->check('order')) {
$order = Set::merge($order, $this->Session->read('order'));
}
if(!empty($this->data)) {
$this->data['Order'] = Set::merge($order, $this->data['Order']);
if($step == 'thanks') { // $step is your last step
if(!$this->Order->save($this->data)) {
$this->Session->setFlash('There was an error trying to save your order,
please make sure you completed all steps');
$step = 'confirm'; // $step is your last-but-one step
}
}
} else {
$this->data['Order'] = $order;
}
$this->Session->write('order', $this->data['Order']);
$this->render('add' . DS . $step); //put your files in a folder and name them after the matching step, no need for validation, cakephp will 404 on any missing steps
}
?>
Then in your view, post your form to the next page, so the accounts page posts to /orders/add/range, the range form posts to /orders/add/items and so on. You can then provide user navigation between the steps just by linking to that page.
<div id="page" class="accountinfo">
<?php
echo $this->Form->create('Order', array('url' => '/orders/add/range'));
echo $this->Form->input('contact_name');
echo $this->Form->input('company_name');
echo $this->Form->input('account_number');
echo $this->Form->input('order_number');
echo $this->Form->input('date_required');
?>
<div id="paging">
<?php echo $this->Html->link('Previous', array('controller' => 'orders', 'action' => 'index')); // first step so previous takes you back to the index ?>
<?php echo $this->Form->submit('Next'); ?>
</div>
<?php echo $this->Form->end(); ?>
</div> <!-- page -->
I don’t think I could make this any simpler!
Related posts: