laratribe / laravel-advanced-filters
Advanced column filters for Laravel. Text, numeric, date and set filters with custom operators and strict allow-listing โ declared once on an Eloquent model, then rendered with Blade + Alpine, Livewire, Inertia or as a JSON API.
Package info
github.com/laratribe/laravel-advanced-filters
pkg:composer/laratribe/laravel-advanced-filters
Requires
- php: ^8.2
- illuminate/contracts: ^10.0|^11.0|^12.0|^13.0
- illuminate/database: ^10.0|^11.0|^12.0|^13.0
- illuminate/support: ^10.0|^11.0|^12.0|^13.0
- illuminate/view: ^10.0|^11.0|^12.0|^13.0
Requires (Dev)
- larastan/larastan: ^2.9|^3.0
- laravel/pint: ^1.18
- livewire/livewire: ^3.0|^4.0
- orchestra/testbench: ^8.0|^9.0|^10.0|^11.0
- pestphp/pest: ^2.0|^3.0|^4.0
Suggests
- livewire/livewire: Required only if you use the Livewire <livewire:advanced-filters::panel /> adapter.
Provides
None
Conflicts
None
Replaces
None
README
Declare filters once on an Eloquent model, then render them with Blade + Alpine, Livewire, Inertia (Vue/React), or no UI at all as a JSON API.
๐ Documentation ย ยทย ๐ Live demo ย ยทย ๐ป Demo source
The demo is one model with seven filters, driving a Blade + Alpine page, a Livewire page and a JSON API โ each page shows the code behind it.
- ๐ One trait โ add
HasFiltersand afilters()method to a model. That's the setup. - ๐ช Self-describing โ the server tells the frontend which columns exist, which operators each allows, their labels and how many values they take. That's what makes a generic panel possible.
- ๐๏ธ Four frontends, one backend โ no duplicated filter logic between them.
- ๐งฉ Extensible โ add your own filter types (with their own input views) and your own operators, without forking a shipped view.
- ๐จ CSS-framework-agnostic โ semantic markup, stable
af-*classes, a bundled vanilla theme, and an opt-in Tailwind one. - ๐ Safe by construction โ
filters()is the allow-list. Undeclared columns and disallowed operators are dropped before they reach SQL.
Installation
composer require laratribe/laravel-advanced-filters
The service provider auto-registers and the PHP side works immediately. For the shipped UI, see frontend assets.
Requires PHP 8.2+ and Laravel 10, 11, 12 or 13. Livewire 3/4 and Alpine are optional.
Quick start
1. Declare filters on the model
use Laratribe\AdvancedFilters\Concerns\HasFilters; use Laratribe\AdvancedFilters\Contracts\Filterable; use Laratribe\AdvancedFilters\Filters\{TextFilter, SetFilter, NumericFilter, DateFilter}; class Product extends Model implements Filterable { use HasFilters; public static function filters(): array { return [ TextFilter::make('name', 'Name'), SetFilter::make('category', 'Category')->options([ 'electronics' => 'Electronics', 'books' => 'Books', ])->multiple(), NumericFilter::make('price', 'Price'), DateFilter::make('released_at', 'Released'), ]; } }
2. Filter and paginate
$filters = Product::normalizeFilters($request->input('column_filters')); $products = Product::query() ->where('active', true) // your own constraints ->applyFilters($filters) // the trait scope ->paginate(25) ->withQueryString(); return view('products.index', [ 'products' => $products, 'filterFields' => Product::filterDefinitions(), 'activeFilters' => $filters, ]);
3. Render it
<x-advanced-filters::panel :fields="$filterFields" :active="$activeFilters" :base-url="route('products.index')" />
That's a working filter UI. See the docs for Livewire, Inertia and JSON API.
Filter types
| Type | Class | Default operators |
|---|---|---|
| Text | TextFilter |
contains, not_contains, starts_with, ends_with, equals, not_equals |
| Number | NumericFilter |
equals, not_equals, >, <, โฅ, โค, between |
| Date | DateFilter |
equals, >, <, between |
| Set | SetFilter |
equals, not_equals, in, not_in |
Plus your own, and your own operators.
The wire contract
Two plain-array shapes, no framework coupling, SemVer-stable:
- Out โ
[{ key, label, type, input, clauses, clauseItems, optionItems? }] - In โ
[{ field, operator, value, valueTo? }]
Playground
A Testbench app demonstrating every frontend against a seeded SQLite model, including a custom filter type and a custom operator:
composer install
vendor/bin/testbench workbench:build
vendor/bin/testbench serve
# / โ Blade + Alpine /livewire โ Livewire
Testing
composer test # Pest composer lint # Pint composer analyse # PHPStan
Security
NumericFilter::havingExpression() accepts raw SQL and is developer-supplied, never user
input โ values are always bound as parameters. If you find a security issue, please email
rns6393@gmail.com rather than opening a public issue.
๐ค Author
Ram Sharma
- GitHub: @rnsharma93
- Email: rns6393@gmail.com
If you find this package useful, please consider starring the repository on GitHub!
๐ License & Open Source
Laravel Advanced Filters is open-source software licensed under the MIT license.
You are completely free to use, modify and distribute this package in both personal and commercial projects. Contributions, issues and feature requests are always welcome โ have a look at the issues page if you'd like to contribute.