labrodev/laravel-filter-components
Installation
composer require labrodev/laravel-filter-components
Publish the package's views (optional, for customization):
php artisan vendor:publish --provider="Labrodev\LaravelFilterComponents\LaravelFilterComponentsServiceProvider" --tag="views"
Basic Usage Register a filter in your controller or service:
use Labrodev\LaravelFilterComponents\Filters\DateRangeFilter;
use Labrodev\LaravelFilterComponents\Filters\IsNotNullFilter;
use Labrodev\LaravelFilterComponents\Filters\WhereInFilter;
$queryBuilder = new \Spatie\QueryBuilder\QueryBuilder($model);
$queryBuilder->addFilter(new DateRangeFilter('created_at'));
$queryBuilder->addFilter(new IsNotNullFilter('unpaid_invoices'));
$queryBuilder->addFilter(new WhereInFilter('status', ['active', 'pending']));
First Use Case Render a filter form in your Blade view:
@filterComponent('dateRange', 'created_at', 'Created At')
@filterComponent('isNotNull', 'unpaid_invoices', 'Has Unpaid Invoices')
@filterComponent('whereIn', 'status', 'Status', ['active', 'pending'])
Filter Registration
QueryBuilder instance dynamically or statically:
// Dynamic registration (e.g., in a controller)
$queryBuilder = (new QueryBuilder($model))
->addFilter(new DateRangeFilter('date_column'))
->addFilter(new WhereInFilter('category', ['web', 'mobile']));
View Integration
@filterComponent) to render filters in your views:
@filterComponent('dateRange', 'published_at', 'Publication Date')
@filterComponent('whereIn', 'tags', 'Tags', ['web', 'laravel'], label: 'Select Tags')
Custom Filter Logic
FilterInterface:
use Labrodev\LaravelFilterComponents\Contracts\FilterInterface;
class CustomFilter implements FilterInterface {
public function apply($queryBuilder, $query, $value) {
// Custom logic here
return $query->where('custom_column', $value);
}
}
QueryBuilder Integration
QueryBuilder methods:
$results = $queryBuilder
->allowedFilters(['dateRange', 'whereIn'])
->paginate();
CRUD Filtering
index actions to pre-filter results:
public function index(Request $request) {
$queryBuilder = (new QueryBuilder(Post::class))
->addFilter(new DateRangeFilter('created_at'))
->allowedFilters(['dateRange', 'whereIn']);
return view('posts.index', [
'posts' => $queryBuilder->paginate(),
]);
}
Reusable Filter Groups
$advancedFilters = [
new WhereInFilter('status', ['draft', 'published']),
new DateRangeFilter('updated_at'),
];
$queryBuilder->addFilters($advancedFilters);
Dynamic Filter Loading
if (auth()->user()->isAdmin()) {
$queryBuilder->addFilter(new WhereInFilter('user_id', User::all()->pluck('id')));
}
Form Request Validation
FormRequest classes:
public function rules() {
return [
'date_from' => 'sometimes|date',
'date_to' => 'sometimes|date',
'status' => 'sometimes|in:active,pending',
];
}
URL Parameter Handling
QueryBuilder's built-in URL parameter handling:
$queryBuilder->defaultSort('created_at', 'desc');
Localization
@filterComponent('dateRange', 'created_at', __('Created At'))
Testing
public function test_date_range_filter() {
$query = Post::query();
$filter = new DateRangeFilter('created_at');
$filter->apply($query, $query, ['from' => '2023-01-01', 'to' => '2023-12-31']);
$this->assertDatabaseHas('posts', [
'created_at' => '2023-06-01',
]);
}
View Publishing
php artisan vendor:publish --tag="views"
Filter Overwriting
allowedFilters() to restrict:
$queryBuilder->allowedFilters(['dateRange']); // Only allow dateRange
DateRangeFilter Quirks
date_from and date_to parameters are named correctly in requests:
// Correct: date_from=2023-01-01&date_to=2023-12-31
// Incorrect: from=2023-01-01&to=2023-12-31 (will fail silently)
WhereInFilter Edge Cases
null values may cause SQL errors. Validate inputs:
$values = $request->input('status') ?? [];
if (!is_array($values)) $values = [$values];
IsNotNullFilter Logic
true/false or 1/0 for whereNotNull/whereNull. Customize if needed:
$filter = new IsNotNullFilter('column', 'custom_true_value', 'custom_false_value');
Query Inspection
toSql() and getBindings() to debug queries:
dd($queryBuilder->getQuery()->toSql(), $queryBuilder->getQuery()->getBindings());
Filter Application Order
$queryBuilder->addFilter(new WhereInFilter('status'))->addFilter(new DateRangeFilter('created_at'));
Blade Directive Errors
@filterComponent directives or missing views:
php artisan view:clear
Custom Filter Styling
resources/views/vendor/labrodev-filter-components:
<!-- Example: Custom date range input -->
<div class="custom-date-filter">
{{ $input }}
</div>
Performance
allowedFilters() to restrict filters and avoid unnecessary logic:
$queryBuilder->allowedFilters(['dateRange']); // Only allow dateRange
Dynamic Filter Labels
return view('posts.index', [
'filters' => [
'dateRange' => __('Custom Date Label'),
],
]);
Filter Persistence
QueryBuilder's remember() to persist filters across sessions:
$queryBuilder->remember();
Extending Filters
class StatusFilter extends WhereInFilter {
protected $defaultValues = ['active', 'pending', 'draft'];
public function __construct($column) {
parent::__construct($column, $this->defaultValues);
}
}
API Integration
QueryBuilder's JSON response:
return $queryBuilder->paginate()->withQueryString();
How can I help you explore Laravel packages today?