Pagination is very useful when you have to show a huge list of records on the page. It divides the records into multiple pages.
Limited number of records shown at a time.
Livewire has provided the WithPagination
trait for generating pagination. Its implementation is similar to Laravel default pagination.
In this tutorial, I show how you can create Livewire pagination with search filter and sorting in Laravel 9.
Contents
- Add Database configuration
- Create a Table
- Create Model
- Create Controller
- Create Route
- Create Livewire Component
- Create View
- Output
- Conclusion
1. Add Database configuration
Open .env
file to update the database connection.
Specify the host, database name, username, and password.
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=tutorial DB_USERNAME=root DB_PASSWORD=
2. Create a Table
- Create a table
employees
using migration.
php artisan make:migration create_employees_table
- Now, navigate to
database/migrations/
folder from the project root. - Find a PHP file that ends with
create_employees_table
and open it. - Define the table structure in the
up()
method.
public function up() { Schema::create('employees', function (Blueprint $table) { $table->id(); $table->string('emp_name',60); $table->string('email',80); $table->string('gender',20); $table->string('city',100); $table->smallInteger('status',2); $table->timestamps(); }); }
- Run the migration –
php artisan migrate
- The table is been created and I added some records to it.
3. Create Model
- Create
Employees
Model –
php artisan make:model Employees
- Open
app/Models/Employees.php
file. - Specify mass assignable Model attributes – emp_name, email, gender, city, and status using the
$fillable
property.
Completed Code
<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Employees extends Model { use HasFactory; protected $fillable = [ 'emp_name','email','gender','city','status' ]; }
4. Create Controller
- Create
EmployeesController
controller.
php artisan make:controller EmployeesController
- Open
app\Http\Controllers\EmployeesController.php
file. - Create 1 method –
- index() – Load
index
view.
- index() – Load
Completed Code
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class EmployeesController extends Controller { public function index(){ return view('index'); } }
5. Create Route
- Open
routes/web.php
file. - Define 1 route –
- / – Load index view.
<?php use Illuminate\Support\Facades\Route; use App\Http\Controllers\EmployeesController; Route::get('/', [EmployeesController::class, 'index']);
6. Create Livewire Component
Create emp-pagination
component –
php artisan make:livewire emp-pagination
This will create 2 files –
- app/Http/Livewire/EmpPagination.php
- resources/views/livewire/emp-pagination.blade.php
app/Http/Livewire/EmpPagination.php
- Include
Livewire\WithPagination
trait andApp\Models\Employees
model. - Create 5 property variables –
- $paginationTheme – Livewire pagination by default uses Tailwind CSS. If you are using Bootstrap in your project then you can change it to bootstrap using
$paginationTheme
property. - $orderColumn – Store sorting order column name. I set it to
emp_name
. - $sortOrder – Store sorting order – asc or desc.
- $sortLink – Use to store sorting icon.
- $searchTerm – Use for data binding.
- $paginationTheme – Livewire pagination by default uses Tailwind CSS. If you are using Bootstrap in your project then you can change it to bootstrap using
- Class methods –
- updated() – Using this reset the pagination layout while searching.
- sortOrder() – Using this method update values of order by.
This method takes column name as parameter. If sortOrder == 'asc'
then assign desc
to $this->sortOrder
and down
to $caretOrder
otherwise, assign asc
to $this->sortOrder
and up
to $caretOrder
.
Update $sortLink
icon and assign $columnName
to $this->orderColumn
.
-
- render() – Fetch records from the
employees
table. Here, use$this->orderColumn
and$this->sortOrder
for sorting records.
- render() – Fetch records from the
If $searchTerm
is not empty then search on emp_name
and city
fields using like
. Generate pagination by calling paginate(10)
. You can change the number from 10 to 5,15,25, etc according to your requirement.
Load livewire.emp-pagination
view and pass $employees
.
Completed Code
<?php namespace App\Http\Livewire; use Livewire\Component; use Livewire\WithPagination; use App\Models\Employees; class EmpPagination extends Component { use WithPagination; protected $paginationTheme = 'bootstrap'; public $orderColumn = "emp_name"; public $sortOrder = "asc"; public $sortLink = '<i class="sorticon fa-solid fa-caret-up"></i>'; public $searchTerm = ""; public function updated(){ $this->resetPage(); } public function sortOrder($columnName=""){ $caretOrder = "up"; if($this->sortOrder == 'asc'){ $this->sortOrder = 'desc'; $caretOrder = "down"; }else{ $this->sortOrder = 'asc'; $caretOrder = "up"; } $this->sortLink = '<i class="sorticon fa-solid fa-caret-'.$caretOrder.'"></i>'; $this->orderColumn = $columnName; } public function render(){ $employees = Employees::orderby($this->orderColumn,$this->sortOrder)->select('*'); if(!empty($this->searchTerm)){ $employees->orWhere('emp_name','like',"%".$this->searchTerm."%"); $employees->orWhere('city','like',"%".$this->searchTerm."%"); } $employees = $employees->paginate(10); return view('livewire.emp-pagination', [ 'employees' => $employees, ]); } }
resources/views/livewire/emp-pagination.blade.php
- Create a text element for searching. Add
wire:model="searchTerm"
to it. - Create
<table >
and if$employees
have records then loop on$employees
to create new<tr>
. If not then showNo record found
message. - For sorting add
wire:click
on header column that callssortOrder()
. Here, pass the column name. - Add
{!! $sortLink !!}
to display sort order icon. - Show pagination links using –
$employees->links()
.
Completed Code
<div> <div class="container"> <div class="row mt-5"> <div class="col-md-12"> <!-- Search box --> <input type="text" class="form-control" placeholder="Search Name or city" style="width: 250px;" wire:model="searchTerm" > <!-- Paginated records --> <table class="table"> <thead> <tr> <th class="sort" wire:click="sortOrder('emp_name')">Name {!! $sortLink !!}</th> <th class="sort" wire:click="sortOrder('email')">Email {!! $sortLink !!}</th> <th class="sort" wire:click="sortOrder('gender')">Gender {!! $sortLink !!}</th> <th class="sort" wire:click="sortOrder('city')">City {!! $sortLink !!}</th> <th>Status</th> </tr> </thead> <tbody> @if ($employees->count()) @foreach ($employees as $employee) <tr> <td>{{ $employee->emp_name }}</td> <td>{{ $employee->email }}</td> <td>{{ $employee->gender }}</td> <td>{{ $employee->city }}</td> <td>{{ $employee->status }}</td> </tr> @endforeach @else <tr> <td colspan="5">No record found</td> </tr> @endif </tbody> </table> <!-- Pagination navigation links --> {{ $employees->links() }} </div> </div> </div> </div>
7. Create View
Create index.blade.php
file in resources/views/
folder.
Include emp-pagination
component and also include livewire style and script.
Completed Code
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Create Livewire pagination with search filter and sorting in Laravel</title> <!-- Fontawesome --> <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css"> <!-- Bootstrap --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" > @livewireStyles <style type="text/css"> .sorticon{ visibility: hidden; color: darkgray; } .sort:hover .sorticon{ visibility: visible; } .sort:hover{ cursor: pointer; } </style> </head> <body> <livewire:emp-pagination /> @livewireScripts </body> </html>
8. Output
9. Conclusion
In the example, I have added a search box with pagination similarly you can add other elements for filtering.
You can also view this tutorial to know livewire pagination with date range filter.
If you found this tutorial helpful then don't forget to share.