Adding Ajax Panels to the CakePHP Status Plugin
Previously On...
Last time we made a simple panel that showed the last 10 users that signed up for you web app. It was a good example for using the requestAction approach (or as AD7six pointed out you can skip the requestAction part and go right to the model).
Let's Get Ajaxy Up In This Mofo
This time we'll do a panel that shows the number of sign ups based on a time frame. We'll add a drop down that let's you select day, week, month or year and it'll show a breakdown of new users for that period. The updates will use ajax.
The Element
Just like last time we're going to create a new element: /app/views/elements/panels/signups.ctp. This time, however, the element will contain a form:
<?php echo $form->create('User', array('id' => 'SignupsForm')); ?>
<h1>
<?php __('Signups'); ?>
<?php echo $form->input('signup_span', array('type' => 'select', 'div' => false, 'label' => false,
'options' => array('day' => 'day',
'week' => 'week',
'month' => 'month',
'year' => 'year')));
?>
</h1>
<?php echo $form->end(); ?>
<div id="signup-table">
<p><?php echo $html->image('/status/img/ajax-loader.gif') ?></p>
</div>
In addition to the form, there is a div (signup-table) that will be used to hold the result of the Ajax call. For now we'll just stick a spinny icon in there.
The JavaScript
<script type="text/javascript">
$(function(){
$("#UserSignupSpan").change(function() {
$("#signup-table").html("<p><img src=\"/status/img/ajax-loader.gif\" \></p>");
$.get("/users/signups/" + $(this).val(), function(data) {
$("#signup-table").html(data);
});
}).change();
});
</script>
Pretty standard jQuery. We catch the change in the span select, set the holder div to the spinny icon and make the request for the updated data.
The Controller
function signups($span=1) {
if (!Configure::read('Status.allow')) {
die;
}
switch ($span) {
default:
case 'day':
$field = 'SUBSTR(created, 1, 13)';
$limit = 24;
break;
case 'week':
$field = 'SUBSTR(created, 1, 10)';
$limit = 7;
break;
case 'month':
$field = 'SUBSTR(created, 1, 7)';
$limit = 12;
break;
case 'year':
$field = 'SUBSTR(created, 1, 4)';
$limit = 5;
break;
}
$data = $this->User->find('all', array('fields' => array($field . ' AS span', 'count(*) as cnt'),
'group' => 'span',
'order' => 'span DESC',
'limit' => $limit));
$this->set('data', $data);
}
In practice I would move most of this code to a custom find type, but for the sake of this example I'll put it all in the controller. An important note: Unlike the example in the previous post, this action has a view associated with it. That means you can access it directly without going through the status panel. To protect against that we add the check at the top to make sure the user is allowed to access the status panel.
Include The New Panel
Remember to add the panel to the list of panels in bootstrap.php:
Configure::write('Status.panels', array('panels/signups'));
What It Looks Like


0 Comments