MRT logoMaterial React Table

Legacy V2 Docs
On This Page

    Global Filtering (Search) Feature Guide

    Material React Table has a powerful built-in global filtering (search) feature that uses a fuzzy matching algorithm and ranks/sorts the results based on how closely rows match the search query. In this guide, we'll cover how to use, customize, or disable the global filter and search features to fit your needs.

    Relevant Table Options

    1
    boolean
    true
    MRT Column Filtering Docs
    2
    boolean
    true
    MRT Global Filtering Docs
    3
    boolean
    true
    MRT Global Filtering Docs
    4
    boolean
    true
    MRT Global Filtering Docs
    5
    (column: Column<TData, unknown>) => boolean
    6
    MRT_FilterOption
    7
    Array<MRT_FilterOption | string> | null
    8
    boolean
    TanStack Table Filters Docs
    9
    TextFieldProps | ({ table }) => TextFieldProps
    Material UI TextField Props
    10
    OnChangeFn<GlobalFilterState>
    TanStack Table Filters Docs
    11
    OnChangeFn<GlobalFilterState>
    TanStack Table Filters Docs
    12
    OnChangeFn<boolean>
    13
    'left' | 'right'
    'right'
    14
    ({ internalFilterOptions, onSelectFilterMode, table }) => ReactNode[]

    Relevant Column Options

    1
    boolean
    MRT Column Filtering Docs
    2
    boolean

    Relevant State Options

    1
    any
    TanStack Table Filtering Docs
    2
    MRT_FilterFn
    3
    boolean
    false

    Disable Global Filtering

    You can either disable the global filter feature entirely or disable it for specific columns.

    Disable Global Filtering per Column

    If you simply want to not include a column as one of the columns that the global filter scans through during filtering, you can set the enableGlobalFilter option to false for that column.

    const columns = [
    {
    accessorKey: 'id',
    header: 'Id',
    enableGlobalFilter: false, // do not scan this column during global filtering
    },
    {
    accessorKey: 'name',
    header: 'Name',
    },
    ];

    Disable Global Filter Feature

    You can disable the global filtering feature and hide the search icon by setting the enableGlobalFilter table option to false.

    const table = useMaterialReactTable({
    columns,
    data,
    enableGlobalFilter: false, //disable search feature
    });
    return <MaterialReactTable table={table} />;

    Client-Side Global Filtering

    Client-side filtering (and global filtering) is enabled by default. This means that the search box will scan through all columns and try to find matches for the search term.

    Global Filter Function

    You can use any of the built-in filterFns or any of the custom filter functions that you have defined in the filterFns prop, just like you would with the column filters.

    const table = useMaterialReactTable({
    columns,
    data,
    globalFilterFn: 'contains', //turn off fuzzy matching and use simple contains filter function
    });

    Or a custom filter function:

    const table = useMaterialReactTable({
    columns,
    data,
    filterFns: {
    myCustomFilterFn: (row, id, filterValue) =>
    row.getValue(id).startsWith(filterValue),
    },
    globalFilterFn: 'myCustomFilterFn', //set the global filter function to myCustomFilterFn
    });

    The default global filter function is set to fuzzy, which is a filtering algorithm based on the popular match-sorter library from Kent C. Dodds, though you can change the global filter function by setting the globalFilterFn table option.

    Ranked Results

    If you keep the default fuzzy filterFn option as the global filter function, you get an extra ranked results feature enabled by default. This means that when a user searches with the search box, the results will be sorted by the closest match first instead of the order the data was defined in.

    The ranked results feature will disable itself automatically if a sort direction is applied to a column, if any sub-rows are expanded, or if any of the manual props are set to true.

    If you do not want ranked results to be enabled at all, but you still want fuzzy matching, you can set the enableGlobalFilterRankedResults table option to false.

    const table = useMaterialReactTable({
    columns,
    data,
    enableGlobalFilterRankedResults: false, //preserve the order of the data when fuzzy match searching
    });

    Global Filter Modes

    Similar to the column filter modes, you can enable the user to be able to choose between multiple different filter modes for the global filter with the enableGlobalFilterModes table option. You can then customize which filter modes are available in the drop-down by setting the globalFilterModeOptions table option or by rendering your own custom menu items with the renderGlobalFilterModeMenuItems table option.

    const table = useMaterialReactTable({
    columns,
    data,
    enableGlobalFilterModes: true, //enable the user to choose between multiple search filter modes
    globalFilterModeOptions: ['fuzzy', 'startsWith'], //only allow the user to choose between fuzzy and startsWith filter modes
    });

    Show Search Field by Default

    Additionally, if you want to show the search text box by default and not hide it behind the search icon, you can set the showGlobalFilter state to true in the initialState.

    Manual Server-Side Global Filtering

    A very common use case when you have a lot of data is to filter the data on the server, instead of client-side. In this case, you will want to set the manualFiltering table option to true and manage the globalFilter state yourself like in the example below (can work in conjunction with manual column filtering).

    // You can manage and have control over the columnFilters state yourself
    const [globalFilter, setGlobalFilter] = useState('');
    const [data, setData] = useState([]); //data will get updated after re-fetching
    useEffect(() => {
    const fetchData = async () => {
    // send api requests when columnFilters state changes
    const filteredData = await fetch();
    setData([...filteredData]);
    };
    }, [globalFilter]);
    const table = useMaterialReactTable({
    columns,
    data, // this will already be filtered on the server
    manualFiltering: true, //turn off client-side filtering
    onGlobalFilterChange: setGlobalFilter, //hoist internal global state to your state
    state: { globalFilter }, //pass in your own managed globalFilter state
    });
    return <MaterialReactTable table={table} />;

    Specifying manualFiltering turns off all client-side filtering and assumes that the data you pass to <MaterialReactTable /> is already filtered.

    Here is the full Remote Data example showing off server-side filtering, pagination, and sorting.

    Demo

    Open StackblitzOpen Code SandboxOpen on GitHub

    No records to display

    0-0 of 0

    Source Code

    1import { useEffect, useMemo, useState } from 'react';
    2import {
    3 MaterialReactTable,
    4 useMaterialReactTable,
    5 type MRT_ColumnDef,
    6 type MRT_ColumnFiltersState,
    7 type MRT_PaginationState,
    8 type MRT_SortingState,
    9} from 'material-react-table';
    10
    11type UserApiResponse = {
    12 data: Array<User>;
    13 meta: {
    14 totalRowCount: number;
    15 };
    16};
    17
    18type User = {
    19 firstName: string;
    20 lastName: string;
    21 address: string;
    22 state: string;
    23 phoneNumber: string;
    24};
    25
    26const Example = () => {
    27 //data and fetching state
    28 const [data, setData] = useState<User[]>([]);
    29 const [isError, setIsError] = useState(false);
    30 const [isLoading, setIsLoading] = useState(false);
    31 const [isRefetching, setIsRefetching] = useState(false);
    32 const [rowCount, setRowCount] = useState(0);
    33
    34 //table state
    35 const [columnFilters, setColumnFilters] = useState<MRT_ColumnFiltersState>(
    36 [],
    37 );
    38 const [globalFilter, setGlobalFilter] = useState('');
    39 const [sorting, setSorting] = useState<MRT_SortingState>([]);
    40 const [pagination, setPagination] = useState<MRT_PaginationState>({
    41 pageIndex: 0,
    42 pageSize: 10,
    43 });
    44
    45 //if you want to avoid useEffect, look at the React Query example instead
    46 useEffect(() => {
    47 const fetchData = async () => {
    48 if (!data.length) {
    49 setIsLoading(true);
    50 } else {
    51 setIsRefetching(true);
    52 }
    53
    54 const url = new URL(
    55 '/api/data',
    56 process.env.NODE_ENV === 'production'
    57 ? 'https://www.material-react-table.com'
    58 : 'http://localhost:3000',
    59 );
    60 url.searchParams.set(
    61 'start',
    62 `${pagination.pageIndex * pagination.pageSize}`,
    63 );
    64 url.searchParams.set('size', `${pagination.pageSize}`);
    65 url.searchParams.set('filters', JSON.stringify(columnFilters ?? []));
    66 url.searchParams.set('globalFilter', globalFilter ?? '');
    67 url.searchParams.set('sorting', JSON.stringify(sorting ?? []));
    68
    69 try {
    70 const response = await fetch(url.href);
    71 const json = (await response.json()) as UserApiResponse;
    72 setData(json.data);
    73 setRowCount(json.meta.totalRowCount);
    74 } catch (error) {
    75 setIsError(true);
    76 console.error(error);
    77 return;
    78 }
    79 setIsError(false);
    80 setIsLoading(false);
    81 setIsRefetching(false);
    82 };
    83 fetchData();
    84 // eslint-disable-next-line react-hooks/exhaustive-deps
    85 }, [
    86 columnFilters, //re-fetch when column filters change
    87 globalFilter, //re-fetch when global filter changes
    88 pagination.pageIndex, //re-fetch when page index changes
    89 pagination.pageSize, //re-fetch when page size changes
    90 sorting, //re-fetch when sorting changes
    91 ]);
    92
    93 const columns = useMemo<MRT_ColumnDef<User>[]>(
    94 () => [
    95 {
    96 accessorKey: 'firstName',
    97 header: 'First Name',
    98 },
    99 //column definitions...
    117 ],
    118 [],
    119 );
    120
    121 const table = useMaterialReactTable({
    122 columns,
    123 data,
    124 enableRowSelection: true,
    125 getRowId: (row) => row.phoneNumber,
    126 initialState: { showColumnFilters: true },
    127 manualFiltering: true,
    128 manualPagination: true,
    129 manualSorting: true,
    130 muiToolbarAlertBannerProps: isError
    131 ? {
    132 color: 'error',
    133 children: 'Error loading data',
    134 }
    135 : undefined,
    136 onColumnFiltersChange: setColumnFilters,
    137 onGlobalFilterChange: setGlobalFilter,
    138 onPaginationChange: setPagination,
    139 onSortingChange: setSorting,
    140 rowCount,
    141 state: {
    142 columnFilters,
    143 globalFilter,
    144 isLoading,
    145 pagination,
    146 showAlertBanner: isError,
    147 showProgressBars: isRefetching,
    148 sorting,
    149 },
    150 });
    151
    152 return <MaterialReactTable table={table} />;
    153};
    154
    155export default Example;
    156

    Customize Global Filter Position

    You can customize the position of the global filter (search box) in the top toolbar by setting the positionGlobalFilter table option to left or right. It is shown on the right by default.

    const table = useMaterialReactTable({
    columns,
    data,
    positionGlobalFilter: 'left', //show the global filter on the left side of the top toolbar
    initialState: {
    showGlobalFilter: true, //show the global filter by default
    },
    });

    Customize the Search Text Field

    You can customize the search text field by passing in props to the muiSearchTextFieldProps table option. This is useful if you want to customize the placeholder text, add styles, or any other text field props.

    const table = useMaterialReactTable({
    columns,
    data,
    muiSearchTextFieldProps: {
    placeholder: 'Search all users',
    sx: { minWidth: '300px' },
    variant: 'outlined',
    },
    });
    return <MaterialReactTable table={table} />;

    Demo

    1HughJayMungus42
    2LeroyLeroyJenkins51
    3CandiceDeniseNutella27
    4MicahHenryJohnson32
    1-4 of 4

    Source Code

    1import { useMemo } from 'react';
    2import { MaterialReactTable, type MRT_ColumnDef } from 'material-react-table';
    3import { data, type Person } from './makeData';
    4
    5const Example = () => {
    6 const columns = useMemo<MRT_ColumnDef<Person>[]>(
    7 //column definitions...
    32 );
    33
    34 return (
    35 <MaterialReactTable
    36 columns={columns}
    37 data={data}
    38 enableGlobalFilterModes
    39 initialState={{
    40 showGlobalFilter: true,
    41 }}
    42 positionGlobalFilter="left"
    43 muiSearchTextFieldProps={{
    44 placeholder: `Search ${data.length} rows`,
    45 sx: { minWidth: '300px' },
    46 variant: 'outlined',
    47 }}
    48 />
    49 );
    50};
    51
    52export default Example;
    53

    Filter Match Highlighting

    Filter match highlighting is a new featured enabled by default that will highlight text in the table body cells that matches the current search query with a shade of the theme.palette.warning.main color.

    If you are using a custom Cell render override for a column, you will need to use the renderedCellValue table option instead of cell.getValue() to preserve the filter match highlighting.

    const columns = [
    {
    accessorKey: 'name',
    header: 'Name',
    Cell: ({ renderedCellValue }) => <span>{renderedCellValue}</span>, // use renderedCellValue instead of cell.getValue()
    },
    ];

    Disable Filter Match Highlighting

    Filter match highlighting can be disabled by setting the enableFilterMatchHighlighting table option to false.

    const table = useMaterialReactTable({
    columns,
    data,
    enableFilterMatchHighlighting: false, //disable filter match highlighting
    });

    View Extra Storybook Examples