Laravel Pagination 分頁功能

1. 基本使用

eg:每次顯示15個

$row = User::paginate(15);
1.1帶上原本現有url 的query功能 withQueryString()

有時你的網址可能會同時有其他query, 比如搜尋頁面,分類頁面等等,加上withQueryString()就可

        $row = User::where('name', 'LIKE', "%{$search}%")
            ->paginate(15)
            ->withQueryString();

這樣一來,你轉頁時得到的網址就是類似如下: xxx.com/user/keyword=xxx&page=2

1.2fragment() 加上錨點

withQueryString()就可

        $row = User::where('name', 'LIKE', "%{$search}%")
            ->paginate(15)
            ->fragment('user_data')
            ->withQueryString();

這樣一來,你轉頁時得到的網址就是類似如下: xxx.com/user/keyword=xxx&page=2#user_data

2. 顯示輸出 及 設定樣式

在balde直接用$row->links()就能顯示

注:不要放在foreach內

2.1 預設樣式是 Tailwindcss, 你可手動改為 Bootstrap
//app/Providers/AppServiceProvider.php 

use Illuminate\Pagination\Paginator;

    public function boot(){

        Paginator::useBootstrap();
    }

這樣一設定就會把原本的 tailwindcss 切換為 Bootstrap

2.2 使用指自定的格式/排版

我有時前台是tailwindcss 而後台是 bootstrap,我會用以下方法

執行一下vendor:publish

php artisan vendor:publish --tag=laravel-pagination

這個路徑就是 Laravel 內置的格式/排版 resources/views/vendor/pagination

內置文件我一般不用搞他,那麼我就找到2個常用的copy一份出去 resources/views/vendor/pagination/bootstrap-4.blade.php resources/views/vendor/pagination/tailwind.blade.php

分別把他們放到 resources/views/common/pagination/tailwind.blade.php resources/views/common/pagination/bootstrap-4.blade.php

然後去 blade 把$row 改一改

{!! $row->links('common.pagination.bootstrap-4') !!}
//or
{!! $row->links('common.pagination.tailwind') !!}

這樣一來在有需要的地方就能做對應的設定,比如前台我是用tailwind就可設定分頁用tailwind,反之後台如何是用bootstrap就引入 bootstrap!

當然如果前後台一樣的你可用 2.1 方法1去做決定是否需要切換至 bootstrap

2.3 onEachSide()
{!! $row->onEachSide(5)->links('common.pagination.tailwind') !!}

onEachSide() 是指 當前頁面的左右兩邊分別顯示多少個分頁鏈結,我不太清楚是版本還是我的設定問題,我發現不管是tailwindcss 或 bootstrap 都都是太準確,或者官方的排版格式有些問題

相信的確是有多少問題,所以網上有不少人分享了他們的修正版,使用了之後排版顯示的數量會合理很多,大家可取以下的代碼,是我收集及整理到的

ref: https://laracasts.com/discuss/channels/general-discussion/limit-the-pagination-link-amount

2.3.1 bootstrap版

//resources/views/common/pagination/bootstrap.blade.php

@if ($paginator->hasPages())
<ul class="pagination" role="navigation">
    {{-- Previous Page Link --}}
    @if ($paginator->onFirstPage())
        <li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.previous')">
            <span class="page-link" aria-hidden="true">&lsaquo;</span>
        </li>
    @else
        <li class="page-item">
            <a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')">&lsaquo;</a>
        </li>
    @endif

    <?php
        $start = $paginator->currentPage() - 2; // show 3 pagination links before current
        $end = $paginator->currentPage() + 2; // show 3 pagination links after current
        if($start < 1) {
            $start = 1; // reset start to 1
            $end += 1;
        } 
        if($end >= $paginator->lastPage() ) $end = $paginator->lastPage(); // reset end to last page
    ?>

    @if($start > 1)
        <li class="page-item">
            <a class="page-link" href="{{ $paginator->url(1) }}">{{1}}</a>
        </li>
        @if($paginator->currentPage() != 4)
            {{-- "Three Dots" Separator --}}
            <li class="page-item disabled" aria-disabled="true"><span class="page-link">...</span></li>
        @endif
    @endif
        @for ($i = $start; $i <= $end; $i++)
            <li class="page-item {{ ($paginator->currentPage() == $i) ? ' active' : '' }}">
                <a class="page-link" href="{{ $paginator->url($i) }}">{{$i}}</a>
            </li>
        @endfor
    @if($end < $paginator->lastPage())
        @if($paginator->currentPage() + 3 != $paginator->lastPage())
            {{-- "Three Dots" Separator --}}
            <li class="page-item disabled" aria-disabled="true"><span class="page-link">...</span></li>
        @endif
        <li class="page-item">
            <a class="page-link" href="{{ $paginator->url($paginator->lastPage()) }}">{{$paginator->lastPage()}}</a>
        </li>
    @endif

    {{-- Next Page Link --}}
    @if ($paginator->hasMorePages())
        <li class="page-item">
            <a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')">&rsaquo;</a>
        </li>
    @else
        <li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.next')">
            <span class="page-link" aria-hidden="true">&rsaquo;</span>
        </li>
    @endif
</ul>
@endif
2.3.1 tailwind版

//resources/views/common/pagination/tailwind.blade.php

@if ($paginator->hasPages())
{{--    Custom default component--}}
    <nav role="navigation" aria-label="{{ __('Pagination Navigation') }}" class="flex items-center justify-center">
        <span class="relative z-0 inline-flex shadow-sm rounded-md">
            {{-- Previous Page Link --}}
            @if ($paginator->onFirstPage())
                <span aria-disabled="true" aria-label="{{ __('pagination.previous') }}">
                    <span class="relative inline-flex items-center px-1 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default rounded-l-md leading-5" aria-hidden="true">
                        <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
                            <path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
                        </svg>
                    </span>
                </span>
            @else
                <a href="{{ $paginator->previousPageUrl() }}" rel="prev" class="relative inline-flex items-center px-1 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-l-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150" aria-label="{{ __('pagination.previous') }}">
                    <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
                        <path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
                    </svg>
                </a>
            @endif

            {{-- Pagination Elements --}}
            @if($paginator->currentPage() > 2)
                <a href="{{ $paginator->url(1) }}" class="relative inline-flex items-center px-3 py-2 -ml-px text-sm font-medium text-success bg-white border border-gray-300 leading-5 hover:text-black hover:bg-gray-100 focus:z-10 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150" aria-label="{{ __('Go to page :page', ['page' => 1]) }}">
                    1
                </a>
            @endif
            @if($paginator->currentPage() > 3)
                {{-- "Three Dots" Separator --}}
                <span aria-disabled="true">
                    <span class="relative inline-flex items-center p-2 -ml-px text-sm font-medium text-gray-700 bg-white border border-gray-300 cursor-default leading-5">...</span>
                </span>
            @endif
            @foreach(range(1, $paginator->lastPage()) as $i)
                @if($i >= $paginator->currentPage() - 1 && $i <= $paginator->currentPage() + 1)
                    @if ($i == $paginator->currentPage())
                        <span aria-current="page">
                            <span class="relative inline-flex items-center px-3 py-2 -ml-px text-sm font-medium badge-success border border-gray-300 cursor-default leading-5">{{ $i }}</span>
                        </span>
                    @else
                        <a href="{{ $paginator->url($i) }}" class="relative inline-flex items-center px-3 py-2 -ml-px text-sm font-medium text-success bg-white border border-gray-300 leading-5 hover:text-black hover:bg-gray-100 focus:z-10 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150" aria-label="{{ __('Go to page :page', ['page' => $i]) }}">
                            {{ $i }}
                        </a>
                    @endif
                @endif
            @endforeach
            @if($paginator->currentPage() < $paginator->lastPage() - 2)
                {{-- "Three Dots" Separator --}}
                <span aria-disabled="true">
                    <span class="relative inline-flex items-center p-2 -ml-px text-sm font-medium text-gray-700 bg-white border border-gray-300 cursor-default leading-5">...</span>
                </span>
            @endif
            @if($paginator->currentPage() < $paginator->lastPage() - 1)
                <a href="{{ $paginator->url($paginator->lastPage()) }}" class="relative inline-flex items-center px-3 py-2 -ml-px text-sm font-medium text-success bg-white border border-gray-300 leading-5 hover:text-black hover:bg-gray-100 focus:z-10 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150" aria-label="{{ __('Go to page :page', ['page' => $paginator->lastPage()]) }}">
                    {{ $paginator->lastPage() }}
                </a>
            @endif

            {{-- Next Page Link --}}
            @if ($paginator->hasMorePages())
                <a href="{{ $paginator->nextPageUrl() }}" rel="next" class="relative inline-flex items-center px-1 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-r-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150" aria-label="{{ __('pagination.next') }}">
                    <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
                        <path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
                    </svg>
                </a>
            @else
                <span aria-disabled="true" aria-label="{{ __('pagination.next') }}">
                    <span class="relative inline-flex items-center px-1 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default rounded-r-md leading-5" aria-hidden="true">
                        <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
                            <path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
                        </svg>
                    </span>
                </span>
            @endif
        </span>
    </nav>
@endif