Filtering
A filter form for a table, built from the table's own fields — no template to write.
Marking a field
Filtering is chosen per field, on the field itself: turn Filterable on. Columns have nothing to do with it — a field can be filterable without being shown in the grid at all.
The form then appears with pbFilters:
[[!pbFilters? &table=`Products`]]Operators
The filter is applied through the same operator set the grid and the API use:
| Group | Operators |
|---|---|
| Equality | equals, not_equals |
| Comparison | greater_than, greater_than_or_equal, less_than, less_than_or_equal |
| Ranges | between, not_between |
| Dates | before, after, equals_or_before, equals_or_after |
| Text | contains, like, starts_with, ends_with |
| Sets | is_in, is_not_in |
| Presence | is_set, is_not_set |
| Boolean | true, false |
Which one a field gets is derived from its type: a number offers ranges, a date offers date operators, a text field offers contains.
System filters
Four columns every table has can be filtered without being fields at all:
published_at created_at updated_at deleted_atThey are declared on the table as system filters and behave like the rest. This is how "created this week" or "unpublished only" is built without adding a field that stores nothing.
Quick filters in the toolbar
A table can offer preset filters as toolbar buttons — unpublished, needs attention, whatever the project calls for.
They come from the table's action controller: if the class has a quickFilters() method, its result is drawn in the toolbar. No method, no buttons, no error.
Why nothing happens
A field that is not marked filterable is ignored silently
Not in the form, not over the API, and no error either way. This is by design — an unknown filter key must not leak whether a hidden field exists — but it does mean the first thing to check is always the flag on the field.