Skip to content

Commit d999d98

Browse files
authored
kb(Selects): Add KB for virtual scrolling skeletons (#3261)
1 parent 6a8f2da commit d999d98

File tree

2 files changed

+163
-1
lines changed

2 files changed

+163
-1
lines changed

_contentTemplates/common/dropdowns-virtualization.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ the component will call this method to request the model that matches the `Value
3333

3434
#limitations
3535
* When the initially selected item is not on the first page, the dropdown does not scroll to it on first opening.
36-
* The component calculates the position of the dropdown items during virtual scrolling. In this case, the loading indicators (skeletons) do not display as they will affect the proper item positioning.
36+
* The component calculates the position of the dropdown items during virtual scrolling. In this case, the loading indicators (skeletons) do not display as they will affect the proper item positioning. You can [add loading skeletons to the virtual dropdown with CSS](slug:dropdowns-kb-show-loading-indicator-skeletons-during-virtual-scrolling).
3737
#end
3838

3939
#remote-data-sample-intro
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
---
2+
title: Display Loading Indicators during Virtual Scrolling
3+
description: Learn how to display loading skeleton indicators during virtual scrolling in a Telerik Blazor AutoComplete, ComboBox, DropDownList, MultiColumnComboBox, and MultiSelect componenta.
4+
type: how-to
5+
page_title: How to Display Loading Indicators during Virtual Scrolling
6+
slug: dropdowns-kb-show-loading-indicator-skeletons-during-virtual-scrolling
7+
tags: telerik, blazor, virtualization, autocomplete, combobox, dropdownlist, multicolumncombobox, multiselect
8+
ticketid: 1587267, 1699463
9+
res_type: kb
10+
---
11+
12+
## Environment
13+
14+
<table>
15+
<tbody>
16+
<tr>
17+
<td>Product</td>
18+
<td>
19+
AutoComplete for Blazor, <br />
20+
ComboBox for Blazor, <br />
21+
DropDownList for Blazor, <br />
22+
MultiColumnComboBox for Blazor, <br />
23+
MultiSelect for Blazor
24+
</td>
25+
</tr>
26+
</tbody>
27+
</table>
28+
29+
## Description
30+
31+
This KB article answers the following questions:
32+
33+
* How to show loading indicators in the Telerik select components during virtual scrolling?
34+
* How to display loading skeletons while the user scrolls a Telerik dropdown component with virtual scroll mode?
35+
* How to improve the Telerik dropdown virtualization styling and add gray bars during scrolling?
36+
37+
## Solution
38+
39+
To show loading indicators (skeletons) during virtual scrolling of Telerik dropdown components:
40+
41+
1. Add an image to your app, which looks like one or more lines of skeletons.
42+
1. Set the image as a repeating background to the `.k-list-container .k-virtual-scroller-size` CSS combinator.
43+
1. Apply a background color to `.k-list-container .k-list-ul`, so that users do not see the background image behind the rendered dropdown items.
44+
45+
>caption Display skeleton loading indicators during virtual scrolling of Telerik dropdown components
46+
47+
````RAZOR
48+
@using Telerik.DataSource
49+
@using Telerik.DataSource.Extensions
50+
51+
<TelerikDropDownList @bind-Value="@SelectedValue"
52+
OnRead="@OnSelectRead"
53+
TItem="@ListItem"
54+
TValue="@int"
55+
TextField="@nameof(ListItem.Text)"
56+
ValueField="@nameof(ListItem.Id)"
57+
ScrollMode="@DropDownScrollMode.Virtual"
58+
ValueMapper="@GetItemFromValue"
59+
ItemHeight="30"
60+
PageSize="20"
61+
Filterable="true"
62+
FilterOperator="@StringFilterOperator.Contains"
63+
Width="240px" />
64+
65+
<TelerikComboBox @bind-Value="@SelectedValue"
66+
OnRead="@OnSelectRead"
67+
TItem="@ListItem"
68+
TValue="@int"
69+
TextField="@nameof(ListItem.Text)"
70+
ValueField="@nameof(ListItem.Id)"
71+
ScrollMode="@DropDownScrollMode.Virtual"
72+
ValueMapper="@GetItemFromValue"
73+
ItemHeight="30"
74+
PageSize="20"
75+
Filterable="true"
76+
FilterOperator="@StringFilterOperator.Contains"
77+
Width="240px" />
78+
79+
<style>
80+
/* Apply background color to regular items, so that the skeletons are not visible behind them */
81+
.k-list-container .k-list-ul {
82+
background: var(--kendo-color-surface);
83+
}
84+
85+
/* Show skeletons during virtual scrolling */
86+
.k-list-container .k-virtual-scroller-size {
87+
background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTgwIiBoZWlnaHQ9Ijk2IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogPGcgaWQ9IkxheWVyXzEiPgogIDx0aXRsZT5Ta2VsZXRvbnM8L3RpdGxlPgogIDxyZWN0IGlkPSJzdmdfMSIgaGVpZ2h0PSIxNCIgd2lkdGg9IjE4MCIgeT0iMCIgeD0iMCIgZmlsbD0iI2Q5ZDlkOSIvPgogIDxyZWN0IGlkPSJzdmdfMiIgaGVpZ2h0PSIxNCIgd2lkdGg9IjkwIiB5PSIyNCIgeD0iMCIgZmlsbD0iI2Q5ZDlkOSIvPgogIDxyZWN0IGlkPSJzdmdfMyIgaGVpZ2h0PSIxNCIgd2lkdGg9IjE1MCIgeT0iNDgiIHg9IjAiIGZpbGw9IiNkOWQ5ZDkiLz4KICA8cmVjdCBpZD0ic3ZnXzQiIGhlaWdodD0iMTQiIHdpZHRoPSIxMjAiIHk9IjcyIiB4PSIwIiBmaWxsPSIjZDlkOWQ5Ii8+CiA8L2c+Cjwvc3ZnPg==");
88+
background-repeat: repeat-y;
89+
background-position: 8px 0;
90+
}
91+
</style>
92+
93+
@code {
94+
private List<ListItem> ListItems { get; set; } = new();
95+
96+
private int SelectedValue { get; set; } = 3;
97+
98+
// Use the correct event argument type in your app.
99+
// ReadEventArgs is a base type.
100+
private async Task OnSelectRead(ReadEventArgs args)
101+
{
102+
DataSourceResult result = await ListItems.ToDataSourceResultAsync(args.Request);
103+
104+
args.Data = result.Data;
105+
args.Total = result.Total;
106+
}
107+
108+
private async Task<ListItem?> GetItemFromValue(int id)
109+
{
110+
// Simulate async operation.
111+
await Task.Delay(100);
112+
return ListItems.FirstOrDefault(x => x.Id == id);
113+
}
114+
115+
protected override void OnInitialized()
116+
{
117+
var rnd = Random.Shared;
118+
119+
ListItems = Enumerable.Range(1, 1000).Select(x =>
120+
{
121+
return new ListItem()
122+
{
123+
Id = x,
124+
Text = $"Item {x} {(char)rnd.Next(65, 91)}{(char)rnd.Next(65, 91)}"
125+
};
126+
127+
}).ToList();
128+
129+
base.OnInitialized();
130+
}
131+
132+
public class ListItem
133+
{
134+
public int Id { get; set; }
135+
public string Text { get; set; } = string.Empty;
136+
}
137+
}
138+
````
139+
140+
## Notes
141+
142+
The Base64-encoded SVG image above was created from the following markup. You can modify it, according to your preferences, instead of starting from scratch.
143+
144+
````HTML
145+
<svg width="180" height="96" xmlns="http://www.w3.org/2000/svg">
146+
<g id="Layer_1">
147+
<title>Skeletons</title>
148+
<rect id="svg_1" height="14" width="180" y="0" x="0" fill="#d9d9d9" />
149+
<rect id="svg_2" height="14" width="90" y="24" x="0" fill="#d9d9d9" />
150+
<rect id="svg_3" height="14" width="150" y="48" x="0" fill="#d9d9d9" />
151+
<rect id="svg_4" height="14" width="120" y="72" x="0" fill="#d9d9d9" />
152+
</g>
153+
</svg>
154+
````
155+
156+
## See Also
157+
158+
* [AutoComplete Virtualization](slug:autocomplete-virtualization)
159+
* [ComboBox Virtualization](slug:combobox-virtualization)
160+
* [DropDownList Virtualization](slug:dropdownlist-virtualization)
161+
* [MultiColumnComboBox Virtualization](slug:multicolumncombobox-virtualization)
162+
* [MultiSelect Virtualization](slug:multiselect-virtualization)

0 commit comments

Comments
 (0)