Any easy way to limit how many links are shown with Laravels pagination?
Currently it shows 13 links at most (Prev, 1 2 3 4 5 7 8 .. 78 79 next)
This however
The old way of defining a custom presenter doesn't work with Laravel 5.3+, the number of links shown seems to be hard-coded in the $onEachSide
parameter of Illuminate/Pagination/UrlWindow::make()
:
public static function make(PaginatorContract $paginator, $onEachSide = 3)
I ended up just writing my own render() function, stealing some code from LengthAwarePaginator
/**
* Stole come code from LengthAwarePaginator::render() and ::elements() to allow for a smaller UrlWindow
*
* @param LengthAwarePaginator $paginator
* @param int $onEachSide
* @return string
*/
public static function render(LengthAwarePaginator $paginator, $onEachSide = 2)
{
$window = UrlWindow::make($paginator, $onEachSide);
$elements = array_filter([
$window['first'],
is_array($window['slider']) ? '...' : null,
$window['slider'],
is_array($window['last']) ? '...' : null,
$window['last'],
]);
return LengthAwarePaginator::viewFactory()->make(LengthAwarePaginator::$defaultView, [
'paginator' => $paginator,
'elements' => $elements,
])->render();
}
}
We use Twig, so I registered this as a Twig filter, I imagine something similar could be done for Blade.
Create one file default.blade.php in new pagination folder in view folder with below code. That means you have override core pagination file with our new pagination file. That will set some limit in pagination link.
@if ($paginator->hasPages())
<ul class="pagination pagination">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="disabled"><span>«</span></li>
@else
<li><a href="{{ $paginator->previousPageUrl() }}" rel="prev">«</a></li>
@endif
@if($paginator->currentPage() > 3)
<li class="hidden-xs"><a href="{{ $paginator->url(1) }}">1</a></li>
@endif
@if($paginator->currentPage() > 4)
<li><span>...</span></li>
@endif
@foreach(range(1, $paginator->lastPage()) as $i)
@if($i >= $paginator->currentPage() - 2 && $i <= $paginator->currentPage() + 2)
@if ($i == $paginator->currentPage())
<li class="active"><span>{{ $i }}</span></li>
@else
<li><a href="{{ $paginator->url($i) }}">{{ $i }}</a></li>
@endif
@endif
@endforeach
@if($paginator->currentPage() < $paginator->lastPage() - 3)
<li><span>...</span></li>
@endif
@if($paginator->currentPage() < $paginator->lastPage() - 2)
<li class="hidden-xs"><a href="{{ $paginator->url($paginator->lastPage()) }}">{{ $paginator->lastPage() }}</a></li>
@endif
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li><a href="{{ $paginator->nextPageUrl() }}" rel="next">»</a></li>
@else
<li class="disabled"><span>»</span></li>
@endif
</ul>
@endif
Then Where you want to get pagination then you have to call laravel pagination function with this view file parameter.
$data->links('pagination.default')
I know it's an old question but there is still no way to set in using function links() parameters. I made simple jQuery code, maybe it will help someone. It's much simplier than Zesky's answer. I don't mean better, just simplier :)
JavaScript:
(function($) {
$('ul.pagination li.active')
.prev().addClass('show-mobile')
.prev().addClass('show-mobile');
$('ul.pagination li.active')
.next().addClass('show-mobile')
.next().addClass('show-mobile');
$('ul.pagination')
.find('li:first-child, li:last-child, li.active')
.addClass('show-mobile');
})(jQuery);
CSS:
@media (max-width: /* write what you need, for me it's 560px */) {
ul.pagination li:not(.show-mobile) {
display: none;
}
}
This code make visible only few li elements. Active, two before, two after, prev/next arrows. That make only 7 visible elements at most instead of 15.
I used css to limit the links that I allowed. Really simple.. this can be extended to show any number of pages, at any number of breakpoints
@media screen and ( max-width: 400px ){
li.page-item {
display: none;
}
.page-item:first-child,
.page-item:nth-child( 2 ),
.page-item:nth-last-child( 2 ),
.page-item:last-child,
.page-item.active,
.page-item.disabled {
display: block;
}
}
this specific implementation allows the arrows, the '...', the first page, active page and last page
It's an old question, but just thought I'd share how I've recently achieved reducing the number of pagination links in a Laravel 5.2 application:
Inside your ViewServiceProvider
:
\Illuminate\Pagination\AbstractPaginator::presenter(function($paginator) {
return new \App\Pagination\BootstrapPresenter($paginator);
});
<?php namespace App\Pagination;
use Illuminate\Pagination\UrlWindow;
use Illuminate\Contracts\Pagination\Paginator as PaginatorContract;
use Illuminate\Pagination\BootstrapThreePresenter as LaravelBootstrapThreePresenter;
class BootstrapPresenter extends LaravelBootstrapThreePresenter
{
/**
* Create a new Bootstrap presenter instance.
*
* @param \Illuminate\Contracts\Pagination\Paginator $paginator
* @param \Illuminate\Pagination\UrlWindow|null $window
* @return void
*/
public function __construct(PaginatorContract $paginator, UrlWindow $window = null)
{
$this->paginator = $paginator;
// Make the pagination window smaller (default is 3).
$this->window = UrlWindow::make($paginator, 1);
}
}
From:
To: