How to add search and filter to DataTable with Data
This how-to guide shows you how to use the Data component to easily add searching and filtering to a DataTable.
Prerequisites
Let’s get started!
Use this CodeSandbox template to start. The template is populated with a paginated DataTable configured to display SpaceX data.
There is a guide coming soon about how to configure a DataTable with a REST API.
Set up Data provider
In index.js
, start by importing Data
from grommet.
Then, remove the data
property from DataTable and place it as a property on Data. The Data component is now the data provider, controlling which data should be rendered in the DataTable.
import { Box, Data, DataTable, Grommet, Pagination, Text } from "grommet"; ... <Data data={data}> <DataTable columns={columns} /> </Data>
Add default search and filter capabilities
Toolbar
Add toolbar
as a boolean property on Data to display a search input, filter button, and results summary above the DataTable.
<Data data={data} toolbar>
At this point, your project should look like this:

Total
We are only fetching one page of data at a time. Add total={numberItems}
to inform Data of the total number of records.
numberItems
is defined in the starter template using a key from the API response providing the total number of records in the table.
<Data data={data} total={numberItems} toolbar> <DataTable columns={columns} /> </Data>
View and onView
The view
property specifies the subset of data to be displayed, whether that be applied filters, current page, and/or other customizations.
To ensure the table displays the proper results from any applied filters, use view
and onView
.
First, create a state variable called view
.
const [view, setView] = useState();
Next, add view
and onView
as properties on Data. When the filter change, onView
will provide the new values. Use this to update the view
state variable and reset the page to 1.
<Data data={data} view={view} onView={nextView => { setView(nextView); setPage(1); }} total={numberItems} toolbar >
To fetch the data again when the value of view
changes, pass view
as a parameter in fetchData
and include view
as an item in the dependency array of the useEffect.
useEffect(() => { const fetchData = fetchPayloads; fetchData(page, view) .then((d) => setData(d)) .catch((error) => console.log(`Unable to fetch data: ${error}`)); }, [page, view]);
At this point, your project should look like this:

If you type something into the search input and press "Enter", the data in the DataTable will be filtered to those that match the search term.
If you click on the filter button, Data has populated the filters to include all of the data attributes. The input type (Select, CheckBoxGroup, etc.) is determined based on the type of data and amount of results for that attribute.
Customize filtered attributes
To customize which attributes are filterable, use properties
property on Data. In this case, let's only filter by "type" and "mass_lbs".
For the ease of this guide, we've hardcoded the options for "type" and "mass_lbs", but handling this dynamically is recommended for applications in production.
Add the following to Data:
<Data data={data} properties={{ type: { label: 'Type', options: [ 'Dragon 1.0', 'Dragon 1.1', 'Dragon Boilerplate', 'Satellite', ], }, mass_lbs: { label: 'Mass', range: { min: 0, max: 1400 }, }, }} view={view} onView={nextView => { setView(nextView); setPage(1); }} total={numberItems} toolbar > <DataTable columns={columns} /> </Data>
Now, when the filters menu is opened, the filters will look like this:

Congratulations! You’ve used Data to add search and filter controls to manage what data should be rendered in a DataTable.
To reference a completed implementation, check out this CodeSandbox with completed code.
Still have questions?
Something missing or looking for more information? Get in touch to help make the HPE Design System better.