Implementing AJAX based pagination

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.

Getting ready

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.

How to do it...

  1. We start by adding the 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>
    
  2. Open the 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'));
    }
    }
    ?>
    
  3. Now let the 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(); ?>
    &nbsp;
    <?php echo $this->Paginator->numbers(); ?>
    &nbsp;
    <?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(); ?>
    

How it works...

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");'
));
?>
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.36.194