20090605

Zend_Paginator with Search Params

I have noticed a couple posts out there asking how to incorporate a search with the Zend_Paginator component so that the search params follow along. Here is one way to do it, assuming we are searching for a person in our database.

1. Set up the action to capture the parameters

2. Set up our router to accept the params

3. Modify the example paginator view partial

4. Pass the search params to the paginatorControl view helper


1. Set up the action to capture the parameters


Throughout this example I assume that the search form is labeled 'search'.
public function listAction()
{
$form = new My_Form_Search();

//figure out what page they want to be on with a default of 1
$page = (int)$this->_getParam('page', 1);
$recordsPerPage=15;

//set up our default search
$model = new Default_Model_Person();
$select = $model->select();

//capture the input params
if ($this->_request->getParam('search',0) || $this->_request->isPost()){

//if it is a post, populate the form and reset the page to 1
if ($this->_request->isPost()){
$form->populate($this->_request->getPost());
$page = 1;
}
else{ //'search' showed up via the GET param
$form->populate($this->_request->getParams());
}
//make sure the submitted data is valid and modify select statement
if ($form->valid()){
$search = $form->getValue('search');
$select->where('name like ?',$search.'%');
}
}

//set up the paginator with our select query
$paginator = new Zend_Paginator(new Zend_Paginator_Adapter_DbTableSelect($select));

$paginator->setCurrentPageNumber($page);
$paginator->setItemCountPerPage($recordsPerPage);

//set our view parameters. the third one (searchParams) is
// the key difference from a lot of the other examples out there
$this->view->paginator = $paginator;
$this->view->form = $form;
$this->view->searchParams = array('search'=>$form->getValue('search'));
}

2. Set up our router to accept the params


<config>
<people_path>
<route>people/:page/:search</route>
<defaults>
<module>people</module>
<controller>index</controller>
<action>list</action>
<page>1</page>
<search/><!-- by default the search param is empty -->
</defaults>
<reqs>
<page>\d+</page>
</reqs>
</people_path>
</config>

3. Modify the example paginator view partial


You need to add the search param to the url router on the view partial. Find the relevant lines and toss in the search param to the param array:

<a href="<?php echo  $this->url(array('page' => $this->previous, 'search'=> $this->search)); ?>">
<a href="<?php echo $this->url(array('page' => $page, 'search'=> $this->search)); ?>">
<a href="<?php echo $this->url(array('page' => $this->next, 'search'=> $this->search)); ?>">

4. Pass the search params to the paginatorControl view helper


A little known fact is that you can pass in a fourth parameter to the paginatorControl view helper. We want to give it our search params that we defined above:
echo $this->paginationControl($this->paginator,'Elastic','pagination_control.phtml',$this->searchParams);

And you should be good to go!