Skip to content

Commit 16a788e

Browse files
Merge combobox-kb-autoselect-3032 into production (#3045)
* docs(kb): add kb for automatically select * chore: modify solution section --------- Co-authored-by: Tsvetomir Hristov <[email protected]>
1 parent 998b2f5 commit 16a788e

File tree

1 file changed

+185
-0
lines changed

1 file changed

+185
-0
lines changed
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
---
2+
title: How to Automatically Select Preselected Item on Blur
3+
description: Learn how to configure the Telerik ComboBox for Blazor to automatically select the first matching item when the input loses focus.
4+
type: how-to
5+
page_title: How to Automatically Select Preselected Item on Blur
6+
slug: combobox-kb-autoselect-on-blur
7+
tags: telerik, blazor, combobox, blur, auto-select
8+
res_type: kb
9+
---
10+
11+
## Environment
12+
13+
<table>
14+
<tbody>
15+
<tr>
16+
<td>Product</td>
17+
<td>ComboBox for Blazor</td>
18+
</tr>
19+
</tbody>
20+
</table>
21+
22+
## Description
23+
24+
The article asnwers to the following question:
25+
26+
* How to configure the ComboBox to automatically select the first matching item when the input loses focus (e.g., when the user tabs away or clicks outside)?
27+
* How to auto-select a ComboBox item based on user input when focus is lost?
28+
* Can the ComboBox select a suggested item on blur without pressing Enter?
29+
* How to set the ComboBox value when the user leaves the input field?
30+
31+
## Solution
32+
To automatically select the first matching item in the ComboBox when the input loses focus, use a combination of the ComboBox [`OnRead` event](slug:components/combobox/events#onread) and JavaScript interop. The provided example demonstrates how to:
33+
34+
1. Use the `OnRead` event to filter data and store the first matching item.
35+
2. Attach a JavaScript event handler to detect when the user blurs the ComboBox input.
36+
3. Invoke a .NET method from JavaScript to set the ComboBox value to the first matching item when focus is lost.
37+
4. Update the ComboBox selection programmatically and refresh the UI.
38+
39+
>caption Auto-select the first matching item on blur
40+
41+
````RAZOR
42+
@using Telerik.DataSource.Extensions
43+
44+
@implements IDisposable
45+
46+
@inject IJSRuntime js
47+
48+
<p>ComboBoxFirstItem: @ComboBoxFirstItem?.Text</p>
49+
50+
<p>Selected value: @ComboBoxValue</p>
51+
52+
<TelerikComboBox OnRead="@OnComboBoxRead"
53+
TItem="@ListItem"
54+
TValue="@int"
55+
Value="@ComboBoxValue"
56+
ValueChanged="@( (int newValue) => ComboBoxValueChanged(newValue) )"
57+
TextField="@nameof(ListItem.Text)"
58+
ValueField="@nameof(ListItem.Id)"
59+
Filterable="true"
60+
FilterOperator="@StringFilterOperator.Contains"
61+
Placeholder="Select an item..."
62+
ShowClearButton="true"
63+
Width="200px"
64+
Id="combo-1">
65+
<ComboBoxSettings>
66+
<ComboBoxPopupSettings Class="select-on-tab" />
67+
</ComboBoxSettings>
68+
</TelerikComboBox>
69+
<br/>
70+
<br/>
71+
<TelerikTextBox Placeholder="Next form item" Width="200px"/>
72+
73+
@* Move JavaScript to a separate JS file *@
74+
<script suppress-error="BL9992">
75+
function attachComboKeyDown(selector) {
76+
var comboInput = document.querySelector(selector);
77+
if (comboInput) {
78+
comboInput.addEventListener("keydown", onComboInputKeyDown);
79+
}
80+
}
81+
82+
function detachComboKeyDown(selector) {
83+
var comboInput = document.querySelector(selector);
84+
if (comboInput) {
85+
comboInput.removeEventListener("keydown", onComboInputKeyDown);
86+
}
87+
}
88+
89+
function onComboInputKeyDown(e) {
90+
if (e.key == "Tab") {
91+
dotNet.invokeMethodAsync("OnComboBoxTab", e.target.value);
92+
}
93+
}
94+
95+
var dotNet;
96+
97+
function saveDotNetRef(dotNetRef) {
98+
dotNet = dotNetRef;
99+
}
100+
</script>
101+
102+
@code {
103+
private DotNetObjectReference<__Main>? DotNetRef { get; set; }
104+
105+
private List<ListItem> ComboBoxData { get; set; } = new();
106+
private int ComboBoxValue { get; set; }
107+
private ListItem? ComboBoxFirstItem { get; set; }
108+
109+
[JSInvokable("OnComboBoxTab")]
110+
public void OnComboBoxTab(string newStringValue)
111+
{
112+
if (ComboBoxFirstItem is not null && ComboBoxFirstItem.Text.Contains(newStringValue))
113+
{
114+
ComboBoxValue = ComboBoxFirstItem.Id;
115+
ComboBoxFirstItem = default;
116+
117+
StateHasChanged();
118+
}
119+
}
120+
121+
private void ComboBoxValueChanged(int newValue)
122+
{
123+
ComboBoxValue = newValue;
124+
ComboBoxFirstItem = default;
125+
}
126+
127+
private async Task OnComboBoxRead(ReadEventArgs args)
128+
{
129+
var result = await ComboBoxData.ToDataSourceResultAsync(args.Request);
130+
131+
args.Data = result.Data;
132+
args.Total = result.Total;
133+
134+
if (args.Request.Filters.Count > 0)
135+
{
136+
ComboBoxFirstItem = args.Data.Cast<ListItem>().First();
137+
}
138+
else
139+
{
140+
ComboBoxFirstItem = default;
141+
}
142+
}
143+
144+
protected override async Task OnAfterRenderAsync(bool firstRender)
145+
{
146+
if (firstRender)
147+
{
148+
await Task.Delay(1); // ensure HTML is ready
149+
await js.InvokeVoidAsync("saveDotNetRef", DotNetRef);
150+
await js.InvokeVoidAsync("attachComboKeyDown", "#combo-1");
151+
}
152+
153+
await base.OnAfterRenderAsync(firstRender);
154+
}
155+
156+
protected override void OnInitialized()
157+
{
158+
DotNetRef = DotNetObjectReference.Create(this);
159+
160+
for (int i = 1; i <= 24; i++)
161+
{
162+
ComboBoxData.Add(new ListItem()
163+
{
164+
Id = i,
165+
Text = $"Item {i}"
166+
});
167+
}
168+
}
169+
170+
public void Dispose()
171+
{
172+
DotNetRef?.Dispose();
173+
_ = js.InvokeVoidAsync("detachComboKeyDown", "#combo-1");
174+
}
175+
176+
public class ListItem
177+
{
178+
public int Id { get; set; }
179+
public string Text { get; set; } = string.Empty;
180+
}
181+
}
182+
````
183+
## See Also
184+
185+
- [ComboBox Events](slug:components/combobox/events)

0 commit comments

Comments
 (0)