Click here to Skip to main content
12,554,555 members (80,351 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as



CakePHP 2-0 Ajax Pagination WITHOUT The Pages

, 11 May 2015 CPOL
Rate this:
Please Sign up or sign in to vote.
As I promised in this article, I have created a full CakePHP example of performing AJAX pagination without the pages.  The goal of this article is to display news articles to a user.

As I promised, I have created a full CakePHP example of performing AJAX pagination without the pages.  The goal of this article is to display news articles to a user.  As the user scrolls down, we will dynamically load in additional content so they can continue to scroll and read.

Start by downloading a fresh copy of CakePHP 2.0 dev edition.  I saved my copy to a folder called cake-2-0 in my htdocs folder allowing me to load: http://localhost/cake-2-0/.  I'm not sure if this issue will be resolved by the time you get your fresh copy, but I immediately see this error:

Fatal error: Class 'Debugger' not found in C:\xampp\htdocs\cake-2-0\cake\libs\view\pages\home.ctp on line 26

To fix this, I had to add the following line in app/config/bootstrap.php:

App::import('Core', 'Debugger');

Reloading now looks a little better.  The next thing we need to do is create a new database and update our database config file.  Create your new database now and rename app/config/database.php.default to database.php.  Open this file and update your information accordingly.

Next, we'll create a new table called "events":

CREATE TABLE `events` (
`title` varchar(255) NOT NULL,
`description` text NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,

Because I'm lazy (or enjoy saving time - depends how you look at it) I decided to use CakePHP's baking console to create my controller, model, and views.  Below is a very quick overview of what I did:

1. Open a command prompt - Start | Run | cmd | <enter>
2. cd \xampp\htdocs\cake-2-0 <enter>
3. cake\console\cake bake <enter>
4. m <enter> - to bake our model
5. <enter> - use our default database config
6. 1 <enter> - bake our Event model
7. n <enter> - don't need validation for our purposes
8. n <enter> - no relationships needed
9. <enter> - our model looks good and can be baked
10. n <enter> - we don't need unit tests created
11. c <enter> - to bake our controller
12. <enter> - use our default database config
13. 1 <enter> - bake our Events controller
14. n <enter> - don't want to bake it interactively
15. y <enter> - we want to bake our basic view functions (add, edit, delete, index)
16. n <enter> - we don't need admin routing
17 <enter> - looks good, bake it
18. n <enter> - we don't need unit tests
19. v <enter> - bake our views
20. <enter> - default database is good
21. 1 <enter> - bake our event views
22. n <enter> - don't want to bake interactively
23 q <enter> - all done

The above is just to quickly create our model, controller, and views with the most basic functionality to get us started.  Feel free to spend more time here if you wish to add validation, create relationships (perhaps to a user table), etc...

Next, we need to create some events so we can paginate through them.  Visit the add page now: http://localhost/cake-2-0/events/add.  I created 10 basic events.  You can grab some fake text from to make your descriptions nice and long.  I did 5 paragraphs for each one.

Now that we have our content, let's alter our controller to only display two events at a time.  Open up app/controllers/events_controller.php and add the following code:

var $paginate = array(
'limit' => 2

This should go above our index() function, beneath the var $name = 'Events'.  Now if we reload our page, our basic table should only display two events and 5 page options beneath it.  Let's continue by altering our app/views/events/index.ctp to not display it in a table listing and make it look more like a flow of events.  Below is my basic HTML to do this, feel free to alter as required:

<div id="newsfeed">
<h2><?php echo __('Events');?>

We now have a basic event listings page.  Next, we need to download Jquery and save it to app/webroot/js/jquery.js.  Let's continue editing our index.ctp and add our basic Javascript to perform the loading of our content when we scroll down.  This is mostly taken from my previous post with a few basic additions:

<?php echo $this->Html->script('jquery', false);?>

If you reload your events list and scroll down, you will see that we are now constantly loading page 2 of our events with each scroll.  This is definitely not optimal.  We don't need new content with every scroll.  Let's alter our Javascript to only load new content every 300 pixels:

<script type="text/javascript">
var lastX = 0;
var currentX = 0;
$(window).scroll(function () {
currentX = $(window).scrollTop();
if (currentX - lastX > 300) {
lastX = currentX;
$.get('events/index/page:2', function(data) {

That's a bit better.  However, you may notice that our full layout is being included every single time we scroll down.  Let's fix this up by adding the following in our events controller:

var $components = array('RequestHandler');

This can go below our previous paginate code, still above our index() function.  Next, let's improve our Javascript to keep track of our pages and load the next page each time we need it.  I found that 300 pixels was a bit too much, so I lowered it to 200 pixels in the code below:

<script type="text/javascript">
var lastX = 0;
var currentX = 0;
var page = 1;
$(window).scroll(function () {
currentX = $(window).scrollTop();
if (currentX - lastX > 200 * page) {
lastX = currentX;
$.get('events/index/page:' + page, function(data) {

If we reload and try again, something isn't quite working right.  Even though we are incrementing the page number, it's still loading page 2 each time.  The reason for this is our entire page is being returned in our Ajax including our Javascript causing it to restart over and over again and always use page 2.  What we want to do in this scenario is to not return our Javascript in our Ajax call.  I'm not sure if this is the best way to do, but it was the simplest I found.  In your events controller, inside of our index() function, add the following line of code after we set our events:

$this->set('isAjax', $this->RequestHandler->isAjax());

Now in our view, we need to not return our Javascript if it is being called through AJAX:

<?php if (!$isAjax):?>

That is much better.  Our pages are being properly loaded each time.  We can even scroll up and down and extra pages are not being requested because of this!

Uh oh, what happens if we scroll down past 5 pages though?  It appears CakePHP is pulling the same last two results over and over again!  To solve this, we need to determine our max pages and ensure we don't perform any more AJAX if our page count exceed this value.  Let's update our index.ctp again:

<?php if (!$isAjax):?>

In the above code we are determining the "maxPages" by using the Paginator counter() function to tell us how many pages there are.  We then update our Javascript to ensure our Javascript "page" variable is less than our max pages.  If it's not, stop loading additional pages through AJAX.

We almost have a completely working example.  One final thing we should do, purely for aestics is to exclude a bit more data from being displayed when we are loading our events via AJAX.  Below is my final code for the index.ctp file that hides a bit more content when our view is being loaded via AJAX:

<?php if (!$isAjax):?>



This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Jamie Munro
Software Developer (Senior)
Canada Canada
I am the author of five books: ASP.NET MVC 5 with Bootstrap and Knockout.js, Knockout.js: Building Dynamic Client-Side Web Applications, 20 Recipes for Programming PhoneGap, 20 Recipes for Programming MVC 3, and Rapid Application Development with CakePHP.

I enjoy reading and writing and I like to blog as much as I can on my personal blog EndYourIf.

I'm a father of three kids, twins (boy and a girl) and another baby girl.

You may also be interested in...


Comments and Discussions

QuestionPlease give me the controller coding of this ajax pagination. Pin
Sradhanjali Behera26-Aug-15 3:08
memberSradhanjali Behera26-Aug-15 3:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.161021.1 | Last Updated 12 May 2015
Article Copyright 2015 by Jamie Munro
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid