The previous recipe, Paginating a custom find type, showed us how to paginate a custom find type. Each page link changes the browser location, forcing the reload of all the elements in the page.
This recipe allows us to use AJAX (using the jQuery javascript library
) to only load what is really needed, so that every time a page is changed, only the set of rows is changed without having to load a whole new page.
We need some sample models and data to work with, and we need a fully working pagination of a custom find type. Follow the entire recipe, Paginating a custom find type, including its Getting ready section.
jQuery javascript
library to our layout. If you don't have one already, create a file named default.ctp
in your app/views/layouts
directory. Make sure you add the link to the jQuery library (here we are using the Google-hosted one), the place holder for a loading message (to be shown when an AJAX connection is in progress), and that you wrap the view content with a DIV with an ID set to content
.<head> <title><?php echo $title_for_layout; ?></title> <?php echo $this->Html->script('http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js'), ?> </head> <body> <div id="main"> <div id="loading" style="display: none; float: right;">Loading...</div> <div id="content"> <?php echo $content_for_layout; ?> </div> </div> </body> </html>
PostsController
and add the RequestHandler
component, and the Jquery
helper engine (the rest of the controller remains unmodified:<?php
class PostsController extends AppController {
public $components = array('RequestHandler'),
public $helpers = array('Js' => 'Jquery'),
public function index() {
$this->paginate['Post'] = array(
'search',
'terms' => array(
'Post 1',
'Post 2'
),
'limit' => 3
);
$posts = $this->paginate('Post'),
$this->set(compact('posts'));
}
}
?>
Paginator
helper know that we are using AJAX-based pagination. Edit the view file app/views/posts/index.ctp
and add the highlighted lines:<?php $this->Paginator->options(array( 'evalScripts' => true, 'update' => '#content', 'before' => $this->Js->get('#loading')->effect('fadeIn', array('speed'=>'fast')), 'complete' => $this->Js->get('#loading')->effect('fadeOut', array('speed'=>'fast')), )); ?> <p> <?php echo $this->Paginator->prev(); ?> <?php echo $this->Paginator->numbers(); ?> <?php echo $this->Paginator->next(); ?> </p> <ul> <?php foreach($posts as $post) { ?> <li>#<?php echo $post['Post']['id']; ?>: <?php echo $post['Post']['title']; ?></li> <?php } ?> </ul> <?php echo $this->Js->writeBuffer(); ?>
When the update setting is specified to the options()
method of the Paginator
helper, the Paginator
knows it is dealing with an AJAX-based pagination. The update setting points to the ID of the DOM element holding the content that changes when each pagination link is clicked. In our case, that DOM element is a DIV with an ID set to content
, defined in the layout.
The other option we specify to the Paginator
helper is evalScripts
, which tells the helper to evaluate any Javascript code that is being obtained as a result of an AJAX request. That way, when a page with results is being obtained through AJAX, the Javascript code that is automatically added by the JQuery engine will be executed. Similarly, we need to print out this generated code, and we do so by calling the writeBuffer()
method at the end of the index.ctp
view.
The other two options we use are before
, and complete
, which are sent directly to the AJAX operation. The before
option, executed before an AJAX request is made, is an ideal place for us to show the loading DIV. The complete
option, executed after an AJAX operation is completed, is utilized to hide the loading DIV.
We could also specify Javascript code to the before
and complete
options, rather than utilizing the helper methods provided by the jQuery engine. The same effect could be achieved by changing the options as follows:
<?php
$this->Paginator->options(array(
'evalScripts' => true,
'update' => '#content',
'before' => '$("#loading").fadeIn("fast");',
'complete' => '$("#loading").fadeOut("fast");'
));
?>
18.116.36.194