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
employeesusing 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_tableand 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
EmployeesModel –
php artisan make:model Employees
- Open
app/Models/Employees.phpfile. - Specify mass assignable Model attributes – emp_name, email, gender, city, dateofjoining, and status using the
$fillableproperty.
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
EmployeesControllercontroller.
php artisan make:controller EmployeesController
- Open
app\Http\Controllers\EmployeesController.phpfile. - Create 1 method –
- index() – Load
indexview.
- 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.phpfile. - 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-paginationcomponent –
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\WithPaginationtrait andApp\Models\Employeesmodel. - 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
fromdate from datepicker. - $to_date – Store selected
todate from datepicker. - $orderColumn – Assign sorting column name. Change its value while implementing in your project.
- $sortOrder – Assign sorting order –
ascordesc. I set itasc.
- Class methods –
- updated() – Using this reset the pagination layout during date filtering.
- render() – Fetch records from
employeestable. Use class variables for settingorderby(). Iffrom_dateandto_dateare not empty then search ondateofjoiningfield 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$employeesrecord if it is not empty. If it is empty then showNo record foundrow. - Display pagination links using
{{ $employees->links() }}.
Script –
- Initialize datepicker on
#from_dateand#to_date. - Using
onSelectevent to updatefrom_dateandto_datemodel 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.