syncfusion/ej2-grids

Feature-request: Add possibility to get filtered rows

Opened this issue · 11 comments

The following link brings to the click handler on the "select all" checbox in the grid.
It would be nice if like some other grid libraries we could set an option that specifies if clicking this "select all" checkbox would select all rows in the grid (even the rows that are not being displayed due to paging, which is the current implementation), or only select all visible rows. (I found out that's already doable by setting persistSelection to false on the selectionSettings object, but I'll leave it here for info)

What could be even nicer was if there was a way to select only filtered rows (by API mostly such as Grid.GetFilteredRows() or something like that would be awesome!)

See the selection click handler which defines which items to get as part of the "select all" checkbox selection.

Ok so after further investigation, it seems like it would be possible to get the filtered/search results only by calling the grid.selectionModule.checkSelectAll() and then calling the grid.getSelectedRecords() but that would cause a problem in case a user has set persistSelection to false but still wants all filtered or searched results even if they span multiple pages...

Would you have an idea of how that would be possible? That is, combine both behaviors:

  1. Having the persistSelection set to false so that only visible items are selected when using the checkSelectAll() function or the "select all" button
  2. Still be able to fetch the results of a search or filter operation no matter how much pages they fit on.

I tried searching for a variable that would hold the current dataset used to generate the grid but all I can find is the whole dataset (from grid.dataSource.dataSource.json), on which all queries are applied sequentially whenever a new action (filter, search, etc... is required). So that leaves no option to only get the current "sub dataset".

I don't know if it could be done but it would be really nice if the data could be saved in an intermediate variable after passing the queries (except for the paging) so that we could have a representation of the "current dataset" to play with (compared to the actual version from which we can get the whole dataset or the final page results from grid.currentViewData.

Also, that investigation lead me to a question, are all queries always reprocessed whenever a new page is requested? As that's what it looks like when looking for example at the JsonAdaptor.prototype.processQuery . I wonder if there would be a more efficient way to process data (for example having the said subset of data in memory to work directly with, so that paging would be blazingly fast compared to the actual implementation)

Thanks in advance!

Trying to find more info in the forums, I found that this was indeed possible in previous versions (see here where it is recommended to use the getFilteredRecords() method of the grid API and that's exactly what I'm missing in the current implementation, thanks in advance!

Hi
We can get filtered records by the following way

`

function btnClick() {
var gridFilteredRecords;
var gridObj = document.getElementById('Grid')['ej2_instances'][0];
var query = gridObj.getDataModule().generateQuery(gridObj.filterSettings.columns[0].properties);
gridObj.allowPaging = false;
gridObj.getDataModule().getData({}, query).then(function(e){ gridFilteredRecords = e.result })
gridObj.allowPaging = true;
}

`

Hey there, thanks for the suggestion. I guess that's effectively a way to retrieve the filtered results. I wonder though if it's really effective to reprocess the whole dataset for a single operation like that when we could simply keep a copy of the filtered dataset at all times.

What would you think about adding a new variable and an api endpoint that would keep updated the filtered/searched dataset? The way I did it in my tests was that I updated this collection only on search and filter queries within the processQuery function of the json adaptor IIRC

In case someone would stumble upon this issue and wondered if there was a solution proposed, here it is:

<script> 
    var newData = []; 
    var gridData; 
    function load() { 
        gridData = document.getElementById("Grid").ej2_instances[0].dataSource;   //grid initial dataSource 
    }  
    function action(args) {
        if (args.requestType == "searching" || args.requestType == "filtering") {
            if (!args.searchString && !args.currentFilteringColumn) {
                this.dataSource = gridData;
            }
            else {
                for (var i = 0; i < args.rows.length; i++) {
                    newData.push(args.rows[i].data);
                }
                this.dataSource = newData;
                newData = [];
            }
        }
    }
</script> 

That is, create a global variable which will hold the initial grid data in memory (populated when grid triggers the load event). Then whenever an operation has completed (triggering the complete event), we update the grid's datasource with the filtered/searched data if it's a search or filter query that has been processed. Otherwise, we update the grid's datasource back to the original data.

This will improve performance for operations such as paging in the grid when a search or filter has been applied as in the current implementation, all the queries (filters and search included) are reprocessed on the full dataset on each request (even for paging only) while with this solution, only the subset of data will be processed.

Another point of optimization would be to skip the search/filter query completely if the searchString, currentFilteringColumn and the filter string (if any) have not changed. But this will be for another issue/feature-request I guess.

@os1r1s110 Thanks for the update. Also we have logged a feature request on this and it can be tracked through our feedback portal below.

Link : https://www.syncfusion.com/feedback/3888/support-for-query-processing-from-current-filtered-dataset

Please cast your vote to make it count. We will prioritize the features every release based on the demands.

If you have any more specification/suggestions to the feature request you can add it as a comment in the portal.

Is there any update regarding this? I saw it was supposed to be included in 2019 Volume 2 (I understand it's an attempt and not a guarantee) but there's no news since a couple months, has it been included/implemented?

Could this issue be transferred to the new "merged" repository please? Or be updated according to what has been done to improve performance regarding paging and similar operations being performed on the full dataset instead of only the visible dataset.

Ok so for others that could stumble here, I found something was implemented in the grid.ts file.

It lets the user retrieve the filtered dataset, but to do so, reprocesses the query against the full dataset (again). So while it's available, it's not efficient at all and could still be improved a lot I think (there may be a reason why it's left like that and if so, then it's fine :) )

Hi

We can understand your query but in the Grid the operations like, filter, sort, etc. are performed using the Data Manager control which is a separate plug-in. The Data Manager processes the data based on the query(filter, sort, etc.) and returns back the result to the Grid in this case. So it is not possible to maintain the filtered records in the Grid itself. Because consider the case of a nested filter column that needs to be sorted. For this as you have mentioned the filter will be performed, then on sorting this filtered record will be sorted. Now either the same column or any other column can be sorted and when it is any other column then the sort structure will be changed completely and so the previous data cannot be used here. Also when there are large data sets, maintaining a separate filter data set will also cause performance problems and furthermore the entire structure would need to be changed for this which might modify the existing behavior thus causing a break for other users.

So for this we suggest you to use the sample-level workaround that we have provided earlier