Table filters
Filters narrow which rows appear in a table. Define them on the table; the index host keeps table_filters state and applies them when rendering. Live selects call setTableFilter(name, value) on the host (Conduit only supports top-level props, so nested table_filters.* model paths are not used).
from almasix.orbit.tables import ( Table, TextColumn, Filter, SelectFilter, TernaryFilter, FilterGroup,)
table = ( Table.make("posts") .columns([TextColumn.make("title").searchable()]) .filters([ SelectFilter.make("status") .label("Status") .options({ "draft": "Draft", "published": "Published", }), # Filter name ≠ column: point at the attribute SelectFilter.make("author") .attribute("author_id") .options(lambda **ctx: ctx.get("authors", {})), TernaryFilter.make("featured").label("Featured"), Filter.make("mine").query( lambda q, value: [r for r in q if r.get("mine")] ), ]))

Filter types
Section titled “Filter types”| Class | Role |
|---|---|
Filter |
Base — .options(...), .query(callback), .attribute(...), .apply(query, value) |
SelectFilter |
Dropdown; default equality on attribute or name |
TernaryFilter |
All / Yes / No for booleans |
TrashedFilter |
Soft-delete scopes |
FilterGroup |
Nest filters under a named group via .filters([...]) |
.apply() is a no-op when the value is None, "", or [] (unless a custom .query() handles empty values on purpose).
Filter groups
Section titled “Filter groups”from almasix.orbit.tables import FilterGroup, SelectFilter, TernaryFilter
FilterGroup.make("visibility").label("Visibility").filters([ SelectFilter.make("status").options({ "draft": "Draft", "published": "Published", }), TernaryFilter.make("featured"),])Soft deletes
Section titled “Soft deletes”from almasix.orbit.tables import TrashedFilter
table.filters([TrashedFilter.make()])Index chrome
Section titled “Index chrome”List pages render a Filters dropdown with indicator chips for active values. Search sits on the right of the same toolbar row as the Filters trigger.
table.defer_filters() # require Apply instead of live updatesUse deferred filters when each change is expensive (large queries, remote APIs) or when operators prefer to set several values before applying.
In a Resource
Section titled “In a Resource”from almasix.orbit import Resourcefrom almasix.orbit.tables import Table, TextColumn, SelectFilter, TernaryFilter
class PostResource(Resource): @classmethod def table(cls, table: Table) -> Table: return ( table.columns([ TextColumn.make("title").searchable().sortable(), TextColumn.make("status").badge(), ]) .filters([ SelectFilter.make("status").options({ "draft": "Draft", "review": "Review", "published": "Published", }), TernaryFilter.make("featured").label("Featured"), ]) .defer_filters() )Empty after filtering
Section titled “Empty after filtering”When filters match no rows, the empty state still renders. Customize the copy on the table:
table.empty_state_heading("No matches")table.empty_state_description("Try clearing filters or broadening search.")

See also Tables overview and standalone tables.