When developing database CRUD applications with CakePHP, sooner or later you end up writing view code looking more or less like this
<div class="my model form">
<?php echo $this->Form->create('MyModel');?>
<fieldset>
<legend></legend>
<?php
echo $this->Form->input('id');
echo $this->Form->input('name');
?>
</fieldset>
<?php echo $this->Form->end(__('Submit', true));?>
</div>
This creates a nice form with a submit button at the end that every self respecting user can press to create a new record or modify the data of an existing one. It is also logical that you place a link to the index page somewhere near the form, so your users know where to go in case they change their mind about altering the database data.
With my users this time is was different. The form had to contain a cancel button. So how does one do it? If you are using the cake bake script and wish to have two nice round green buttons right at the bottom of your form then replace the last two lines of the previous code fragment with the following:
...
<div class="submit">
<?php echo $this->Form->submit(__('Submit', true), array('name' => 'ok', 'div' => false)); ?>
<?php echo $this->Form->submit(__('Cancel', true), array('name' => 'cancel','div' => false)); ?>
</div>
</fieldset>
<?php echo $this->Form->end();?>
The next thing to know from inside the controller code, is which button was pressed before the data were posted and that is available inside the
'form'
array of the
Controller::params
property.
So a simple modification like the one on the following code :
public function edit($id = null)
{
if (!$id && empty($this->data)) {
$this->Session->setFlash(__('Invalid property', true));
$this->redirect(array('action' => 'index'));
}
if (!empty($this->data)) {
// abort if cancel button was pressed
if (isset( $this->params['form']['cancel'])) {
$this->Session->setFlash(__('Changes were not saved. User cancelled.', true));
$this->redirect( array( 'action' => 'index' ));
}
// proceed to save changes as usual
}
... and everyone is happy.
Edit: Alternatively, if working with CakePHP version 2.4 then the sane info is inside the
data
array of the controller's
request
property.
So the previous code gets rewritten like this
public function edit($id = null)
{
if (!$this->MyModel->exists($id)) {
throw new NotFoundException(__('Invalid record'));
}
if ($this->request->is(array( 'post','put'))) {
if (isset($this->request->data['cancel'])) {
$this->Session->setFlash(__('Changes were not saved. User cancelled.'));
return $this->redirect( array( 'action' => 'index' ));
}
// proceed to save changes as usual
}
There is one last thing though... the cancel button in your form should also indicate that no form validation should
be performed at the browser level. This can be accomplished by setting the
'formnovalidate'
key of the Form::input options parameter to TRUE. So the whole cancel button creation tag should now look like this:
<div class="submit">
<?php echo $this->Form->submit(__('Create Account'), array('name' => 'ok', 'div' => FALSE)); ?>
<?php echo $this->Form->submit(__('Cancel'), array('name' => 'cancel', 'formnovalidate' => TRUE, 'div' => FALSE)); ?>
</div>
Form->end(); ?>