Filtering KendoGrid with virtual scrolling on.

4 Answers 709 Views
Grid
Krzysztof
Top achievements
Rank 1
Iron
Krzysztof asked on 11 May 2021, 02:02 PM | edited on 11 May 2021, 02:47 PM

There seems to be a bug when filtering the grid with virtual scrolling. Everything works fine if I apply the filter before scrolling through the grid.

Now failed scenario:

1. Scroll to the very bottom of the grid.

2. Apply filter.

Result - nothing shows up. Unless you scroll, then the records magically appear. Setting skip to 0 after filtering does nothing, skip = 1 works sometimes.

Fun fact: if  filtered item list does not exceed the maximum number of rows in the actual grid view, there is no way to make them display.

 

Is there a way to bypass this issue? Am I doing something wrong?

https://kendo-grid-checkall-kjuhaw.stackblitz.io

https://stackblitz.com/edit/kendo-grid-checkall-kjuhaw?file=app

4 Answers, 1 is accepted

Sort by
0
Yanmario
Telerik team
answered on 12 May 2021, 08:06 AM

Hi Krysztof,

Thank you for the provided StackBlitz example.

It seems that the Grid is configured to display 10 items per page while using virtual scrolling. It is recommended to set the pageSize at least three(3) times the number of the visible Grid elements. This will avoid any unexpected behavior during scrolling, as demonstrated in the following article of our documentation:

https://www.telerik.com/kendo-angular-ui/components/grid/scroll-modes/virtual/#toc-getting-started

Setting a proper pageSize will fix the issue with filtered items not displaying when they are less than the maximum number of rows.

I also managed to update the provided demo:

https://stackblitz.com/edit/kendo-grid-checkall-3sls9r?file=app%2Fapp.component.ts

Please try the suggestion and let us know in case the issue persists. Thank you. We are looking forward to your reply.

Regards,
Yanmario Menev
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
Krzysztof
Top achievements
Rank 1
Iron
answered on 12 May 2021, 08:25 AM | edited on 12 May 2021, 08:26 AM

Thank you for your response.

 

What you just did, is setting pageSize to a number that is greater than data table length, which seems to be in denial with virtual scrolling concept. It works, because all items will be rendered right away. But, stackblitz code is just mere example of our production code.

For instance, let's assume there is a set of data, that consists a thousand (1k) records. There are 12 visible elements in the grid and pageSize set to 100. It still doesn't work. As if the grid remembered previous scroll position (scrolled to bottom without filter), which stands for skip > number of filtered elements or something.

Is there any way to invoke grid's rendering and rest scrollbar position after applying filters?

0
Svet
Telerik team
answered on 17 May 2021, 05:49 AM

Hi Krzysztof,

Indeed when using virtual scrolling the Grid loads just a portion of the complete data set. The loaded items are equal to the number provided via the pageSize property. We do recommend to load a bit more items than the currently visible once in order to ensure the smooth scrolling of the Grid while fetching the new portion of data.

Please see the following example where I loaded 1k records, show 12 items at once and set the pageSize to 100:

https://stackblitz.com/edit/angular-1zg22x?file=app/app.component.ts

I am unable to reproduce the undesired behavior when filtering. Please check the example and feel free to update it in order to demonstrate the issue. Thank you.

Regards,
Svetlin
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

0
Krzysztof
Top achievements
Rank 1
Iron
answered on 17 May 2021, 07:56 AM

Hello Svetlin.

In the privided example, on every grid state change, you are truncating the data table, which leads to loading "different" set of data. It slows down the performace - that's why in my code sample [kendoGridBinding] has been used instead of [data], because (correct me if I'm wrong) you cannot use [filter] with [data]. Thus, when the grid receives new set of data (filtered out portion of complete set), it resets its rendering and scrolling.

I need filters to be dynamically applied externally (not from within the grid) with [kendoGridBinding] and [filter], so using [filterable] is not an option.

I'd be greatful if you would consider my code sample as a base for resolving this issue. I'm reading Kendo's documentation even in bed at this point.

Krzysztof
Top achievements
Rank 1
Iron
commented on 17 May 2021, 08:02 AM

https://stackblitz.com/edit/angular-1zg22x-nh8hxw?file=app/app.component.ts
1. Click "Apply filters".
2. Click "Remove filters".

Pay attention how long it takes for the grid to switch from displaying 9 elements to full table.
Svet
Telerik team
commented on 20 May 2021, 07:10 AM

Please find a few more comments on  your latest reply:

In the privided example, on every grid state change, you are truncating the data table, which leads to loading "different" set of data.

Indeed, that is the expected behavior when using virtual scrolling or paging. Basically just a portion of the complete data set it loaded at once in the Grid. That helps to better the performance since the browser doesn't have to render all Grid rows at once. Indeed the time needed by the browser to render the complete DOM is the most often reason for some performance issues.

It slows down the performace - that's why in my code sample [kendoGridBinding] has been used instead of [data], because (correct me if I'm wrong) you cannot use [filter] with [data].

In general, virtual scrolling or paging are implemented in order to improve the performance by limiting the number of elements that have to be rendered by the browser at once. The kendoGridBinding directive expects the complete data set to be passed to it at once. The benefit of the kendoGridBinding directive is that it encapsulates the logic for performing all Grid data operations (filtering, sorting, grouping, and paging). But if you load large number of items in the Grid it is expected that some performance issues will occur. If you use the [data] binding then any Grid data operations should be applied manually to the Grid data on (dataStateChange) event. You can use the built-in process() method to apply the current Grid state to any data set.

I need filters to be dynamically applied externally (not from within the grid) with [kendoGridBinding] and [filter], so using [filterable] is not an option.
The Grid [filter] input property is responsible for applying any filter to the Grid state. It should be of type CompositeFilterDescriptor. The data of the Grid has to be filtered according to the applied filter state using the process() method or any other manual approach.


In the provided example the undesired behavior is caused by the aforementioned expected behavior of the browser which needs some time to render all rows. Basically the more rows that have to be rendered the more time will be required by the browser. That is why in such cases virtual scrolling or paging is the most effective performance optimization technique.

You can further simulate an asynchronous operation by utilizing the setTimeout() function and toggle the [loading] property of the Grid in order to show a loading spinner while the data is being rendered:

https://stackblitz.com/edit/angular-1zg22x-bsmk8k?file=app/app.component.ts

I hope the provided information helps. Please submit a private support thread in case any further assistance is required for a specific feature of the Grid. Thank you.

 

 

Krzysztof
Top achievements
Rank 1
Iron
commented on 20 May 2021, 09:37 AM

You went far beyond the scope of the scenario.

Considering this code example:

https://stackblitz.com/edit/angular-1zg22x-yjlqvi?file=app/app.component.ts

would you mind answering questions related to this particular case? Without suggesting things that don't meet my criteria of usage?

1. Compare the performance in this example, to the one you provided. Insert something ridiculous in the input field and erase it (in other words, apply a filter matching none of the values so the grid would be empty, than clear the input, so the grid has to load all the items). It happens almost instantaneously, which is what we are aiming for. Your explanation is more like a "theory crafting session" or "I bet you did not read THE documentation". Can your code example be that performant? If so, how to achieve it?
2. Why does the filter work fine unless the grid is scrolled down before applying the filter?
3. How to fix it. Based on THIS PARTICULAR code sample. Without truncating table nonsence (if it is not posiible - just admit it).
4. Hipotheticaly, if I buy a licence, would you change the approach of evaluating and answering questions?
Svet
Telerik team
commented on 25 May 2021, 05:43 AM

Hi Krzysztof,

Thank you for the provided latest example. I see what you are referring. What could be done is to get a reference to the kendoGridBinding directive and set its skip manually to 0 when filtering:

 @ViewChild('grid', {read: DataBindingDirective}) bindingDirective: 
...
this.bindingDirective.skip = 0;
...

Here is an updated example:

https://stackblitz.com/edit/angular-1zg22x-8synzv?file=app/app.component.ts

Let me add that the usage of the kendoGridBinding directive for the required approach isn't needed. If you need to apply some filters manually or other data operations (together with virtual scrolling) we recommend to bind the Grid via its [data] property and process the data on (dataStateChange).

It looks like there was some confusion in this thread so far. Please let me know in case I am missing something. I am looking forward to your reply.

Regards,
Svetlin
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Krzysztof
Top achievements
Rank 1
Iron
commented on 25 May 2021, 08:08 AM

Works like a charm :) Tkank you. Sorry for my attitude at the end, but I had enough of that subject :)
Tags
Grid
Asked by
Krzysztof
Top achievements
Rank 1
Iron
Answers by
Yanmario
Telerik team
Krzysztof
Top achievements
Rank 1
Iron
Svet
Telerik team
Share this question
or