Reputation: 110
I know how to filter rows based on content that is rendered in the table, but how could I filter (using useFilters) a table based on information which isn't shown in the table, but is available in the data-set?
I figure I could let react-table show the tags/meta-data in the table and just hide it with styling, but that seems not too good.
Example data:
{title:"Lesson One", author:"Joe", category:"math"}
Where title
and author
are shown in the table, but category
is only used for filtering.
Upvotes: 2
Views: 2574
Reputation: 446
My solution for this isn't the most elegant, but perhaps you can adapt it to fit your needs. I used the react-table examples to do most of the boilerplate, so the fields do not match with the example fields you gave but hopefully you can adapt it.
https://codesandbox.io/s/vigorous-ardinghelli-z7fc1?file=/src/App.js
In summary:
Any fields that you do not want shown you can hide on table creation by passing the hiddenColumns
property an array of string IDs.
const {
...
} = useTable(
{
columns,
data,
initialState: {
hiddenColumns: ["firstName"] // In your case, "category"
}
},
useFilters
);
I obtained an array of hidden columns from the table instance (line 86)
// Obtain an array of the hidden columns so we can render the filter for them
const hiddenColumns = React.useMemo(() => {
return allColumns.filter(
(column) => column.id === state.hiddenColumns.find(
(columnId) => columnId === column.id))
}, [allColumns, state.hiddenColumns])
Note however that the allColumns
property returns a flat array of columns, meaning that if you have nested columns then it does not track that information, instead you will need to use the columns
property and modify the filtering to match your column nesting (if tracking the nesting is necessary for you). Ref
Once I obtain the hidden columns I can render Filter
for each of them, depending on if canFilter
is true or false, followed by the visible columns. (line 111)
<thead>
{hiddenColumns.map(hiddenColumn => {
return hiddenColumn.canFilter ?
<tr key={hiddenColumn.id} role="row">
<th colSpan={visibleColumns.length} style={{ textAlign: 'left'}}>
{hiddenColumn.render('Filter')}
</th>
</tr> : null
})}
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th {...column.getHeaderProps()}>
{column.render('Header')}
<div>{column.canFilter ? column.render('Filter') : null}</div>
</th>
))}
</tr>
))}
</thead>
You can obviously change the positioning of where the filter for hidden columns is rendered to suite your needs.
Also I will mention that the hook useGlobalFilter searches on hidden columns, so if you were looking for a global filter solution then it should work without any workarounds.
Upvotes: 2