Data filtering and searching is a very common need in web applications — from product filters in e-commerce to report searches in management systems. In Laravel, there are several ways to implement it, from the simplest to the most structured. This article will teach you a clean, easily extensible data filter pattern that doesn't clutter the controller.
The Simple Approach: Filter Directly in the Controller
The most basic way is to use conditionals in the query builder. Suitable for filters that aren't too numerous:
<?php
namespace App\Http\Controllers;
use App\Models\Product;
use Illuminate\Http\Request;
class ProductController extends Controller
{
public function index(Request $request)
{
$query = Product::query();
// Filter by name (search)
if ($request->filled('search')) {
$query->where('name', 'like', '%' . $request->search . '%');
}
// Filter by category
if ($request->filled('category_id')) {
$query->where('category_id', $request->category_id);
}
// Filter by price range
if ($request->filled('min_price')) {
$query->where('price', '>=', $request->min_price);
}
if ($request->filled('max_price')) {
$query->where('price', '<=', $request->max_price);
}
// Sorting
$sortBy = $request->get('sort_by', 'created_at');
$sortDir = $request->get('sort_dir', 'desc');
$allowedSorts = ['name', 'price', 'created_at'];
if (in_array($sortBy, $allowedSorts)) {
$query->orderBy($sortBy, $sortDir === 'asc' ? 'asc' : 'desc');
}
$products = $query->paginate(15)->withQueryString();
return view('products.index', compact('products'));
}
}
Creating the Filter Form in Blade
<form method="GET" action="{{ route('products.index') }}">
<input type="text" name="search" value="{{ request('search') }}" placeholder="Search products...">
<select name="category_id">
<option value="">All Categories</option>
@foreach($categories as $cat)
<option value="{{ $cat->id }}" {{ request('category_id') == $cat->id ? 'selected' : '' }}>
{{ $cat->name }}
</option>
@endforeach
</select>
<input type="number" name="min_price" value="{{ request('min_price') }}" placeholder="Min price">
<input type="number" name="max_price" value="{{ request('max_price') }}" placeholder="Max price">
<button type="submit">Filter</button>
<a href="{{ route('products.index') }}">Reset</a>
</form>
Use withQueryString() on the paginator so the filter parameters persist when moving between pages.
This is only part of the article. For the full discussion, with examples and step-by-step details, you can read it on the original source:
How to Build a Data Filter Feature in Laravel
More programming tutorials and developer tools are also available at dhiecoderweb.com.
Top comments (0)