Blog>
Snippets

Implementing Multi-Select Filters in React TanStack Table

Explain how to enhance column filtering by creating a multi-select dropdown filter, allowing users to filter table data based on multiple selection options.
// MultiSelectFilter.js
import React from 'react';

export function MultiSelectFilter({
  column: { filterValue, setFilter, preFilteredRows, id },
}) {
  const options = React.useMemo(() => {
    const optionsSet = new Set();
    preFilteredRows.forEach(row => {
      optionsSet.add(row.values[id]);
    });
    return [...optionsSet.values()];
  }, [id, preFilteredRows]);

  return (
    <select
      multiple
      value={filterValue}
      onChange={e => {
        const value = Array.from(e.target.selectedOptions, option => option.value);
        setFilter(value || undefined);
      }}
    >
      {options.map(option => (
        <option key={option} value={option}>
          {option}
        </option>
      ))}
    </select>
  );
}
This component creates a multi-select dropdown filter for a specific column in a React TanStack Table. It uses useMemo to calculate column options based on the distinct values present in preFilteredRows for the given column id. onChange, it captures multiple selected values and updates the filter value for that column, which the useFilters hook uses to filter the table data.
// Use the MultiSelectFilter component in your table column definition
const columns = React.useMemo(
  () => [
    {
      Header: 'Example Column',
      accessor: 'exampleColumn',
      Filter: MultiSelectFilter,
      filter: 'includesMultiple'
    },
    // Other column definitions
  ],
  []
);
This snippet demonstrates how to integrate the MultiSelectFilter component into a column definition for a React TanStack Table. 'includesMultiple' is a custom filter type that needs to be implemented to handle array of selected values for filtering.
// Implementing custom filter logic
const filterTypes = React.useMemo(
  () => ({
    includesMultiple: (rows, id, filterValue) => {
      if (filterValue && filterValue.length) {
        return rows.filter(row =>
          filterValue.includes(row.values[id])
        );
      }
      return rows;
    },
  }),
  []
);
This code snippet defines a custom filter logic 'includesMultiple' that works with the MultiSelectFilter component. It filters the rows based on whether the row's value for a given column id is included in the selected filter values.