DocsBlog
  • 1.2.1

  • light

    dark

    system

    Switch mode
  • Cerberus

    Acheron

    Elysium

Get Started
Components
Data Grid
Signals
Styling
Theming

Get Started

OverviewQuick StartColumnsContextTheme

Layout

DimensionsSizingSlotsOverlaysNewToolbarFooterPagination

Features

PinningSortingFilteringNew

Reference

API

On this page

Loading...

Loading...

Loading...

Loading...

On this page

  • Edit this page on Github

Filtering

Learn about the filtering feature in the Data Grid component.

  • source

Overview

Filtering allows users to view a subset of data based on criteria. There are three ways for a user to filter:

  1. Single-column filtering: Clicking the "Filter" option from the feature menu when the column has opted into filtering.
  2. Multi-column filtering: Following option 1 for any additional column
  3. Global filtering: Utilizing the setGlobalFilter action from the Data Grid Context.

Active Actions

Once a filter is active, the user can:

  1. Edit filters: Clicking the added "Edit filter" icon button that displays in the column header that has the active filter.
  2. Clear filters: Clicking the "Clear Filter" option in the column feature menu.

Implementing column filtering

You must opt-in to column filtering by setting the features.filter prop to true or passing in a custom filter function. Doing so will display the filter option in the column menu.

Multi-column Filtering

Multi-column filtering is enabled by default. The user simply selects another column to filter in addition to any other column that is actively filtered.

Global Filtering

You can globally filter the Grid by utilizing the setGlobalFilter action in any slot component you provide.

In this example, we create a custom Toolbar that filters the grid globally on input.

Custom Comparator

A comparator determines how two cell values should be filtered. The default comparator uses the vanilla JavaScript basic comparison from the Operator provided.

To provide a custom comparator, you can pass a function as the features.filter option.

The snippet below is the same comparator we are using for all the demos on this page.

Operators

The Data Grid provides an OPERATORS constant which is used to ensure consistency across any filter-based approach you may use.

Options

The filter feature accepts either a boolean or a custom filter function that provides the following arguments:

ParamsTypeDescription
rowTDataThe row of the grid comparing the filter.
columnIdstringThe columnId the filter is applied to.
filterValueunknownThe value provided to the filter.
Copy
'use client'

import { DataGrid } from '@cerberus/data-grid'
import { Box } from 'styled-system/jsx'
import { createFakeQuery } from '../quick-start/data'
import { columns } from './columns'

export function BasicDemo() {
  const data = createFakeQuery(1000)
  return (
    <Box h="20rem" w="90%">
      <DataGrid columns={columns} data={data()} />
    </Box>
  )
}

// columnHelper.accessor('id', {
//   header: 'ID',
//   width: 80,
//   features: {
//     pinning: {
//       defaultPosition: 'left',
//     },
//     sort: true,
//     filter: true,
//   },
//   cell: ({ value }) => <Text>#{value}</Text>,
// })
Copy
'use client'

import { Search } from '@carbon/icons-react'
import { DataGrid, OPERATORS, useDataGridContext } from '@cerberus/data-grid'
import { Button, cerberus, Field, Input, Show } from '@cerberus/react'
import { useRead } from '@cerberus/signals'
import { HStack, Stack } from 'styled-system/jsx'
import { createFakeQuery } from '../quick-start/data'
import { columns } from './columns'

export function GlobalDemo() {
  const data = createFakeQuery(200)
  return (
    <Stack direction="column" h="25rem" w="90%">
      <DataGrid columns={columns} data={data()} toolbar={<Toolbar />} />
    </Stack>
  )
}

function Toolbar<TData>() {
  const store = useDataGridContext<TData>()
  const currentFilter = useRead(store.globalFilter)

  function search(formData: FormData) {
    const value = formData.get('search') as string
    store.setGlobalFilter({ value, operator: OPERATORS.contains })
  }

  return (
    <HStack justify="flex-end" w="full">
      <HStack gap="md" justify="flex-end" w="1/2">
        <Show when={currentFilter.value}>
          <Button
            palette="danger"
            onClick={() =>
              store.setGlobalFilter({
                operator: OPERATORS.contains,
                value: null,
              })
            }
            size="sm"
          >
            Clear
          </Button>
        </Show>

        <cerberus.form action={search} w="3/4">
          <Field hideLabel label="Search anything">
            <Input
              placeholder="Press enter to search..."
              name="search"
              startIcon={<Search />}
              size="md"
            />
            <button type="submit" hidden>
              Search
            </button>
          </Field>
        </cerberus.form>
      </HStack>
    </HStack>
  )
}
Copy
'use client'

import { DataGrid } from '@cerberus/data-grid'
import { Box } from 'styled-system/jsx'
import { createFakeQuery } from '../quick-start/data'
import { columns } from './columns'

export function BasicDemo() {
  const data = createFakeQuery(1000)
  return (
    <Box h="20rem" w="90%">
      <DataGrid columns={columns} data={data()} />
    </Box>
  )
}

// columnHelper.accessor('id', {
//   header: 'ID',
//   width: 80,
//   features: {
//     pinning: {
//       defaultPosition: 'left',
//     },
//     sort: true,
//     filter: true,
//   },
//   cell: ({ value }) => <Text>#{value}</Text>,
// })
import { VStack } from '@/styled-system/jsx'
import { Text } from '@cerberus/react'
import { columnHelper } from '../quick-start/helper.demo'

export const columns = [
  columnHelper.accessorFn((row) => `${row.firstName} ${row.lastName}`, {
    id: 'fullName',
    header: 'Employee',
    minWidth: 300,
    features: {
      sort: true,
      filter: (row, _colId, val) => {
        // 1. Bail early if the user cleared the input
        if (!val) return true
        // 2. Normalize the search term to lowercase
        const searchTerm = String(val).toLowerCase()
        // 3. Reconstruct the string we want to search
        const fullName = `${row.firstName} ${row.lastName}`.toLowerCase()
        // 4. Grab the email from the raw row data
        const email = String(row.email).toLowerCase()
        // 5. Match against BOTH
        // If they type "john", it matches the name.
        // If they type "@company.com", it matches the email.
        return fullName.includes(searchTerm) || email.includes(searchTerm)
      },
    },
    cell: ({ row, value }) => (
      <VStack alignItems="flex-start" gap="0">
        <Text textStyle="body-md">{value}</Text>
        <Text color="page.text.100" textStyle="label-sm">
          {row.email}
        </Text>
      </VStack>
    ),
  }),
]
import { type FilterOperator } from '@cerberus/data-grid'

export const OPERATORS: Record<FilterOperator, FilterOperator> = {
  contains: 'contains',
  equals: 'equals',
  starts_with: 'starts_with',
  ends_with: 'ends_with',
  greater_than: 'greater_than',
  less_than: 'less_than',
  between: 'between',
  includes_some: 'includes_some',
}