Filters
The ability to filter data in a table.
Can-Filter
The ability for a column to be column filtered is determined by the following:
- The column was defined with a valid
accessorKey/accessorFn. column.enableColumnFilteris not set tofalseoptions.enableColumnFiltersis not set tofalseoptions.enableFiltersis not set tofalse
The ability for a column to be globally filtered is determined by the following:
- The column was defined a valid
accessorKey/accessorFn. - If provided,
options.getColumnCanGlobalFilterreturnstruefor the given column. If it is not provided, the column is assumed to be globally filterable if the value in the first row is astringornumbertype. column.enableColumnFilteris not set tofalseoptions.enableColumnFiltersis not set tofalseoptions.enableFiltersis not set tofalse
State
Filter state is stored on the table using the following shape:
export type FiltersTableState = {
columnFilters: ColumnFiltersState
globalFilter: any
}
export type ColumnFiltersState = ColumnFilter[]
export type ColumnFilter = {
id: string
value: unknown
}export type FiltersTableState = {
columnFilters: ColumnFiltersState
globalFilter: any
}
export type ColumnFiltersState = ColumnFilter[]
export type ColumnFilter = {
id: string
value: unknown
}Filter Functions
The following filter functions are built-in to the table core:
includesString- Case-insensitive string inclusion
includesStringSensitive- Case-sensitive string inclusion
equalsString- Case-insensitive string equality
equalsStringSensitive- Case-sensitive string equality
arrIncludes- Item inclusion within an array
arrIncludesAll- All items included in an array
arrIncludesSome- Some items included in an array
equals- Object/referential equality
Object.is/===
- Object/referential equality
weakEquals- Weak object/referential equality
==
- Weak object/referential equality
inNumberRange- Number range inclusion
Every filter function receives:
- The row to filter
- The columnId to use to retrieve the row's value
- The filter value
and should return true if the row should be included in the filtered rows, and false if it should be removed.
This is the type signature for every filter function:
export type FilterFn<TData extends AnyData> = {
(
row: Row<TData>,
columnId: string,
filterValue: any,
addMeta: (meta: any) => void
): boolean
resolveFilterValue?: TransformFilterValueFn<TData>
autoRemove?: ColumnFilterAutoRemoveTestFn<TData>
addMeta?: (meta?: any) => void
}
export type TransformFilterValueFn<TData extends AnyData> = (
value: any,
column?: Column<TData>
) => unknown
export type ColumnFilterAutoRemoveTestFn<TData extends AnyData> = (
value: any,
column?: Column<TData>
) => boolean
export type CustomFilterFns<TData extends AnyData> = Record<
string,
FilterFn<TData>
>export type FilterFn<TData extends AnyData> = {
(
row: Row<TData>,
columnId: string,
filterValue: any,
addMeta: (meta: any) => void
): boolean
resolveFilterValue?: TransformFilterValueFn<TData>
autoRemove?: ColumnFilterAutoRemoveTestFn<TData>
addMeta?: (meta?: any) => void
}
export type TransformFilterValueFn<TData extends AnyData> = (
value: any,
column?: Column<TData>
) => unknown
export type ColumnFilterAutoRemoveTestFn<TData extends AnyData> = (
value: any,
column?: Column<TData>
) => boolean
export type CustomFilterFns<TData extends AnyData> = Record<
string,
FilterFn<TData>
>filterFn.resolveFilterValue
This optional "hanging" method on any given filterFn allows the filter function to transform/sanitize/format the filter value before it is passed to the filter function.
filterFn.autoRemove
This optional "hanging" method on any given filterFn is passed a filter value and expected to return true if the filter value should be removed from the filter state. eg. Some boolean-style filters may want to remove the filter value from the table state if the filter value is set to false.
Using Filter Functions
Filter functions can be used/referenced/defined by passing the following to columnDefinition.filterFn or options.globalFilterFn:
- A
stringthat references a built-in filter function - A function directly provided to the
columnDefinition.filterFnoption
The final list of filter functions available for the columnDef.filterFn and tableOptions.globalFilterFn options use the following type:
export type FilterFnOption<TData extends AnyData> =
| "auto"
| BuiltInFilterFn
| FilterFn<TData>export type FilterFnOption<TData extends AnyData> =
| "auto"
| BuiltInFilterFn
| FilterFn<TData>Filter Meta
Filtering data can often expose additional information about the data that can be used to aid other future operations on the same data. A good example of this concept is a ranking-system like that of match-sorter that simultaneously ranks, filters and sorts data. While utilities like match-sorter make a lot of sense for single-dimensional filter+sort tasks, the decoupled filtering/sorting architecture of building a table makes them very difficult and slow to use.
To make a ranking/filtering/sorting system work with tables, filterFns can optionally mark results with a filter meta value that can be used later to sort/group/etc the data to your liking. This is done by calling the addMeta function supplied to your custom filterFn.
Below is an example using our own match-sorter-utils package (a utility fork of match-sorter) to rank, filter, and sort the data
import { compareItems, rankItem } from "@tanstack/match-sorter-utils"
import { sortingFns } from "@tanstack/react-table"
const fuzzyFilter = (row, columnId, value, addMeta) => {
// Rank the item
const itemRank = rankItem(row.getValue(columnId), value)
// Store the ranking info
addMeta(itemRank)
// Return if the item should be filtered in/out
return itemRank.passed
}
const fuzzySort = (rowA, rowB, columnId) => {
let dir = 0
// Only sort by rank if the column has ranking information
if (rowA.columnFiltersMeta[columnId]) {
dir = compareItems(
rowA.columnFiltersMeta[columnId]!,
rowB.columnFiltersMeta[columnId]!
)
}
// Provide an alphanumeric fallback for when the item ranks are equal
return dir === 0 ? sortingFns.alphanumeric(rowA, rowB, columnId) : dir
}import { compareItems, rankItem } from "@tanstack/match-sorter-utils"
import { sortingFns } from "@tanstack/react-table"
const fuzzyFilter = (row, columnId, value, addMeta) => {
// Rank the item
const itemRank = rankItem(row.getValue(columnId), value)
// Store the ranking info
addMeta(itemRank)
// Return if the item should be filtered in/out
return itemRank.passed
}
const fuzzySort = (rowA, rowB, columnId) => {
let dir = 0
// Only sort by rank if the column has ranking information
if (rowA.columnFiltersMeta[columnId]) {
dir = compareItems(
rowA.columnFiltersMeta[columnId]!,
rowB.columnFiltersMeta[columnId]!
)
}
// Provide an alphanumeric fallback for when the item ranks are equal
return dir === 0 ? sortingFns.alphanumeric(rowA, rowB, columnId) : dir
}Column Def Options
filterFn
filterFn?: FilterFn | keyof FilterFns | keyof BuiltInFilterFnsfilterFn?: FilterFn | keyof FilterFns | keyof BuiltInFilterFnsThe filter function to use with this column.
Options:
- A
stringreferencing a built-in filter function - A custom filter function
enableColumnFilter
enableColumnFilter?: booleanenableColumnFilter?: booleanEnables/disables the column filter for this column.
enableGlobalFilter
enableGlobalFilter?: booleanenableGlobalFilter?: booleanEnables/disables the global filter for this column.
Column API
getCanFilter
getCanFilter: () => booleangetCanFilter: () => booleanReturns whether or not the column can be column filtered.
getCanGlobalFilter
getCanGlobalFilter: () => booleangetCanGlobalFilter: () => booleanReturns whether or not the column can be globally filtered.
getFilterIndex
getFilterIndex: () => numbergetFilterIndex: () => numberReturns the index (including -1) of the column filter in the table's state.columnFilters array.
getIsFiltered
getIsFiltered: () => booleangetIsFiltered: () => booleanReturns whether or not the column is currently filtered.
getFilterValue
getFilterValue: () => unknowngetFilterValue: () => unknownReturns the current filter value of the column.
setFilterValue
setFilterValue: (updater: Updater<any>) => voidsetFilterValue: (updater: Updater<any>) => voidA function that sets the current filter value for the column. You can pass it a value or an updater function for immutability-safe operations on existing values.
getAutoFilterFn
getAutoFilterFn: (columnId: string) => FilterFn<TData> | undefinedgetAutoFilterFn: (columnId: string) => FilterFn<TData> | undefinedReturns an automatically calculated filter function for the column based off of the columns first known value.
getFilterFn
getFilterFn: (columnId: string) => FilterFn<TData> | undefinedgetFilterFn: (columnId: string) => FilterFn<TData> | undefinedReturns the filter function (either user-defined or automatic, depending on configuration) for the columnId specified.
getFacetedRowModel
type getFacetedRowModel = () => RowModel<TData>type getFacetedRowModel = () => RowModel<TData>⚠️ Requires that you pass a valid
getFacetedRowModelfunction tooptions.facetedRowModel. A default implementation is provided via the exportedgetFacetedRowModelfunction.
Returns the row model with all other column filters applied, excluding its own filter. Useful for displaying faceted result counts.
getFacetedUniqueValues
getFacetedUniqueValues: () => Map<any, number>getFacetedUniqueValues: () => Map<any, number>⚠️ Requires that you pass a valid
getFacetedUniqueValuesfunction tooptions.getFacetedUniqueValues. A default implementation is provided via the exportedgetFacetedUniqueValuesfunction.
A function that computes and returns a Map of unique values and their occurrences derived from column.getFacetedRowModel. Useful for displaying faceted result values.
getFacetedMinMaxValues
getFacetedMinMaxValues: () => Map<any, number>getFacetedMinMaxValues: () => Map<any, number>⚠️ Requires that you pass a valid
getFacetedMinMaxValuesfunction tooptions.getFacetedMinMaxValues. A default implementation is provided via the exportedgetFacetedMinMaxValuesfunction.
A function that computes and returns a min/max tuple derived from column.getFacetedRowModel. Useful for displaying faceted result values.
Row API
columnFilters
columnFilters: Record<string, boolean>columnFilters: Record<string, boolean>The column filters map for the row. This object tracks whether a row is passing/failing specific filters by their column ID.
columnFiltersMeta
columnFiltersMeta: Record<string, any>columnFiltersMeta: Record<string, any>The column filters meta map for the row. This object tracks any filter meta for a row as optionally provided during the filtering process.
Table Options
filterFns
filterFns?: Record<string, FilterFn>filterFns?: Record<string, FilterFn>This option allows you to define custom filter functions that can be referenced in a column's filterFn option by their key.
Example:
declare module "@tanstack/table-core" {
interface FilterFns {
myCustomFilter: FilterFn<unknown>
}
}
const column = columnHelper.data("key", {
filterFn: "myCustomFilter",
})
const table = useTable({
columns: [column],
filterFns: {
myCustomFilter: (rows, columnIds, filterValue) => {
// return the filtered rows
},
},
})declare module "@tanstack/table-core" {
interface FilterFns {
myCustomFilter: FilterFn<unknown>
}
}
const column = columnHelper.data("key", {
filterFn: "myCustomFilter",
})
const table = useTable({
columns: [column],
filterFns: {
myCustomFilter: (rows, columnIds, filterValue) => {
// return the filtered rows
},
},
})filterFromLeafRows
filterFromLeafRows?: booleanfilterFromLeafRows?: booleanBy default, filtering is done from parent rows down (so if a parent row is filtered out, all of its children will be filtered out as well). Setting this option to true will cause filtering to be done from leaf rows up (which means parent rows will be included so long as one of their child or grand-child rows is also included).
maxLeafRowFilterDepth
maxLeafRowFilterDepth?: numbermaxLeafRowFilterDepth?: numberBy default, filtering is done for all rows (max depth of 100), no matter if they are root level parent rows or the child leaf rows of a parent row. Setting this option to 0 will cause filtering to only be applied to the root level parent rows, with all sub-rows remaining unfiltered. Similarly, setting this option to 1 will cause filtering to only be applied to child leaf rows 1 level deep, and so on.
This is useful for situations where you want a row's entire child hierarchy to be visible regardless of the applied filter.
enableFilters
enableFilters?: booleanenableFilters?: booleanEnables/disables all filters for the table.
manualFiltering
manualFiltering?: booleanmanualFiltering?: booleanDisables the getFilteredRowModel from being used to filter data. This may be useful if your table needs to dynamically support both client-side and server-side filtering.
onColumnFiltersChange
onColumnFiltersChange?: OnChangeFn<ColumnFiltersState>onColumnFiltersChange?: OnChangeFn<ColumnFiltersState>If provided, this function will be called with an updaterFn when state.columnFilters changes. This overrides the default internal state management, so you will need to persist the state change either fully or partially outside of the table.
enableColumnFilters
enableColumnFilters?: booleanenableColumnFilters?: booleanEnables/disables all column filters for the table.
getFilteredRowModel
getFilteredRowModel?: (
table: Table<TData>
) => () => RowModel<TData>getFilteredRowModel?: (
table: Table<TData>
) => () => RowModel<TData>If provided, this function is called once per table and should return a new function which will calculate and return the row model for the table when it's filtered.
- For server-side filtering, this function is unnecessary and can be ignored since the server should already return the filtered row model.
- For client-side filtering, this function is required. A default implementation is provided via any table adapter's
{ getFilteredRowModel }export.
Example:
import { getFilteredRowModel } from '@tanstack/[adapter]-table'
getFilteredRowModel: getFilteredRowModel(),
})import { getFilteredRowModel } from '@tanstack/[adapter]-table'
getFilteredRowModel: getFilteredRowModel(),
})getColumnFacetedRowModel
getColumnFacetedRowModel: (columnId: string) => RowModel<TData>getColumnFacetedRowModel: (columnId: string) => RowModel<TData>Returns the faceted row model for a given columnId.
globalFilterFn
globalFilterFn?: FilterFn | keyof FilterFns | keyof BuiltInFilterFnsglobalFilterFn?: FilterFn | keyof FilterFns | keyof BuiltInFilterFnsThe filter function to use for global filtering.
Options:
- A
stringreferencing a built-in filter function) - A
stringthat references a custom filter functions provided via thetableOptions.filterFnsoption - A custom filter function
onGlobalFilterChange
onGlobalFilterChange?: OnChangeFn<GlobalFilterState>onGlobalFilterChange?: OnChangeFn<GlobalFilterState>If provided, this function will be called with an updaterFn when state.globalFilter changes. This overrides the default internal state management, so you will need to persist the state change either fully or partially outside of the table.
enableGlobalFilter
enableGlobalFilter?: booleanenableGlobalFilter?: booleanEnables/disables the global filter for the table.
getColumnCanGlobalFilter
getColumnCanGlobalFilter?: (column: Column<TData>) => booleangetColumnCanGlobalFilter?: (column: Column<TData>) => booleanIf provided, this function will be called with the column and should return true or false to indicate whether this column should be used for global filtering.
This is useful if the column can contain data that is not string or number (i.e. undefined).
Table API
setColumnFilters
setColumnFilters: (updater: Updater<ColumnFiltersState>) => voidsetColumnFilters: (updater: Updater<ColumnFiltersState>) => voidSets or updates the state.columnFilters state.
resetColumnFilters
resetColumnFilters: (defaultState?: boolean) => voidresetColumnFilters: (defaultState?: boolean) => voidResets the columnFilters state to initialState.columnFilters, or true can be passed to force a default blank state reset to [].
getPreFilteredRowModel
getPreFilteredRowModel: () => RowModel<TData>getPreFilteredRowModel: () => RowModel<TData>Returns the row model for the table before any column filtering has been applied.
getFilteredRowModel
getFilteredRowModel: () => RowModel<TData>getFilteredRowModel: () => RowModel<TData>Returns the row model for the table after column filtering has been applied.
setGlobalFilter
setGlobalFilter: (updater: Updater<any>) => voidsetGlobalFilter: (updater: Updater<any>) => voidSets or updates the state.globalFilter state.
resetGlobalFilter
resetGlobalFilter: (defaultState?: boolean) => voidresetGlobalFilter: (defaultState?: boolean) => voidResets the globalFilter state to initialState.globalFilter, or true can be passed to force a default blank state reset to undefined.
getGlobalAutoFilterFn
getGlobalAutoFilterFn: (columnId: string) => FilterFn<TData> | undefinedgetGlobalAutoFilterFn: (columnId: string) => FilterFn<TData> | undefinedCurrently, this function returns the built-in includesString filter function. In future releases, it may return more dynamic filter functions based on the nature of the data provided.
getGlobalFilterFn
getGlobalFilterFn: (columnId: string) => FilterFn<TData> | undefinedgetGlobalFilterFn: (columnId: string) => FilterFn<TData> | undefinedReturns the global filter function (either user-defined or automatic, depending on configuration) for the table.
getGlobalFacetedRowModel
getGlobalFacetedRowModel: () => RowModel<TData>getGlobalFacetedRowModel: () => RowModel<TData>Returns the faceted row model for the global filter.
getGlobalFacetedUniqueValues
getGlobalFacetedUniqueValues: () => Map<any, number>getGlobalFacetedUniqueValues: () => Map<any, number>Returns the faceted unique values for the global filter.
getGlobalFacetedMinMaxValues
getGlobalFacetedMinMaxValues: () => [number, number]getGlobalFacetedMinMaxValues: () => [number, number]Returns the faceted min and max values for the global filter.
Credits
- Filters - TanStack Table
v8Docs