Pagination là một class trong Laravel core, nó hỗ trợ chúng ta phân trang dữ liệu trả về trong Database (Query Builder, Elequent ORM) một cách đơn giản và linh hoạt. Điều này trong hầu hết các framework hiện tại mặc định không hỗ trợ.
Mặc đinh Pagination trong Laravel sẽ sử dụng Taiwind CSS
framework và bạn có thể thay đổi nó một cách dễ dàng
1. Sử dụng Pagination
# Đối với Query Builder
paginate($perPage, $columns, $pageName, $page);
Trong đó:
$perPage
– là số lượng item sẽ lấy ra và hiển thị trên mỗi trang. Mặc định sẽ là 15 item trên mỗi trang.$columns
– là những cột sẽ lấy ra trong database. Mặc định sẽ lấy hết (SELETC *
)$pageName
– là tên của query string sẽ chứa tham số page number. Mặc định$pageName = 'page'
.$page
– là item bạn muốn lấy ra là trang số mấy, nếu page là null thì Laravel sẽ xử lý theo data của page query string. Mặc định$page = null
.
Ví dụ: Phân trang 5 User trong bảng users một trang
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;
class UserController extends Controller
{
/**
* Show all of the users for the application.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
return view('user.index', [
'users' => DB::table('users')->paginate(5)
]);
}
}
Trong trường hợp bạn muốn sử dụng pagination dạng đơn giản, chỉ có 2 button là previous và next thì bạn có thể sử dụng phương thức simplePaginate
với cú pháp tương tự như phương thức paginate
$users = DB::table('users')->simplePaginate(15);
# Đối với Eloquent ORM
Đối với trường hợp bạn sử dụng Eloquent thì cú pháp và phương thức cũng tương tự như đối với Query Builder
use App\Models\User;
$users = User::paginate(15);
// Hoặc
$users = User::where('votes', '>', 100)->paginate(15);
# Tự tạo ra phân trang thủ công
Trong trường hợp data của bạn là một dữ liệu không phải được trả về từ Query Builder hoặc Elequent ORM, bạn có thể sử dụng một trong hai class Illuminate\Pagination\Paginator
hoặc Illuminate\Pagination\LengthAwarePaginator
để tạo ra pagination với cú pháp:
use Illuminate\Pagination\Paginator;
$paginate = new Paginator($items, $perPage, $currentPage, $options);
// Hoặc
use Illuminate\Pagination\LengthAwarePaginator;
$paginate = new LengthAwarePaginator($items, $total, $perPage, $currentPage, $options);
Trong đó:
$item
– là mảng data mà bạn muốn phân trang.$total
là tổng số bản ghi có trong item.$perPage
– là số lượng item sẽ lấy ra và hiển thị trên mỗi trang.$currentPage
– là trang dữ liệu bạn muốn lấy ra hiện tại. Mặc định$currentPage = null
.$options
– là các tham số cấu hình thêm cho pagination. Mặc định$options = []
.
Như các bạn đã thấy thì Ở Paginator
không tồn tại tham số $total
vì lớp paginator
này tương tự như simplePaginate
nên nó không cần phải lấy ra tổng số lượng item trong mảng, còn LengthAwarePaginator
thì tương tự như paginate
nên nó cần lấy ra tổng số lượng item để tính toán và hiển thị
Ví dụ:
$students = [
['name' => 'Nguyễn Văn A'],
['name' => 'Nguyễn Văn B'],
['name' => 'Nguyễn Văn C'],
['name' => 'Nguyễn Văn D'],
];
$paginate = new \Illuminate\Pagination\Paginator($students, 2);
# Custom Pagination URL
Mặc định, Laravel sẽ sử dụng link hiện tại để làm URL paginate, nhưng trong trường hợp bạn muốn thay đổi nó, bạn có thể sử dụng phương thức withPath
để thay đổi URL theo ý bạn
Ví dụ: Đổi paginate URL từ /users
thành admin/users
use App\Models\User;
Route::get('/users', function () {
$users = User::paginate(15);
$users->withPath('/admin/users');
//
});
Nếu bạn cần add thêm một vài tham số vào trong URL, bạn có thể sử dụng phương thức appends
để add thêm query string vào URL
Ví dụ: Thêm tham số sort
vào trong URL paginate
use App\Models\User;
Route::get('/users', function () {
$users = User::paginate(15);
$users->appends(['sort' => 'votes']);
//
});
Hoặc bạn có thể sử dụng phương thức withQueryString
để add thêm tất cả các query string trên URL hiện tại vào trong paginate
$users = User::paginate(15)->withQueryString();
Bạn cũng có thể thêm cách hash fragment vào cuối URL trong pagination bằng cách sử dụng phương thức fragment
.
Ví dụ: Thêm #users
vào cuối URL
$users = User::paginate(15)->fragment('users');
2. Hiển thị Pagination Data
Đối với trường hợp các bạn sử dụng phương thức paginate
thì Laravel sẽ trả về LengthAwarePaginator
, simplePaginate
sẽ trả về Paginator
và cả hai phương thức này đều trả về result set như nhau. Các bạn có thể lặp dữ liệu như một array bình thường
Ví dụ: Hiển thị data paginate trong Blade template
<div class="container">
@foreach ($users as $user)
{{ $user->name }}
@endforeach
</div>
{{ $users->links() }}
Trong đó, phương thức links
chính là phương thức sẽ render ra view data hiển thị danh sách các page.
Nếu như bạn return luôn một pagination thì Laravel sẽ tự convert nó về dạng JSON, điều này sẽ rất tiện cho các bạn đang làm API.
JSON object sẽ có dạng như sau:
{
"total": 50,
"per_page": 15,
"current_page": 1,
"last_page": 4,
"first_page_url": "http://laravel.app?page=1",
"last_page_url": "http://laravel.app?page=4",
"next_page_url": "http://laravel.app?page=2",
"prev_page_url": null,
"path": "http://laravel.app",
"from": 1,
"to": 15,
"data":[
{
// Record...
},
{
// Record...
}
]
}
Trong trường hợp bạn không muốn sử dụng pagination view mặc định của Laravel, bạn có thể chỉ định view khác, hoặc thậm chí viết thêm view của bạn. Để thay đổi view bạn chỉ cần truyền view name vào trong phương thức links
{{ $paginator->links('view.name') }}
Hoặc muốn truyền thêm data vào view
{{ $paginator->links('view.name', ['foo' => 'bar']) }}
Bạn có thể export các view mặc định của Laravel ra thư mục resources/views/vendor
để tiện cho việc tham khảo cũng như là chỉnh sửa. Để export view bạn có thể sử dụng command vendor:publish
với tham số --tag=laravel-pagination
php artisan vendor:publish --tag=laravel-pagination
Leave a Comment