Skip to content

Commit e242035

Browse files
kb(comboBox): debounce OnRead
1 parent 55b2e49 commit e242035

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed

components/combobox/events.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@ You can also call remote data through async operations.
212212

213213
>caption Custom Data according to the user input in the ComboBox
214214
215+
>tip You can also [debounce the service calls and implement minimum filter length]({%slug combo-kb-debounce-onread%}).
216+
215217
````CSHTML
216218
@SelectedValue
217219
<br />
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
---
2+
title: Debounce custom filter calls, implement min filter length
3+
description: how to debounce the custom server filter service calls and to implement min filter length
4+
type: how-to
5+
page_title: Debounce OnRead calls, Min Filter Length
6+
slug: combo-kb-debounce-onread
7+
position:
8+
tags:
9+
ticketid: 1460897
10+
res_type: kb
11+
---
12+
13+
## Environment
14+
<table>
15+
<tbody>
16+
<tr>
17+
<td>Product</td>
18+
<td>ComboBox for Blazor</td>
19+
</tr>
20+
</tbody>
21+
</table>
22+
23+
24+
## Description
25+
26+
I want to specify a debounce time for filtering. This way I can (for example) set the debounce time to 500(ms), and then only have the combo box service filter when the user stops typing.
27+
28+
This can be useful for filtering with remote data - it invokes a filter on every keystroke and network/service delays can cause wrong data display or confusion, in addition to increased service load.
29+
30+
I also want to implement a minimum filter length, if the input is below that length, the servive won't be called.
31+
32+
## Solution
33+
34+
Implement logic in the [OnRead event]({%slug components/combobox/events%}#onread) that will debounce the calls to the service with the desired timeout. For example, use a `CancellationTokenSource`.
35+
36+
For min filter length, just add a check in the handler for the desired string length (in this example - 2 symbols).
37+
38+
>caption Use a `CancellationTokenSource` to debounce OnRead filter calls in the combo box. Add Min Filter Length
39+
40+
````CSHTML
41+
@using System.Threading
42+
43+
@SelectedValue
44+
<br />
45+
<TelerikComboBox Data="@Options"
46+
OnRead="@ReadItems"
47+
Filterable="true"
48+
Placeholder="Find what you seek by typing"
49+
@bind-Value="@SelectedValue">
50+
</TelerikComboBox>
51+
52+
@code{
53+
public string SelectedValue { get; set; }
54+
List<string> Options { get; set; } = new List<string>();
55+
CancellationTokenSource tokenSource = new CancellationTokenSource(); // for debouncing the service calls
56+
57+
async Task RequestData(string userInput, string method)
58+
{
59+
// this method calls the actual service (in this case - a local method)
60+
Options = await GetOptions(userInput, method);
61+
}
62+
63+
async Task ReadItems(ComboBoxReadEventArgs args)
64+
{
65+
if (args.Request.Filters.Count > 0) // there is user filter input, skips providing data on initialization
66+
{
67+
Telerik.DataSource.FilterDescriptor filter = args.Request.Filters[0] as Telerik.DataSource.FilterDescriptor;
68+
string userInput = filter.Value.ToString();
69+
string method = filter.Operator.ToString();
70+
71+
if (userInput.Length > 1) // sample min filter length implementation
72+
{
73+
// debouncing
74+
tokenSource.Cancel();
75+
tokenSource.Dispose();
76+
77+
tokenSource = new CancellationTokenSource();
78+
var token = tokenSource.Token;
79+
80+
await Task.Delay(300, token); // 300ms timeout for the debouncing
81+
82+
//new service request after debouncing
83+
await RequestData(userInput, method);
84+
}
85+
}
86+
else
87+
{
88+
if (Options?.Count < 1)
89+
{
90+
// when there is no user input you may still want to provide data
91+
// in this example we just hardcode a few items, you can either fetch all the data
92+
// or you can provide some subset of most common items, or something based on the business logic
93+
Options = new List<string>() { "one", "two", "three" };
94+
}
95+
}
96+
}
97+
98+
async Task<List<string>> GetOptions(string userInput, string filterOperator)
99+
{
100+
Console.WriteLine("service called - debounced so there are fewer calls");
101+
await Task.Delay(500); // simulate network delay, remove it for a real app
102+
103+
//sample logic for getting suggestions - here they are generated, you can call a remote service
104+
//for brevity, this example does not use the filter operator, but your actual service can
105+
List<string> optionsData = new List<string>();
106+
for (int i = 0; i < 5; i++)
107+
{
108+
optionsData.Add($"option {i} for input {userInput}");
109+
}
110+
111+
return optionsData;
112+
}
113+
````
114+

0 commit comments

Comments
 (0)