Convenient "paginator"

Some time ago, I was puzzled by the search for a solution that would allow replacing the standard "paginator" (CLinkPager) Yii with one that would write something more intelligible instead of page numbers. Say the first characters of the field values ​​on the following pages. I did not find and decided to write my own.



It is extremely inconvenient to switch between numbered pages, say, in the list of users. Especially when the list is big. Each switch when searching for a user for 5-10 pages, as "fortune-telling on coffee grounds". You will either jump the right user, or vice versa, you will be too careful and you won’t reach. Of course, the search helps, but only when you know the last name or other attributes. Even knowing the name does not help, because different Sash, Mash, Dash, Van can be in the table dozens!
The search for a ready-made solution, as I wrote above, did not give anything. Maybe I was looking badly, correct, if not right.

Task


I had to study the structure of CLinkPager and write my own “paginator” class.
The requirements for him were simple:

  • display values, not page numbers
  • display values ​​in whole or fragment
  • display values ​​of only certain fields.

Displaying values, not page numbers, means that you need to display the first field value of each page. In other words, the value of the recording field of the current page, then the value of the recording field of the next page (with an offset equal to the size of the page), etc.
The display of the values ​​in whole or in a fragment means that the conclusion, for example, of the whole surname to the “paginator” is inconvenient. It is much more convenient to derive, say, the first letter, and preferably two, in general, as much as you need.
Displaying the values ​​of only certain fields - means that displaying in “paginator” pieces of field values ​​such as a number or a convenience date will not add, although to whom it is. Therefore, you must specify a list of fields whose values ​​will be displayed in the "pajinator", and for the rest show the usual page numbers.

Decision


I found out that the createPageButtons () function of the CLinkPager class is responsible for rendering the buttons. It’s impossible to selectively override the code for creating certain buttons, so I decided to inherit the class and supplement the code.

Interestingly, the CLinkPager base class turns out to be universal, as it were, "on its own" for any data provider. I had to process two classes of the data provider: CActiveDataProvider , CArrayDataProvider . Each separately.

When working with CActiveDataProvider, I get the values ​​from each page using offset:

if ($this->owner->dataProvider instanceof CActiveDataProvider)
{
	$pagesize = $this->owner->dataProvider->pagination->pagesize;
	$criteria = $this->owner->dataProvider->criteria;
	$this->owner->dataProvider->sort->applyOrder($criteria);
	$criteria->limit = 1;
	for($i=$beginPage;$i<=$endPage;++$i)
	{
		$criteria->offset = $i*$pagesize;
		$m = $this->owner->dataProvider->model->find($criteria);
		$buttons[]=$this->createPageButton(is_null($this->length) ? $m->{$field} : mb_substr($m->{$field}, 0, $this->length, 'utf-8'), $i,$this->internalPageCssClass,false,$i==$currentPage);
	}
}


When working with CArrayDataProvider, I get the values ​​from each page by index:

if ($this->owner->dataProvider instanceof CArrayDataProvider)
{
	$pagesize = $this->owner->dataProvider->pagination->pagesize;
	$data = $this->owner->dataProvider->rawData;
	for($i=$beginPage;$i<=$endPage;++$i)
	{
		$m = $data[$i*$pagesize];
		$buttons[]=$this->createPageButton(is_null($this->length) ? $m[$field] : mb_substr($m[$field], 0, $this->length, 'utf-8'), $i,$this->internalPageCssClass,false,$i==$currentPage);
	}
}


In the class, I declared two variables:
fields - an array of field names for which values ​​should be displayed, not page numbers;
length - the length of the trim value, if null, then the whole.

You can use the class, for example, in CGridView:
'pager'=>array(	
	'class' => 'AlxdTitlePager',
	'fields'=>array('lastname','firstname','middlename','email'),
	'length'=>'2',
	'maxButtonCount'=>10,
	'firstPageLabel'=>'<<',
	'header'=>'',
	'hiddenPageCssClass'=>'disabled',
	'lastPageLabel'=>'>>',
	'nextPageLabel'=>'>',
	'selectedPageCssClass'=>'active',
	'prevPageLabel'=>'<',
	'htmlOptions'=>array('class'=>'pagination')	
)


In general, having run a little code I decided to share it. Anyone interested can get the source code of my AlxdTitlePager class for free.

Also popular now: