Foreword:
Explain what we are going to talk about in this article
How to use pagination, teach you step by step
What attributes can be customized for both the paging classes LinkPager and Pagination
How to extend the paging class LinkPager to what we need
The first step, let’s take a look at how to use the paging class that comes with yii2?
1. controller action
use yii\data\Pagination; $query = Article::find()->where(['status' => 1]); $countQuery = clone $query; $pages = new Pagination(['totalCount' => $countQuery->count()]); $models = $query->offset($pages->offset) ->limit($pages->limit) ->all(); return $this->render('index', [ 'models' => $models, 'pages' => $pages, ]);
2. View
use yii\widgets\LinkPager; //循环展示数据 foreach ($models as $model) { // ...... } //显示分页页码 echo LinkPager::widget([ 'pagination' => $pages, ])
The code can basically be completely copied and some data can be modified. I believe most people can understand it.
Let’s look at the second step. What attributes can be defined in the built-in paging class
First let’s talk about the LinkPager component
.pagination parameter is required. This is an instance of our Pagination class
The default paging class looks like this
. Up and down page buttons and 10 buttons
First, we change the buttons for the previous and next pages to Chinese
<?= LinkPager::widget([ 'pagination' => $pages, 'nextPageLabel' => '下一页', 'prevPageLabel' => '上一页', ]); ?>
If you don’t want to display the previous and next pages, you can set prevPageLabel and nextPageLabel to false
<?= LinkPager::widget([ 'pagination' => $pages, 'nextPageLabel' => false, 'prevPageLabel' => false, ]); ?>
The home page and last page are not displayed by default. If you need, you can set it like this
<?= LinkPager::widget([ 'pagination' => $pages, 'firstPageLabel' => '首页', 'lastPageLabel' => '尾页', ]); ?>
If your data is too small, not enough for 2 pages, paging will not be displayed by default. If you need it, just set hideOnSinglePage=false
<?= LinkPager::widget([ 'pagination' => $pages, 'hideOnSinglePage' => false, ]); ?>
The default displayed page number is 10 pages, you can set maxButtonCount to the number of pages you want to display
<?= LinkPager::widget([ 'pagination' => $pages, 'maxButtonCount' => 5, ]); ?>
Some people don’t like the default style and want to have their own style for pagination. You can set options. Don’t forget to implement pre, next, disabled and other styles by yourself
<?= LinkPager::widget([ 'pagination' => $pages, 'options' => ['class' => 'm-pagination'], ]); ?>
Next let’s talk about the Pagination component
The default paging route is as follows, let’s see what we can do
/controller/action?page=2&per-page=20
First of all, we must specify the total number of items totalCount. Without this parameter, paging cannot be achieved
$pages = new Pagination([ 'totalCount' => $totalCount, ]);
The default number of pages is 20, you can set pageSize to what you want
$pages = new Pagination([ 'totalCount' => $totalCount, 'pageSize' => 5, ]);
We can see from the paging route above that the default number per page is per-page. If you don’t want to display this parameter, just set pageSizeParam=false
$pages = new Pagination([ 'totalCount' => $totalCount, 'pageSizeParam' => false, ]);
We can also see that the default page depends on the parameter page. If you want to change the parameter to p, just set pageParam=p
$pages = new Pagination([ 'totalCount' => $totalCount, 'pageParam' => 'p', ]);
If your pagination exists on the homepage, I believe you definitely want /?p=1 instead of /site/index?p=1. Let’s see how to hide the route
$pages = new Pagination([ 'totalCount' => $totalCount, 'route' => false, ]);
Maybe you will find a bug in the paging class Pagination. Suppose we only have 1 page of data, but when we manually change page=20 in the address bar, will the data of page=1 also be displayed? Of course, this is annoying in most interface APIs. However, this is not a bug, but a friendly verification. Set validatePage=false to avoid this problem
$pages = new Pagination([ 'totalCount' => $totalCount, 'validatePage' => false, ]);
Finally, let’s add a new twist and expand its built-in paging! Don’t just stop reading as soon as you see the word “expansion”. Only when you learn to expand can you become stronger and stronger in the future! What kind of expansion method? Let’s change the paging component to a top and bottom page. Please refer to the picture below for comparison
Next let’s take a look at how the effect on the right is achieved by extending the LinkPager component. The source code is shared with everyone. If you like it, you can use it to study it yourself.
<?php namespace frontend\components; use yii\widgets\LinkPager; use yii\helpers\Html; class MLinkPager extends LinkPager { public $prevPageLabel = '<i class="fa fa-angle-left"></i>'; public $nextPageLabel = '<i class="fa fa-angle-right"></i>'; public $currentCountPageLabel = '第 {currentPage} 页 / 共 {countPage} 页'; public $currentCountPageClass = 'page-number'; public $hideOnSinglePage = false; public function init () { parent::init(); } public function run () { $pageCount = $this->pagination->getPageCount(); if ($pageCount < 2 && $this->hideOnSinglePage) { return ''; } $buttons = []; $currentPage = $this->pagination->getPage(); // prev page if ($this->prevPageLabel !== false) { if (($page = $currentPage - 1) < 0) { $page = 0; } $buttons[] = $this->renderPageButton($this->prevPageLabel, $page, $this->prevPageCssClass, $currentPage <= 0, false); } // current page / count page if ($this->currentCountPageLabel !== false && $pageCount) { $currentCountPageLabel = str_replace(['{currentPage}', '{countPage}'], [$currentPage+1, $pageCount], $this->currentCountPageLabel); $buttons[] = Html::tag('span', $currentCountPageLabel, array('class' => $this->currentCountPageClass)); } // next page if ($this->nextPageLabel !== false) { if (($page = $currentPage + 1) >= $pageCount - 1) { $page = $pageCount - 1; } $buttons[] = $this->renderPageButton($this->nextPageLabel, $page, $this->nextPageCssClass, $currentPage >= $pageCount - 1, false); } return Html::tag('nav', implode("\n", $buttons), $this->options); } protected function renderPageButton($label, $page, $class, $disabled, $active) { $options = ['class' => empty($class) ? $this->pageCssClass : $class]; if ($active) { Html::addCssClass($options, $this->activePageCssClass); } if ($disabled) { return false; } $linkOptions = $this->linkOptions; $linkOptions += $options; $linkOptions['data-page'] = $page; return Html::a($label, $this->pagination->createUrl($page), $linkOptions); } }
In this way, we call MLinkPager to achieve the paging effect as follows
use frontend\components\MLinkPager; <?= MLinkPager::widget([ 'pagination' => $pages, ]); ?>
Of course, the focus of the self-expanded paging structure is to teach everyone how to implement paging expansion. It is inevitable that there will be many questions. If you have good opinions or methods, please leave me a message directly and we can communicate together.