addColumnFilters
addColumnFilters filters table rows by specific column values.
Options
addColumnFilters.const table = createTable(data, {
colFilter: addColumnFilters({ ... }),
});const table = createTable(data, {
colFilter: addColumnFilters({ ... }),
});serverSide?: boolean
If true, filtering will not change vm.current.rows. Control filtering by updating the table’s data and use plugin state to drive your fetch.
Defaults to false.
matchMode?: 'self-or-descendants' | 'self'
How rows that have sub-rows (see addSubRows) are matched.
'self-or-descendants'keeps a row when it matches or when any of its descendants match, so a parent that does not match itself still appears above its matching children. This keeps the tree navigable but means a visible parent’s own cell values may fall outside the filter.'self'requires every kept row to match on its own values. A parent that does not match is removed together with its subtree.
Defaults to 'self-or-descendants'.
Column Options
const columns = table.createColumns([
table.column({
header: 'Name',
accessor: 'name',
plugins: {
colFilter: { ... },
},
}),
]);const columns = table.createColumns([
table.column({
header: 'Name',
accessor: 'name',
plugins: {
colFilter: { ... },
},
}),
]);fn: ({ filterValue, value }) => boolean
Defines filter behavior for the column. Return true to keep the row.
render?: (renderProps) => RenderConfig
Renders a control on cell.current.props.[pluginName].render. renderProps extends TableState and includes:
id: stringfilterValue: Box<any>: the column’s filter value; writingundefinedclears itvalues: ReadonlyBox<any[]>: the column’s values after filteringpreFilteredValues: ReadonlyBox<any[]>: the column’s values before filteringpreFilteredRows: ReadonlyBox<BodyRow[]>
render is called once per header cell. Pass the boxes to your component and read their current there, so the control stays reactive:
render: ({ filterValue, values }) => createRender(TextFilter, { filterValue, values })render: ({ filterValue, values }) => createRender(TextFilter, { filterValue, values })<!-- TextFilter.svelte -->
<script lang="ts">
import type { Box, ReadonlyBox } from '@humanspeak/svelte-headless-table'
const { filterValue, values }: {
filterValue: Box<string | undefined>
values: ReadonlyBox<unknown[]>
} = $props()
</script>
<input bind:value={filterValue.current} placeholder="Search {values.current.length} rows..." /><!-- TextFilter.svelte -->
<script lang="ts">
import type { Box, ReadonlyBox } from '@humanspeak/svelte-headless-table'
const { filterValue, values }: {
filterValue: Box<string | undefined>
values: ReadonlyBox<unknown[]>
} = $props()
</script>
<input bind:value={filterValue.current} placeholder="Search {values.current.length} rows..." />initialFilterValue?: any
Initial filter value, applied when the view model is created.
initialFilterValue: '' on a matchFilter column now filters every row out; use undefined (or omit the option) for "no filter".Prop Set
current.props on table components. The lists below are generated from the plugin's TypeScript prop-set type, so they match the published package exactly.HeaderCell props cell.current.props.colFilter
render: RenderConfig | undefined- The rendered filter component.
Interactions
- Filters on hidden columns still apply.
addHiddenColumnsremoves the cell fromrow.cells, not from the row’s filter data, so a column-filter value keeps narrowing the rows while the column is hidden. - With
addExpandedRows, a sub-row is kept if it matches the filter itself or has a matching descendant (the defaultmatchMode; use'self'to drop non-matching parents). RegistercolFilterbeforeexpandso filtering happens before the tree is flattened; either order produces the same visible rows for a plain tree, but filtering first is cheaper.
Plugin State
addColumnFilters.const vm = table.createViewModel(columns)
const { pluginStates } = vm
const { filterValues } = pluginStates.colFilterconst vm = table.createViewModel(columns)
const { pluginStates } = vm
const { filterValues } = pluginStates.colFilterfilterValues: Box<Record<string, unknown>>
Active filter values by column id. Assign a new record to change them; a column without a value (or with undefined) is not filtered.
filterValues.current = { ...filterValues.current, status: 'single' }filterValues.current = { ...filterValues.current, status: 'single' }preFilteredRows: ReadonlyBox<BodyRow<Item>[]>
Rows before filtering.
Examples
filterValues.current = {
"firstName": "",
"lastName": "",
"age": [
null,
null
],
"visits": 0
} | Name | Info | ||||
|---|---|---|---|---|---|
| First Name | Last Name | Age to | Status | Visits | Profile Progress |
| Claudine | Moore | 54 | relationship | 52 | 29 |
| Janet | Goodwin | 37 | complicated | 29 | 63 |
| Dwayne | Considine | 25 | relationship | 97 | 96 |
| Mary | Mayert | 18 | single | 52 | 64 |
| Sasha | Kovacek | 65 | complicated | 40 | 82 |
| Alexandre | Friesen | 64 | complicated | 63 | 82 |
| Tremaine | Botsford | 35 | single | 3 | 55 |
| Georgiana | Herman | 48 | single | 49 | 58 |
| Ross | Hoppe | 42 | relationship | 97 | 37 |
| Jace | King | 56 | complicated | 2 | 57 |
| Arch | Prosacco | 33 | single | 36 | 93 |
| Garnet | Okuneva | 60 | single | 97 | 77 |
| Oswaldo | Boehm | 29 | single | 22 | 36 |
| Rachael | Flatley | 22 | relationship | 81 | 17 |
| Kelvin | Wintheiser | 45 | complicated | 30 | 83 |
| Kareem | Flatley | 19 | single | 54 | 36 |
| Lurline | Schamberger-Kunze | 28 | single | 61 | 75 |
| Gustave | Hickle | 40 | relationship | 54 | 26 |
| Erna | Zieme | 44 | single | 55 | 64 |
| King | Mitchell | 32 | complicated | 24 | 7 |
| Amie | McLaughlin | 55 | single | 63 | 16 |
| Lloyd | Nitzsche | 65 | relationship | 77 | 18 |
| Odie | Schulist | 27 | relationship | 15 | 41 |
| Nils | Miller | 64 | complicated | 38 | 50 |
| Ransom | Kessler | 24 | complicated | 20 | 84 |
| Leda | Ratke | 30 | single | 0 | 55 |
| Leopold | Greenholt | 38 | complicated | 57 | 99 |
| Isidro | Sanford | 26 | single | 13 | 21 |
| Eugenia | Schroeder | 39 | relationship | 45 | 2 |
| Samantha | Cole | 35 | single | 92 | 43 |