Skip to content

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).

Filter starts blank. The others are presets: default clauses plus the value type they use.

Filter Link to Filter
Value type text
Default clauses, in order None
TextFilter Link 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
NumberFilter Link 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
BooleanFilter Link to BooleanFilter
Value type boolean
Default clauses, in order equals, not-equals
SelectFilter Link to SelectFilter
Value type select
Default clauses, in order equals, not-equals
DateFilter Link to DateFilter
Value type date
Default clauses, in order equals, not-equals, between, not-between, before, after
DateTimeFilter Link to DateTimeFilter
Value type datetime
Default clauses, in order Same as date
TimeFilter Link to TimeFilter
Value type time
Default clauses, in order Same as date

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().

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|string $type) Link to valueType
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) and is-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|string $source, ...) Link to applyClauseUsing
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.

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 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.

options(array|Closure $options, DataSourceKind|string ...$sources) Link to options
Explicit values or deferred options
multiple(bool $multiple = true) Link to multiple
Off by default. The filter’s own equals and not-equals take a list; a clause you add, replace or set takes one only with its own multiple()
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|string ...$sources) Link to supportsOptionSources
Declare the kinds accepted by deferred options
addOption(string|array|Closure $value, ?string $label = null) Link to addOption
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.

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.

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 boolean Link to PostgreSQL boolean
Map entries used for comparison Booleans, 0, 1, '0', and '1', converted to Booleans
bit: SQL Server’s Boolean, and bit(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 to 0 or 1
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 0 or 1
Text, including SQL Server’s nvarchar Link 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', and true are 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.

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.

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.

View Markdown