Filter API
A filter is a field users filter by: a key, a label, its clauses, the default clause, and whether it
is pinned. On the server it also knows the column its clauses query. Classes live in
InertiaX\Table\Filters and start with FilterClass::make(?string $key = null, ?string $label = null).
Built-in filters
Section titled “Built-in filters”Filter starts blank. The others are presets: default clauses plus the value type they use.
TextFilterLink to TextFilter- Value type
text - Default clauses, in order
equals,not-equals,starts-with,not-starts-with,ends-with,not-ends-with,contains,not-contains NumberFilterLink to NumberFilter- Value type
number - Default clauses, in order
equals,not-equals,greater-than,greater-than-or-equal,less-than,less-than-or-equal,between,not-between DateFilterLink to DateFilter- Value type
date - Default clauses, in order
equals,not-equals,between,not-between,before,after
A clause without a value type of its own takes its filter’s. See Value types for the values each one accepts. Built-in clauses support Eloquent and collections.
A filter needs a key and at least one clause. A keyless filter attached to a column takes the
column’s key; anywhere else, preparing the table fails with
Filter [InertiaX\Table\Filters\TextFilter] has no key: pass one to make(), or attach the filter to a column with ->filter().
A filter without clauses fails with a FilterDefinitionException whose message ends with
the filter has no clauses; add one with addClause().
Common methods
Section titled “Common methods”key(string $key)Link to key- The filter’s name in filter state and URLs
label(?string $label)Link to label- Label; derived from the key if omitted
valueType(ValueType|Link to valueTypestring $type) - Value type of the clauses that declare none: a built-in value type or
vendor/name column(string $column)Link to column- Column the clauses query; defaults to the key and is never sent to the browser
nullable(bool $nullable = true)Link to nullable- Add
is-set(Is not empty) andis-not-set(Is empty) after the other clauses, unless they are already there pinned(bool $pinned = true)Link to pinned- Show the filter in the toolbar unless the page lists its own; see Pinned filters
defaultClause($clause)Link to defaultClause- Choose a registered clause; otherwise the first clause is used
addClause($clause)/addClauses(array)Link to addClause($clause) / addClauses(array)- Add new comparisons
replaceClause($clause)/replaceClauses(array)Link to replaceClause($clause) / replaceClauses(array)- Replace existing comparisons
removeClause($clause)/removeClauses(array)Link to removeClause($clause) / removeClauses(array)- Remove existing comparisons
clearClauses()/setClauses(array)Link to clearClauses() / setClauses(array)- Clear, or clear then add
orderClauses(Closure $callback)Link to orderClauses- Reorder the clause collection
applyClauseUsing(Closure $callback, DataSourceKind|Link to applyClauseUsingstring $source, ...) - Wrap clause application; see Shared clause routing
ValueType is in InertiaX\Table\Filters\Enums. Clause arguments can be clause objects,
ClauseType enum values, or keys. Duplicate adds and missing replace/remove targets fail.
The explicit default must exist in the resulting set, which includes the clauses nullable() adds.
See Clause API.
Filter classes
Section titled “Filter classes”Extend Filter to reuse a filter. The class can set protected string $key,
protected ?string $label, protected ?string $column, protected bool $pinned and
protected string $valueType, and return its clauses from clauses(); make() arguments and
builder methods override them. A table’s filters() can list OrganizationFilter::make() or
OrganizationFilter::class. See Build a filter from scratch.
Automatic and attached filters
Section titled “Automatic and attached filters”Automatic filters require autoFilters() and a filterable column. Number, Boolean, datetime,
time, and date column classes map to their matching filters; other columns map to text. When an
Eloquent model’s database column is nullable, its automatic filter also gets is-set and
is-not-set. Collections and custom sources have no schema and get neither.
A filter attached with a column’s filter() keeps its key, or takes the column’s key when it has
none. It queries that column, including one with a relationship(), count() or sum() binding,
unless it sets its own column with column() or a $column property. A column with an attached
filter gets no automatic filter. Explicit table filters take precedence over attached and automatic
filters with the same key.
Select options
Section titled “Select options”options(array|Link to optionsClosure $options, DataSourceKind| string ...$sources) - Explicit values or deferred options
multiple(bool $multiple = true)Link to multiple- Off by default. The filter’s own
equalsandnot-equalstake a list; a clause you add, replace or set takes one only with its ownmultiple() autoOptions(bool $auto = true, int $limit = 200)Link to autoOptions- Discover bounded distinct values of the filter’s column; default off; limit must be positive
supportsOptionSources(DataSourceKind|Link to supportsOptionSourcesstring ...$sources) - Declare the kinds accepted by deferred options
addOption(string|Link to addOptionarray| Closure $value, ?string $label = null) - Append an option
The options go into the input of each select clause of the filter that has no options of its own,
including a custom clause with valueType('select'). For exact primitive types, use explicit
option records:
SelectFilter::make('level')->options([ ['value' => 1, 'label' => 'Level one'], ['value' => 2, 'label' => 'Level two'],]);Values can be strings, numbers, or Booleans. "1", 1, and true are distinct. A list uses a
non-empty array of those values. Options describe the UI choices; backend input checks validate
shape and type, not membership in the option list. Enforce application value restrictions in a
clause validator or custom source. When distinct values exceed the autoOptions() limit, the
input’s optionsTruncated is set and the UI displays a notice. Source-dependent option closures
must declare the kinds they support.
Custom sources
Section titled “Custom sources”Use options($callback, DataSourceKind::Custom) for an application-owned source. autoOptions()
requires a local dataset and is rejected. See Source-specific options
for callback arguments and timing.
Custom sources implement comparisons from the validated filter conditions. See Filters and options for modifiers, validators, and storage maps.
Boolean storage
Section titled “Boolean storage”Call booleanMap(array $map) on a BooleanFilter builder to override the stored values matching true and false.
The built-in map recognizes true/false, 1/0, and strings such as yes/no, on/off,
enabled/disabled, active/inactive, and checked/unchecked, plus true/false and 1/0.
The submitted filter value is still a Boolean.
For a text column storing custom labels:
BooleanFilter::make('status')->booleanMap([ true => ['published'], false => ['draft', 'archived'],]);Matching depends on the data source and column storage:
- PostgreSQL
booleanLink to PostgreSQL boolean - Map entries used for comparison Booleans,
0,1,'0', and'1', converted to Booleans bit: SQL Server’s Boolean, andbit(1)on MySQL and PostgreSQL Link to bit: SQL Server’s Boolean, and bit(1) on MySQL and PostgreSQL- Map entries used for comparison Booleans,
0,1,'0', and'1', converted to0or1 - Numeric, including MySQL’s
tinyint(1)Boolean Link to Numeric, including MySQL’s tinyint(1) Boolean - Map entries used for comparison Numbers and numeric strings; Booleans become
0or1 - Text, including SQL Server’s
nvarcharLink to Text, including SQL Server’s nvarchar - Map entries used for comparison Scalar values converted to strings; Booleans become
'0'or'1' - SQLite Link to SQLite
- Map entries used for comparison Mixed stored types, compared using SQLite’s rules
- Collection Link to Collection
- Map entries used for comparison Strict membership:
1,'1', andtrueare distinct map entries
Except on SQLite and collections, incompatible entries are ignored. For the selected Boolean value, a nonempty list with no compatible entries raises an error. Null entries and empty lists are supported.
An unqualified column can be on the base table or a joined table. If multiple tables contain it,
qualify it with its table or alias, such as column('flags.enabled').
For computed columns or subqueries whose storage cannot be determined, supply a
custom comparison.
Filter groups
Section titled “Filter groups”Basic mode accepts one root and group with direct conditions, including repeated field keys.
Advanced mode accepts recursive and/or groups up to eight levels including the root.
Both modes allow at most 100 total condition or child-group nodes.
The server rejects unsupported grouping even if submitted outside the built-in UI.
Shared clause routing
Section titled “Shared clause routing”applyClauseUsing(Closure $callback, DataSourceKind|string $source, ...$additionalSources) wraps
application of the selected clause. Its callback can receive $source, the filter’s $column,
the filter’s $key, $value, $clause, $clauseKey, and Closure $applyClause. Delegate with
$applyClause($source, $column, $value), or pass another source or column. The selected clause
still owns validation and its source requirements. See
Custom filters.
See Callback context for injectable arguments and resolution rules.