Filtering

View as Markdown
Filtering allows you to limit the rows available in the table.
Both client-side and server-side filtering are available in Infinite Table - but the way the are configured is pretty similar, so this page documents the common parts, while pointing to the respective pages for the differences.

Configuring Filters for Columns#

The most common way to use filtering in Infinite Table is by configuring filters for columns (this works both for client-side and server-side filtering).
You specify an uncontrolled defaultFilterValue on the <DataSource /> component (or the controlled version, filterValue) and the specified value will be used as the initial filter.
Based on the column type, the correct filter editor is displayed in the column header, along with the correct operator icon. In the UI, you can change the operator being used for the filter.
Specifying an initial filter value for the DataSource
<DataSource<Developer>
  primaryKey="id"
  data={data}
  defaultFilterValue={[
    {
      field: 'age',
      filter: {
        operator: 'gt',
        value: 30,
        type: 'number'
      }
    }
  ]}
>
  <InfiniteTable<Developer>
    columns={columns}
  />
</DataSource>
If you don't need to specify some initial filters, but want the column filter bar to be visible, you need to specify defaultFilterValue = [] (or the controlled filterValue = []).
Specifying any of those props will make the column filter bar visible.
Whenever filters change, onFilterChange will be called with the new filter value - note however, it might not be called immediately, due to the filterDelay prop.
The above snippet will show a number filter for the age column. There are two filter types available at this stage in Infinite Table:
  • string - with the following operators available: contains, eq, startsWith and endsWith
  • number - with the following operators available: eq,neq, gt, gte, lt and lte

Defining Filterable Columns#

By default, all columns are filterable.
If you want to make columns by default not filterable, use the columnDefaultFilterable prop and set it to false.
You can specifically configure each column by using the defaultFilterable property - this overrides the global columnDefaultFilterable prop.

Defining a Filter Type for a Column#

Besides being filterable, a column can decide what type of filter it will display.
Use the columns.type property to specify the type of filter the column will use. Using the type property also configures the data type of the column, which in turn determines the sort type.
If the type of filter you want to show does not match the column type, you can specify the filter with the column.filterType property. Only use this when the type of the data differs from the type of the filter (eg: you have a numeric column, with a custom filter type).

Understanding Filter Types#

A filter type is a concept that defines how a certain type of data is to be filtered. A filter type will have
  • a key - the key used to define the filter in the filterTypes object
  • a label,
  • an array of values considered to be empty values - when any of these values is used in the filter, the filter will not be applied.
  • an array of operators
  • a default operator.
Let's imagine you have a DataSource with developers, each with a salary column, and for that column you want to allow >, >=, < and <= comparisons (operators).
For this, you would define the following filter type:
const filterTypes: DataSourcePropFilterTypes<Developer> = {
  income: {
    label: 'Income',
    emptyValues: ['', null, undefined],
    defaultOperator: 'gt',
    operators: [
      {
        name: 'gt',
        label: 'Greater than',
        fn: ({ currentValue, filterValue, emptyValues }) => {
          if (emptyValues.includes(currentValue)) {
            return true;
          }
          return currentValue > filterValue;
        },
      },
      {
        name: 'gte',
        fn: ({ currentValue, filterValue }) => currentValue >= filterValue,
        //...
      },
      {
        name: 'lt',
        fn: ({ currentValue, filterValue }) => currentValue < filterValue,
        //...
      },
      {
        name: 'lte',
        fn: ({ currentValue, filterValue }) => currentValue <= filterValue,
        //...
      },
    ],
  },
};
Each operator for a certain filter type needs to at least have a name and fn defined. The fn property is a function that will be called when client-side filtering is enabled, with an object that has the following properties:
  • currentValue - the cell value of the current row for the column being filtered
  • filterValue - the value of the filter editor
  • emptyValues - the array of values considered to be empty values for the filter type
  • data - the current row data object - typeof DATA_TYPE
  • index - the index of the current row in the table - number
  • dataArray - the array of all rows originally in the table - typeof DATA_TYPE[]
  • field? - the field the current column is bound to (can be undefined if the column is not bound to a field)
#
Client-side filtering in action with custom filter type
The salary column has a custom filter type, with the following operators: gt, gte, lt and lte.
open
loading demo…

Client-side or server-side filtering#

As already mentioned, filtering can happen either client-side or server-side. By default, it happens client-side - also when the DataSource data property is a function. The only exceptions are lazyLoad and livePagination, where only part of the data is loaded, so it has to be filtered by the server.
To filter server-side, set shouldReloadData.filterValue: true - the data function is then called again on every filter change, with the filterValue in its params.
To both reload the data and filter it client-side, also specify a filterFunction - for example filterFunction={defaultFilterFunction}, which applies the column filters.

Filtering Columns Not Bound to a Field#

If a column is not bound to a field, it can still be used for filtering, even client-side filtering, if it is configured with a columns.valueGetter.
If you don't need a default filter value, the filterValue that's set when the user interacts with the column filter will use the column valueGetter to filter values.
If however, you need initial filtering by that column, the filterValue needs to specify a valueGetter itself.
defaultFilterValue={[
  {
    id: 'salary',
    valueGetter: ({ data }) => data.salary,
    filter: {
      operator: 'gt',
      value: '',
      type: 'number',
    }
  },
]}
#
Filtering a column not bound to a field
The salary column is not bound to a field - however, it can still be used for filtering, as it's configured with a valueGetter.
open
loading demo…

Customizing the Filter Icon for Columns#

Columns can customize the filter icon by using the columns.renderFilterIcon property.
#
Custom filter icons for salary and name columns
The salary column will show a bolded label when filtered.
The firstName column will show a custom filter icon when filtered.
open
loading demo…

Client-side filtering

Learn how to use filtering in the browser.

Server-side filtering

Figure out how to use filtering with server-side integration.