Skip to content

Add new kb article combobox-virtualization-loader #3123

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 155 additions & 0 deletions knowledge-base/combobox-virtualization-loader.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
---
title: Display Loading Indicator in ComboBox with Remote Data and Virtualization
description: Learn how to add a loading indicator in the TelerikComboBox component when using remote data and virtualization functionality in UI for Blazor.
type: how-to
page_title: Adding Loader to ComboBox During Remote Data Fetch and Virtualization
slug: combobox-kb-virtualization-loader
position:
tags: blazor, combobox, loader, templates, nodatatemplate, headertemplate
res_type: kb
ticketid: 1693304
---

## Environment

<table>
<tbody>
<tr>
<td>Product</td>
<td>ComboBox for Blazor</td>
</tr>
</tbody>
</table>

## Description

When using the [ComboBox](https://www.telerik.com/blazor-ui/documentation/components/combobox/overview) component in UI for Blazor with remote data loading and virtualization, the dropdown briefly displays the "No data" message while waiting for the response. This behavior can confuse users who may assume there is no data available when it is still loading. Additionally, during virtual scrolling or filtering, the absence of a loading indicator can lead to user frustration as they cannot perceive ongoing data fetch operations.

## Solution

1. Display a Loading Indicator During Remote Data Fetch
Use the `HeaderTemplate` property of the ComboBox component to show a loading indicator. Add a boolean flag to track the loading state and update it dynamically during data fetch operations. Use a CSS rule to disable the default "No Data" message.

2. Clear Old Items During Filtering/Search
Modify the visibility of old items using CSS rules and conditionally toggle their appearance based on the loading state.

>caption Display a Loading Indicator When Using a Virtualized ComboBox

```razor
@using Telerik.DataSource
@using Telerik.DataSource.Extensions

<p>@SelectedValue</p>

@if (IsLoading == true) {
<style>
.example-cb .k-list-item {
visibility: hidden;
pointer-events: none;
}

.example-cb .k-nodata {
display: none;
}
</style>
}
<TelerikComboBox @ref="ComboBoxRef" TItem="@Person" TValue="@int"
ScrollMode="@DropDownScrollMode.Virtual"
OnRead="@GetRemoteData"
ValueMapper="@GetModelFromValue"
ItemHeight="30"
PageSize="20"
TextField="@nameof(Person.Name)"
ValueField="@nameof(Person.Id)"
@bind-Value="@SelectedValue"
Filterable="true" FilterOperator="@StringFilterOperator.Contains">
<ComboBoxSettings>
<ComboBoxPopupSettings Class="example-cb" Height="200px" />
</ComboBoxSettings>
<NoDataTemplate>
</NoDataTemplate>
<HeaderTemplate>
<TelerikLoader Visible="@IsLoading" />
</HeaderTemplate>
</TelerikComboBox>

@code{
bool IsLoading {get;set;} = false;
int SelectedValue { get; set; } = 1234; // pre-select an item to showcase the value mapper
private TelerikComboBox<Person, int>? ComboBoxRef { get; set; }
async Task GetRemoteData(ComboBoxReadEventArgs args)
{
IsLoading = true;
ComboBoxRef?.Refresh();
DataEnvelope<Person> result = await MyService.GetItems(args.Request);

// set the Data and the TotalItems to the current page of data and total number of items
args.Data = result.Data;
args.Total = result.Total;
IsLoading = false;
ComboBoxRef?.Refresh();
}

async Task<Person> GetModelFromValue(int selectedValue)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoids a compiler warning

Suggested change
async Task<Person> GetModelFromValue(int selectedValue)
async Task<Person?> GetModelFromValue(int selectedValue)

{
// return a model that matches the selected value so the component can get its text
return await MyService.GetItemFromValue(selectedValue);
}

// mimics a real service in terms of API appearance, refactor as necessary for your app
public static class MyService
{
static List<Person> AllData { get; set; }

public static async Task<DataEnvelope<Person>> GetItems(DataSourceRequest request)
{
await Task.Delay(500);
if (AllData == null)
{
AllData = Enumerable.Range(1, 12345).Select(x => new Person { Id = x, Name = $"Name {x}" }).ToList();
}

await Task.Delay(400); // simulate real network and database delays. Remove in a real app

var result = await AllData.ToDataSourceResultAsync(request);
DataEnvelope<Person> dataToReturn = new DataEnvelope<Person>
{
Data = result.Data.Cast<Person>().ToList(),
Total = result.Total
};

return dataToReturn;
}

public static async Task<Person?> GetItemFromValue(int selectedValue)
{
await Task.Delay(400); // simulate real network and database delays. Remove in a real app

return AllData.FirstOrDefault(x => selectedValue == x.Id);
}
}

// used to showcase how you could simplify the return of more than one value from the service
public class DataEnvelope<T>
{
public int Total { get; set; }
public List<T> Data { get; set; }
}

Comment on lines +132 to +138
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part adds an unnecessary and irrelevant complication. Use a simpler example without it.
https://www.telerik.com/blazor-ui/documentation/components/multicolumncombobox/virtualization#remote-data-example

public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
}
```

### Key Points
- Use the `HeaderTemplate` for displaying a loading indicator during scrolling or filtering.
- Call the `Refresh` method on the ComboBox reference to update the UI dynamically during data load operations.
- Toggle visibility of old items using CSS to enhance user experience.
Comment on lines +147 to +150
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should be merged with the solution above.


## See Also
- [ComboBox HeaderTemplate Documentation](https://www.telerik.com/blazor-ui/documentation/components/combobox/templates#header-template)
- [ComboBox Reference and Methods](https://www.telerik.com/blazor-ui/documentation/components/combobox/overview#combobox-reference-and-methods)
- [ComboBox Virtualization Documentation](https://www.telerik.com/blazor-ui/documentation/components/combobox/virtualization#remote-data-example)