Filtering
Types of Filters
There are several types of filters that can be added to the Table:
TextFilter
NumericFilter
SetFilter
DateFilter
BooleanFilter
Adding Filters
To add filters to your table, you can use the make
method on the filter class and pass the attribute of the Eloquent Model you want to filter. Add the filter to the array returned by the filters()
method in your Table class.
TextFilter::make('name');
It will automatically generate a title-cased header based on the attribute name. If you want to customize the header, you can pass the header as the second argument.
TextFilter::make('name', 'Full Name');
Clauses
Each filter has one or more clauses that define how the filter should be applied. The clauses are defined in the Clause
enum and each type of filter has its own set of default clauses. If you want to customize the available clauses, you can pass an array of clauses to the clauses
parameter, or by using the clauses()
method.
use InertiaUI\Table\Filters\Clause;
TextFilter::make('name')->clauses([
Clause::Equals,
Clause::StartsWith,
Clause::Contains,
]);
Nullable attributes
If you want to filter nullable attributes, you may pass the nullable
argument to the filter to add the IsSet
and IsNotSet
clauses. Alternatively, you can use the nullable()
method.
TextFilter::make('name', nullable: true);
TextFilter::make('name')->nullable();
Validate and Modify Input
By default, the incoming filter input is validated to be filled and to be of the correct type. If you want to customize the validation process, you can pass a closure to the validateUsing
parameter, or call the validateUsing()
method.
TextFilter::make('name')->validateUsing(function (mixed $value) {
if(is_string($value) && strlen($value) > 3) {
return $value;
}
});
Note that the callback should return the value if it passes the validation, not a boolean. This way you can modify the value before it is used in the query.
The callback accepts two additional parameters: the clause and the Eloquent builder:
use Illuminate\Database\Eloquent\Builder;
use InertiaUI\Table\Filters\Clause;
TextFilter::make('name')->validateUsing(function (mixed $value, Clause $clause, Builder $query) {
//
});
Customizing the Query
Each combination of filter and clause has a specific way of applying the filter to the query. If you want to customize this, you can pass a closure to the applyUsing
parameter, or call the applyUsing()
method.
use Illuminate\Database\Eloquent\Builder;
use InertiaUI\Table\Filters\Clause;
TextFilter::make('name')->applyUsing(function (Builder $resource, string $attribute, Clause $clause, mixed $value) {
if($clause === Clause::Equals) {
$resource->where($attribute, $value);
}
});
You might wonder why you want to pass such an extensive callback to the static make()
method, but remember that you may also pass invokable classes:
TextFilter::make('name', applyUsing: new MyCustomTextFilter);
Prevent the customized query from being wrapped
By default, each filter gets wrapped into a where()
clause to prevent conflicts with other filters. While this is fine for most cases, you might want to prevent this behavior when you want to interact directly with the Query Builder instance. One example is when you want to remove a global scope. You may pass the applyUnwrapped
argument to the filter, or call the applyUnwrapped()
method.
SetFilter::make('status' applyUsing: new StatusFilter, applyUnwrapped: true);
Alternatively, the applyUsing()
method accepts a second argument which you can set to true
to prevent the query from being wrapped.
SetFilter::make('status')->applyUsing(function () {
//
}, true);
Set Filter
The SetFilter
has an options()
method to populate the select options. You can pass an array of options to it:
SetFilter::make('status')->options([
'active' => 'Active',
'inactive' => 'Inactive',
]);
If you want to allow multiple selections, you can pass the multiple
argument to the filter, or call the multiple()
method.
SetFilter::make('tags')->multiple();
Set Filter Clauses
By default, the SetFilter
has four default clauses to choose from:
In
NotIn
Equals
NotEquals
If you don't want to use the clause selector in the frontend, you can use the withoutClause()
method. This will remove the clause selector from the frontend and always use the Equals
clause. This can be useful for filtering statuses, for example.
SetFilter::make('status')->withoutClause();
Filtering by Relationships
The SetFilter
is great for filtering by relationships. It comes with a pluckOptionsFromModel
helper method that allows you to easily populate the options from an Eloquent Model.
SetFilter::make('company.id', 'Company')->pluckOptionsFromModel(Company::class, 'name');
Alternatively, you can use the relationship as an attribute (without .id
), and use the pluckOptionsFromRelation
method to automatically resolve the key and populate the options from the related Model.
SetFilter::make('company')->pluckOptionsFromRelation('name');
Default Filters
You might want to enable a filter by default with a specific value and clause. You can use the default()
method to set a default value for the filter, as well as a default clause (optional).
TextFilter::make('company')->default('GmbH');
DateFilter::make('created_at')->default(now()->subDays(7), Clause::GreaterThan);
NumericFilter::make('score')->default([55, 100], Clause::Between);
If you don't provide a clause, it will default to the first clause in the list.
Metadata
You can add metadata to the filter by using the meta
argument in the make()
method or by using the meta()
method.
TextFilter::make('name')->meta([
'key' => 'value',
]);
In the default Table component, this metadata is unused and not passed to any DOM element. However, this feature can be useful when extending the Table component using slots, or when you build a custom Table component.