Hey - just curious, is there a search function built in? If I have 5,000 rows, and I want to find all rows that contain the keyword "quack", is there a fast filter?
Thanks!
Hey @vgoklani,
No search functionality is built into react-virtualized but I have a few other libraries that do what you're looking for and can be used alongside react-virtualized.
I'm going to close this issue so it doesn't clutter up the issues list but I'll keep monitoring it in case you have questions. :)
great - thank you so much! This looks particularly nice: https://github.com/bvaughn/js-worker-search
Thank you :D Happy to hear. Hope it works for you!
has this changed at all? Is there any search utility in React-Virtualized?
No. This isn't a search library.
Look at my response above though. I linked several such libraries.
Don't want to reopen this issue, but just wanted to point out that if RV supported "search" through some hooks like it does for sorting, it would make this a lot easier. Just adding an external search library is a lot harder than it sounds...
When you think through what the majority of users would expect from a search box, they expect it to work like pressing ctrl-f in a browser; it searches the _rendered_ text. In a table component, this means that the filtering should be done on the text returned from the cellRenderer functions for each column. For example my raw dataset might contain unix timestamps as a number (seconds since epoc) but the cellRenderer formats it to "December 12th" (actually a properly i18n localized date). As an end user I should be able to search for "december".
So as a programmer to implement this correctly, you actually need to loop over all your data records and all your columns, get the cell renderer for each column, render the element, and extract the text.
This in itself isn't that bad I suppose, but a large part of RV is that it can handle very large data sets by _not_ rendering them all. Now we are back to having to render them all... If RV had a hook for this, then RV could take care of only looping through records until it finds enough to fill the visible rendered rows. So if it's currently rendering 50 rows, it would only need to find the first 50 filtering results.
This would help a lot in keeping performance acceptable and making the end user experience as expected.
Just to clarify, I'm not saying RV should _perform_ any filtering/searching, just saying it would be nice to have something like a callback function on the Column (like search) where someone could specify whether or not this row should be included or filtered out.
If you look at the code for the venerable old datatables.net, it has a render( data, type, row, meta ) function and one of the parameters is type, and that type will be one of ['filter', 'display', 'type', 'sort'] so when it needs to get the text value for rendering in the table, it calls render(..., 'display', ...) and when it needs to get the value to filter on it calls render(..., 'filter', ...). This is convenient, but I don't really like the overloading of the same function...
RV could do something simpler and just have a cellFilterer prop on Column that defaults to () => true but if specified, call it and if it returns a truthy value, add the row to to the result set.
Thinking through this more, another detriment to the proposed external search library is that now if I have 1000 records in an array, I have to filter them myself, perhaps into another 950 record array, to hand off to RV. There is no way to filter the data in place without duplicating the data.
Most helpful comment
Don't want to reopen this issue, but just wanted to point out that if RV supported "search" through some hooks like it does for sorting, it would make this a lot easier. Just adding an external search library is a lot harder than it sounds...
When you think through what the majority of users would expect from a search box, they expect it to work like pressing
ctrl-fin a browser; it searches the _rendered_ text. In a table component, this means that the filtering should be done on the text returned from thecellRendererfunctions for each column. For example my raw dataset might contain unix timestamps as a number (seconds since epoc) but the cellRenderer formats it to "December 12th" (actually a properly i18n localized date). As an end user I should be able to search for "december".So as a programmer to implement this correctly, you actually need to loop over all your data records and all your columns, get the cell renderer for each column, render the element, and extract the text.
This in itself isn't that bad I suppose, but a large part of RV is that it can handle very large data sets by _not_ rendering them all. Now we are back to having to render them all... If RV had a hook for this, then RV could take care of only looping through records until it finds enough to fill the visible rendered rows. So if it's currently rendering 50 rows, it would only need to find the first 50 filtering results.
This would help a lot in keeping performance acceptable and making the end user experience as expected.
Just to clarify, I'm not saying RV should _perform_ any filtering/searching, just saying it would be nice to have something like a callback function on the Column (like
search) where someone could specify whether or not this row should be included or filtered out.If you look at the code for the venerable old datatables.net, it has a render( data, type, row, meta ) function and one of the parameters is
type, and that type will be one of['filter', 'display', 'type', 'sort']so when it needs to get the text value for rendering in the table, it callsrender(..., 'display', ...)and when it needs to get the value to filter on it callsrender(..., 'filter', ...). This is convenient, but I don't really like the overloading of the same function...RV could do something simpler and just have a
cellFiltererprop onColumnthat defaults to() => truebut if specified, call it and if it returns a truthy value, add the row to to the result set.Thinking through this more, another detriment to the proposed external search library is that now if I have 1000 records in an array, I have to filter them myself, perhaps into another 950 record array, to hand off to RV. There is no way to filter the data in place without duplicating the data.