CakePHP, EXTJS DataGrid, and Paging
I was asked earlier if it was possible to use the datagrid with cake 1.2’s paginator. I did some checking, and I don’t think it is. The paginate function is closely tied to the paginate helper. When you call paginate in the controller, all I ever got back was the same results as findAll.
Fear not, however, because pagination with the datagrid is fairly painless. If you don’t have a working datagrid already, please work through my earlier tutorial first.
Ok, to add pagination, we first have to change our getAllUsers controller function. Change the definition to this:
function getAllUsers($limit=10, $page=0)
Page and Limit are how the model knows which chunk of data to pull from the database. We are just setting some defaults.
Now add the following lines inside the controller (I put mine right after the Configure::write line):
if(!empty($_POST['limit'])) $limit = $_POST['limit']; if(!empty($_POST['start'])) $page = ($_POST['start']/$limit)+1;
ExtJS uses posts to send the paging params to cake. The problem is, it sends limit and start, while we need limit and page. The first part just checks to see if $_POST[’limit’] is empty, and if it isn’t, it assigns it to $limit. The second part is similar, but more complicated. For ExtJS, start is which record to start with. If we divide start by limit, we should get the page we are on. However, it didn’t work quite right. By adding 1 to the total, things now work.
Now, change the definition of $userA to read like this:
$userA = $this->User->findAll(null,'*','id ASC', $limit, $page); //gets all the User records and sorts them by username alphabetically.
Note - I left this out the first time. Thanks, Yoris, for catching this.
OK, that takes care of the controller, now we just need to modify myScript.js a little bit. Modify your grid code to look like this:
grid = new Ext.grid.GridPanel({ ds: ds, columns: [ {id:'id',header: "ID", width: 50, sortable: true, dataIndex: 'id'}, {header: "Username", width: 125, sortable: true, dataIndex: 'username'}, {header: "Full name", width: 125, sortable: true, dataIndex: 'fullname'} ], cm: cm, stripeRows: true, height: 350, width: 350, title: 'Data Grid', bbar: new Ext.PagingToolbar({ pageSize: 10, store: ds, displayInfo: true, displayMsg: 'Displaying users {0} - {1} of {2}', emptyMsg: 'No users to display' }) });
bbar is what we are adding (I think it means bottom bar). Page size is the same as limit (I think). The rest is just configuration. Now change your ds.load command to look like this:
ds.load({params:{start:0, limit:10}}); //This loads data from the database into the datastore.
That’s it! You should now have a paging bar at the bottom.