Using pagination you can divide a large list of records into multiple pages and show a limited number of records per page.
But if the search filter is not available with pagination then traversing the paginated result becomes difficult.
In this tutorial, I show how you can add a date range filter with Livewire pagination in Laravel 9.
In the example, I am using jQuery UI library for datepicker.
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->date('dateofjoining'); $table->smallInteger('status'); $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, dateofjoining, 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','dateofjoining','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 – Using this property change the default pagination theme from Tailwind to bootstrap. If you are using Tailwind in your project then remove this property.
- $from_date – Store selected
from
date from datepicker. - $to_date – Store selected
to
date from datepicker. - $orderColumn – Assign sorting column name. Change its value while implementing in your project.
- $sortOrder – Assign sorting order –
asc
ordesc
. I set itasc
.
- Class methods –
- updated() – Using this reset the pagination layout during date filtering.
- render() – Fetch records from
employees
table. Use class variables for settingorderby()
. Iffrom_date
andto_date
are not empty then search ondateofjoining
field usingbetween
. Paginate the fetched records by callingpaginate(10)
.
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 $from_date = ""; public $to_date = ""; public $orderColumn = "emp_name"; public $sortOrder = "asc"; public function updated(){ $this->resetPage(); } public function render(){ $employees = Employees::orderby($this->orderColumn,$this->sortOrder)->select('*'); if(!empty($this->from_date) && !empty($this->to_date)){ $employees->whereBetween('dateofjoining', [$this->from_date, $this->to_date]); } $employees = $employees->paginate(10); return view('livewire.emp-pagination', [ 'employees' => $employees, ]); } }
resources/views/livewire/emp-pagination.blade.php
- Create 2 textbox element for datepicker –
- 1st is for from date. Add
wire:model="from_date"
. - 2nd is for to date. Add
wire:model="to_date"
.
- 1st is for from date. Add
- Create
<table >
to list$employees
record if it is not empty. If it is empty then showNo record found
row. - Display pagination links using
{{ $employees->links() }}
.
Script –
- Initialize datepicker on
#from_date
and#to_date
. - Using
onSelect
event to updatefrom_date
andto_date
model value after date selection. - To update need to call
@this.set()
. Here, pass the model variable name and value.
Completed Code
<div> <div class="container"> <div class="row mt-5"> <div class="col-md-12"> <!-- Date range filter --> <div class="search-filter"> <input type="text" class="datepicker" id="from_date" wire:model="from_date"> <input type="text" class="datepicker" id="to_date" wire:model="to_date"> </div> <!-- Paginated records --> <table class="table"> <thead> <tr> <th >Name</th> <th >Email</th> <th >Gender</th> <th >City</th> <th >Date of Joining</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->dateofjoining }}</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> @section('scripts') <script> $(document).ready(function(){ $("#from_date").datepicker({ dateFormat: "yy-mm-dd", changeYear: true, changeMonth: true, onSelect: function (selected) { var dt = new Date(selected); @this.set('from_date', selected); dt.setDate(dt.getDate() + 1); $("#to_date").datepicker("option", "minDate", dt); } }); $("#to_date").datepicker({ dateFormat: "yy-mm-dd", changeYear: true, changeMonth: true, onSelect: function (selected) { var dt = new Date(selected); @this.set('to_date', selected); dt.setDate(dt.getDate() - 1); $("#from_date").datepicker("option", "maxDate", dt); } }); }); </script> @endsection
7. Create View
Create index.blade.php
file in resources/views/
folder.
Include jQuery and jQuery UI library –
<!-- jQuery UI CSS --> <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.13.2/themes/smoothness/jquery-ui.css"> <!-- jQuery --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script> <!-- jQuery UI JS --> <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js"></script>
Include emp-pagination
component, livewire style, and script. Also, add @yield('scripts')
.
Completed Code
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>How to Add Date range filter with Livewire pagination in Laravel</title> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" > <!-- jQuery UI CSS --> <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.13.2/themes/smoothness/jquery-ui.css"> <!-- jQuery --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script> <!-- jQuery UI JS --> <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js"></script> @livewireStyles <style type="text/css"> .datepicker{ width: 200px; display: inline-block; } </style> </head> <body> <livewire:emp-pagination /> @livewireScripts @yield('scripts') </body> </html>
8. Output
9. Conclusion
In the example, I used jQuery UI library for datepicker but you can use any other library that you are compatible with.
Make sure to call @this.set()
after date selection to update the model value otherwise, data will not filter.
You can view this tutorial if you want to know how you add textbox search filter with Livewire pagination.
If you found this tutorial helpful then don't forget to share.