Pagination using Zend_Paginator

Any web application that retrieves large amounts of data for display is bound to have the need to split that data over several pages. Developing the code to do this from scratch is not trivial, so it is extremely useful that the Zend Framework has the Zend_Paginator module, which assists with this task.

Zend_Paginator works as follows:

1. The paginator is passed either an actual set of data, or a database query that can be used to retrieve the data.
2. The paginator will by default retrieve the first page and 10 items on that page; the page and the items per page can be set at this point if necessary.
3. The paginator can be used to render a navigator, by retrieving the current page and the number of pages.
4. The paginator can be used to render the current page, by iterating over the paginator to retrieve each item in order.

I shall give a concrete example of how this can be implemented below, based on an application I am currently developing.

First, let us start with the controller. In this instance, the controller is user and the action is index. The skeleton for this code is as follows:


class UserController extends Zend_Controller_Action
{
public function indexAction()
{
// Insert implementation here
}
}


The current page will be passed via the URL as a parameter. The first task in the action handler is therefore to retrieve the page number. If it is not specified, it will default to 1.


// Get the current page
$page = $this->getRequest()->getParam('page', 1);


The next step is to construct a Zend_Db_Select object that represents the database query. To do this we need a database adapter; below, we assume that this has been created during the bootstrapping process and can be retrieved via the bootstrap object. The query simply retrieves all records from the user table, ordering them by the user’s display name.


// Get the boostrap object
$bootstrap = $this->getInvokeArg('bootstrap');

// Get the database adapter
$dbAdapter = $bootstrap->getResource('db');

// Create the selection object
$select = $dbAdapter->select()->from('user')->order('name');


Now we have the select object, we can use it to create the paginator object.


// Get a Paginator object using Zend_Paginator's built-in factory
$paginator = Zend_Paginator::factory($select);


We can then set the number of items per page and the current page.


// Set the number of items to show per page
$paginator->setItemCountPerPage(5);

// Select the requested page
$paginator->setCurrentPageNumber($page);


Finally, we should pass the paginator object to the view script.


$this->view->paginator = $paginator;


The view script used is given below. Note that the application uses Zend_Layout, so only the unique content of the page needs to be generated here.


<h3>User Management</h3>

<?php
// Display pagination control
echo $this->paginationControl($this->paginator, 'Elastic', 'paginator.phtml');
?>
<table>
<thead>
<tr>
<th width="25%">Username</th>
<th width="25%">Role</th>
<th width="50%">Name</th>
</tr>
</thead>
<tbody>
<?php
// Render each item for the current page in a table row
foreach ($this->paginator as $item)
{
?>
<tr>
<td><?php echo $this->escape($item['username']); ?></td>
<td><?php echo $this->escape(ucfirst($item['role'])); ?></td>
<td><?php echo $this->escape($item['name']); ?></td>
</tr>
<?php
}
?>
</tbody>
</table>


The script uses the PaginationControl view helper to render the navigator. The view script for the navigator markup is specified as one of the parameters as paginator.phtml; this script is found in the /application/views/scripts directory. The following standard script is used:


<?php if ($this->pageCount): ?>
<div class="paginator">

<!-- First page link -->
<?php if (isset($this->previous)): ?>
<a href="<?php echo $this->url(array('page' => $this->first)); ?>">
First
</a> |
<?php else: ?>
<span class="disabled">First</span> |
<?php endif; ?>

<!-- Previous page link -->
<?php if (isset($this->previous)): ?>
<a href="<?php echo $this->url(array('page' => $this->previous)); ?>">
< Previous
</a> |
<?php else: ?>
<span class="disabled">< Previous</span> |
<?php endif; ?>

<!-- Next page link -->
<?php if (isset($this->next)): ?>
<a href="<?php echo $this->url(array('page' => $this->next)); ?>">
Next >
</a> |
<?php else: ?>
<span class="disabled">Next ></span> |
<?php endif; ?>

<!-- Last page link -->
<?php if (isset($this->next)): ?>
<a href="<?php echo $this->url(array('page' => $this->last)); ?>">
Last
</a>
<?php else: ?>
<span class="disabled">Last</span>
<?php endif; ?>

</div>
<?php endif; ?>


The section used to render the current page as a table makes use of the fact that the paginator object can be iterated over to retrieve each item on the current page in turn.

The following styling is applied to the navigator:


.paginator { padding: 5px; }


The following styling is applied to the table:


table { width: 100%; }

th, td { padding: 5px; }

th { background-color: #4E7DD1; color: #FFFFFF; }




Courtesy:GM-RAM


No comments:

Post a Comment