When creating or editing object sin my table, I have a jquery dialog that opens up with the View for editing or adding an object in it. When they submit, everything works fine. I also added validation cheking to it, but if there were any validation errors, what happens is, the dialog box closes and the user is redirected to the an actual page with the validation error message.
What I want to do is have the validation error display in the dialog box instead of going to a page. I have looked around and seen that I may have to use ajax for this but I am not sure how to start.
Here is the code for my model. I deleted some extra stuff to keep it short.
class LocalClock extends AppModel
{
public $useDbConfig = 'default';
public $useTable = 'local_clocks';
public $validate = array(
'utc_offset_sec' => array(
'rule' => 'notEmpty',
'rule' => 'numeric',
'message' => 'Please Enter a Valid Number'
),
'in_month' => array(
'rule' => 'notEmpty',
'rule' => 'numeric',
'message' => 'Please Enter a Valid Number'
),
'in_week' => array(
'rule' => 'notEmpty',
'rule' => 'numeric',
'message' => 'Please Enter a Valid Number'
),
'in_day' => array(
'rule' => 'notEmpty',
'rule' => 'numeric',
'message' => 'Please Enter a Valid Number'
),
'in_hour' => array(
'rule' => 'notEmpty',
'rule' => 'numeric',
'message' => 'Please Enter a Valid Number'
)
);
public function setStatType( $type )
{
$this->table = 'local_clocks';
$this->_schema = array(
'col1' => array('type' => 'int'),
'col2' => array('type' => 'string'),
'col3' => array('type' => 'string'),
'col4' => array('type' => 'string'),
'col5' => array('type' => 'string'),
}
}
?>
Here is the code for my controller:
class LocalClocksController extends AppController
{
public $components = array('RequestHandler', 'Session'); // enable checking for incoming request attributes
public $helpers = array('Html', 'Form', 'Session', 'Javascript', 'Paginator');
public $paginate = array(
'limit' => 10,
'order' => array(
'LocalClock.id' => 'asc'
)
);
public function index()
{
$this->LocalClock->table = 'local_clocks';
$this->LocalClock->getDataSource()->tableFields['local_clocks'] = array( "id", "name", "auto_offset", "utc_offset_sec", "in_month", "in_week", "in_day", "in_hour", "out_month", "out_week", "out_day", "out_hour", "offset_sec");
if ($this->RequestHandler->accepts('xml'))
{
// xml handler
$this->set('localClocks', $this->LocalClock->find('all'));
$this->set('_serialize', array('local_clocks'));
$data = $this->paginate('LocalClock');
$this->set('localClocks', $data);
}
elseif ($this->RequestHandler->accepts('json'))
{
//json handler
$this->set('localClocks', $this->LocalClock->find('all'));
$this->set('_serialize', array('local_clocks'));
$data = $this->paginate('LocalClock');
$this->set('localClocks', $data);
}
elseif( $this->RequestHandler->accepts('html'))
{
//html handler
//$this->LocalClock->getDataSource()->tableFields['local_clocks'] = array( "id", "name", "auto_offset", "utc_offset_sec", "in_month", "in_week", "in_day", "in_hour", "out_month", "out_week", "out_day", "out_hour", "offset_sec");
$this->set('localClocks', $this->LocalClock->find('all'));
$data = $this->paginate('LocalClock');
$this->set('localClocks', $data);
}
}
public function add()
{
if ($this->request->is('post'))
{
if ($this->LocalClock->save($this->request->data))
{
$this->set('localClocks', $this->request->data);
$this->LocalClock->save($localClocks);
$this->Session->setFlash('Local Clock: '. $this->request->data['LocalClock']['name'] . ' has been created.');
$this->redirect(array('action' => 'index'));
}
else
{
$this->Session->setFlash('Unable to add new Local Clock.');
}
}
}
public function edit($id = null)
{
$this->LocalClock->id = $id;
if ($this->request->is('get'))
{
$this->request->data = $this->LocalClock->read();
$this->set('localClocks', $this->LocalClock->read());
}
else
{
if ($this->LocalClock->save($this->request->data))
{
$this->Session->setFlash('Local Clock: '. $this->request->data['LocalClock']['name'] . ' has been updated.');
$this->redirect(array('action' => 'index'));
}
else
{
$this->Session->setFlash('Unable to update Local Clock: '. $this->request->data['LocalClock']['name']);
$this->set('localClocks', $this->request->data);
}
}
}
?>
Here is the code for my index.ctp:
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/themes/start/jquery-ui.css" type="text/css" media="all" />
<p> <?php echo $this->Paginator->prev('« Previous', null, null, array('class' => 'disabled')); ?>;
<?php echo $this->Paginator->numbers(); ?>
<?php echo $this->Paginator->next('Next »', null, null, array('class' => 'disabled')); ?>; </p>
<script>
$(function()
{
var $dialog = $("#edit_dialog").dialog(
{
autoOpen: false,
title: 'Edit Local Clock',
height: 500,
width: 500,
resizable: true,
modal: true
});
$(".edit_dialog").click(function()
{
$dialog.load($(this).attr('href'), function ()
{
$dialog.dialog('open');
});
return false;
});
});
</script>
<script>
$(function()
{
var $dialog = $("#add_dialog").dialog(
{
autoOpen: false,
title: 'Create Local Clock',
height: 500,
width: 500,
resizable: true,
modal: true
});
$(".add_dialog").click(function()
{
$dialog.load($(this).attr('href'), function ()
{
$dialog.dialog('open');
});
return false;
});
});
</script>
<p><marquee><u>Local Clocks</u></marquee></p>
<div>
<table>
<thead><tr>
<th> <?php echo $this->Paginator->sort('id', 'ID'); ?> </th> <th>Name </th> <th>Auto Offset </th> <th>UTC Offset Sec </th> <th>In Month </th>
<th>In Week </th> <th>In Day </th> <th>In Hour </th> <th>Out Month </th> <th>Out Week </th>
<th>Out Day </th> <th>Out Hour </th> <th>Offset Sec </th> <th>Actions </th>
</tr></thead>
<tbody>
<?php foreach($localClocks as $LocalClock) { ?>
<tr>
<td> <?php echo $LocalClock['LocalClock']['id']; ?> </td>
<td> <?php echo $LocalClock['LocalClock']['name']; ?> </td>
<td> <?php echo $LocalClock['LocalClock']['auto_offset']; ?> </td>
<td> <?php echo $LocalClock['LocalClock']['utc_offset_sec']; ?> </td>
<td> <?php echo $LocalClock['LocalClock']['in_month']; ?> </td>
<td> <?php echo $LocalClock['LocalClock']['in_week']; ?> </td>
<td> <?php echo $LocalClock['LocalClock']['in_day']; ?> </td>
<td> <?php echo $LocalClock['LocalClock']['in_hour']; ?> </td>
<td>
<?php echo $this->Html->link('View', array('action' => 'view', $LocalClock['LocalClock']['id']), array('class' => 'view_dialog')); ?>
<?php echo $this->Html->link('Edit', array('action' => 'edit', $LocalClock['LocalClock']['id']), array('class' => 'edit_dialog'));?>
<?php echo $this->Form->postLink('Delete', array('action' => 'delete', $LocalClock['LocalClock']['id']), array('confirm' => 'Are you sure?')); ?>
</td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
<div>
<?php echo $this->Html->link('Create Local Clock', array('action' => 'add'), array('class' => 'add_dialog')); ?>
</div>
<div id="view_dialog">
</div>
<div id="edit_dialog">
</div>
<div id="add_dialog">
</div>
And lastly here is my edit.ctp:
<p>Edit Settings for Local Clock: <?php echo $localClocks['LocalClock']['name']; ?> </p>
<div>
<?php echo $this->Form->create('LocalClock', array('action' => 'edit', 'inputDefaults' => array('label' => false))); ?>
<?php echo $this->Form->input('id', array('type' => 'hidden')); ?>
<table>
<thead><tr>
<th>Field</th> <th>Current Value</th> <th>New Value</th>
</tr></thead>
<tbody>
<tr> <td>Name</td> <td> <?php echo $localClocks['LocalClock']['name']; ?> </td> <td> <?php echo $this->Form->input('LocalClock.name');?> </td> </tr>
<tr> <td>Auto Offset </td> <td> <?php echo $localClocks['LocalClock']['auto_offset']; ?> </td> <td> <?php echo $this->Form->input('LocalClock.auto_offset');?> </td> </tr>
<tr> <td>UTC Offset Sec</td> <td> <?php echo $localClocks['LocalClock']['utc_offset_sec']; ?> </td> <td> <?php echo $this->Form->input('LocalClock.utc_offset_sec');?> </td> </tr>
<tr> <td>In Month</td> <td> <?php echo $localClocks['LocalClock']['in_month']; ?> </td> <td> <?php echo $this->Form->input('LocalClock.in_month');?> </td> </tr>
</tbody>
</table>
<?php echo $this->Form->end('Save Changes'); ?>
</div>
If I can get help with the edit dialog box and having that validate without closing and redirecting to a page, I should then be able to do the same for the add function.
Thanks for any help,
and let me know if anything is unclear or if anyone needs more info.
To solve this, first add an ajax submit button to the end of the edit file, right before the $this->Form->end(). (Delete the ‘Save changes’ in the parenthesis, because the ajax submit can be changed to say that).
Next in the controller file, change the edit function to this:
The only thing new here is that the code assigns a boolean to a variable to determine whether or not to close the dialog box depending on if there are validation errors.
And that’s it. It plugs right into everything else.
I hope this help others.