T
TanStackβ€’3y ago
optimistic-gold

Dynamically update column header based on filtered data

I would like to know if it's possible to dynamically update a column header based on the current filtering applied to the table data. Here's an example to illustrate my use case: Let's say I have a column header called "Items" and there are 10 rows in the table, each containing the data "1" in each row for that column. If I apply a filter to the table so that it displays only 3 rows with 1 item each, I would like the header for that column to be updated to "Items (3)" to reflect the current number of displayed items. Is there any built-in functionality to achieve this or could you suggest a possible approach to implement this feature? Thank you for your help and for creating this great library!
9 Replies
xenophobic-harlequin
xenophobic-harlequinβ€’3y ago
You can achieve this by using the header.column.getFacetedRowModel() .flatRows.length A possible approach is to set the header conditionally, using the getIsFiltered. If getIsFiltered === true, concat the header.column.getFacetedRowModel() .flatRows.length to the header, otherwise show only the header name
optimistic-gold
optimistic-goldOPβ€’3y ago
wow ok thnx will try it out and see if I can make it work appreciate the response! hey, so I might have been unclear in my initial question. It seems that you are calculating the total number of rows that are filtered. I'm looking for the data that has been filtered so I found that I can get it by accessing the tableInstanceRef
const filteredData = tableInstanceRef.current.getFilteredRowModel();
const totalItems = filteredData.flatRows.reduce((acc, curr) => {
return acc + parseInt(curr.original.number_of_items);
}, 0);
const filteredData = tableInstanceRef.current.getFilteredRowModel();
const totalItems = filteredData.flatRows.reduce((acc, curr) => {
return acc + parseInt(curr.original.number_of_items);
}, 0);
however it seems like the getFilteredRowModel() only runs once initially and I'm not sure how to get the updated filteredData after I use the GlobalFilter to search for something.
xenophobic-harlequin
xenophobic-harlequinβ€’3y ago
You can create a function to do this and then call it inside the table, so every time a change is made the table rerenders and fires the function for you. I use this to get the sum of all values from a column to use that in another component. Everytime i apply a filter, the table runs the function again and it shows me only the filtered rows , then i calculate the sum of the filtered values. I dont know if its this that you want
optimistic-gold
optimistic-goldOPβ€’3y ago
exactly what I want yes I want to show the calculated sum of the filtered values for a specific column in it's header what event handler are you using to call your function every time you apply the filter? I am actually using material-react-table which has it's builtin filter - so I don't use a custom filter. but that is a good idea, I suppose I could just create a custom filter and do what I want there.
xenophobic-harlequin
xenophobic-harlequinβ€’3y ago
I just run my function inside the <tbody>
xenophobic-harlequin
xenophobic-harlequinβ€’3y ago
No description
xenophobic-harlequin
xenophobic-harlequinβ€’3y ago
whenever i apply a filter, the body renders again, firing my function with the built in filter, for every keystroke it sets the filter value (setFilterValue) so when the filter is applied, it renders the table again you can make a function that takes the table as argument, inside the function you map the flatRows of the getFilteredRowModel() getFilteredRowModel().flatRows.map(row => { row.original.YOUR-FIELD-HERE }) then you can set a state with the sum and use it in your header, like `Item (${myState}) or something like that
optimistic-gold
optimistic-goldOPβ€’3y ago
ah got it, so inside the table body makes sense. will try it out πŸ™πŸΌπŸ˜„ thank you

Did you find this page helpful?