Skip to content

Commit dc2db0b

Browse files
committed
kb(Dropdowns): Add KB for disabled select items
1 parent dccf38b commit dc2db0b

File tree

1 file changed

+291
-0
lines changed

1 file changed

+291
-0
lines changed
Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
---
2+
title: Disable Dropdown Item for Selection
3+
description: Learn how to use disabled items in a ComboBox or DropDownList that are visible, but cannot be selected by the user.
4+
type: how-to
5+
page_title: How to Disable ComboBox or DropDownList Item for Selection
6+
slug: dropdown-kb-disabled-items
7+
tags: telerik, blazor, combobox, dropdownlist, multiselect
8+
ticketid: 1474264, 1593235, 1683944, 1695111
9+
res_type: kb
10+
---
11+
12+
## Environment
13+
14+
<table>
15+
<tbody>
16+
<tr>
17+
<td>Product</td>
18+
<td>
19+
ComboBox for Blazor, <br />
20+
DropDownList for Blazor, <br />
21+
MultiSelect for Blazor
22+
</td>
23+
</tr>
24+
</tbody>
25+
</table>
26+
27+
## Description
28+
29+
This KB also answers the following questions:
30+
31+
* How to disable certain items in the ComboBox dropdown (popup)?
32+
* How to denote if a DropDownList or MultiSelect item is selectable or disabled?
33+
* How to flag data items in the Blazor ComboBox that are disabled and no longer available and selectable?
34+
35+
## Solution
36+
37+
The following algorithm applies to the Telerik Blazor ComboBox, DropDownList, and MultiSelect. Review the examples below for some minor implementation differences.
38+
39+
1. Use the component's `OnItemRender` event to apply a `k-disabled` CSS class to non-selectable items. This prevents selection disabled items with a click or tap.
40+
1. Use the component's `ValueChanged` event to track the user selection and override it. This applies especially to ComboBox and DropDownList keyboard navigation, where you should select the next or previous enabled item in the list.
41+
42+
### ComboBox
43+
44+
Reset the ComboBox value to default and then `Rebind()` the component after overriding the user selection.
45+
46+
>caption Use disabled unselectable items in a ComboBox
47+
48+
````RAZOR
49+
<TelerikComboBox @ref="@ComboBoxRef"
50+
Data="@Products"
51+
Value="@ComboBoxValue"
52+
ValueChanged="@( (int? newValue) => ComboBoxValueChanged(newValue) )"
53+
TextField="@nameof(Product.Name)"
54+
ValueField="@nameof(Product.Id)"
55+
Placeholder="Select Product..."
56+
OnItemRender="@OnComboBoxItemRender"
57+
Width="200px">
58+
</TelerikComboBox>
59+
60+
@code {
61+
private TelerikComboBox<Product, int?>? ComboBoxRef { get; set; }
62+
63+
private List<Product> Products { get; set; } = new();
64+
65+
private int? ComboBoxValue { get; set; }
66+
67+
private void OnComboBoxItemRender(ComboBoxItemRenderEventArgs<Product> args)
68+
{
69+
if (!args.Item.Enabled)
70+
{
71+
args.Class = "k-disabled";
72+
}
73+
}
74+
75+
private async Task ComboBoxValueChanged(int? newValue)
76+
{
77+
var newProduct = Products.FirstOrDefault(x => x.Id == newValue);
78+
79+
// Select only enabled items or null
80+
if (newProduct?.Enabled == true || !newValue.HasValue)
81+
{
82+
ComboBoxValue = newValue;
83+
}
84+
else
85+
{
86+
// Skip disabled items during keyboard navigation
87+
// For simplicity, this logic does not handle adjacent disabled items
88+
int oldProductIndex = Products.FindIndex(x => x.Id == ComboBoxValue);
89+
int newProductIndex = Products.FindIndex(x => x.Id == newValue);
90+
91+
ComboBoxValue = default;
92+
await Task.Delay(1);
93+
94+
if (newProductIndex > oldProductIndex && Products.Count > newProductIndex + 1)
95+
{
96+
ComboBoxValue = Products[++newProductIndex].Id;
97+
}
98+
else if (newProductIndex > 0)
99+
{
100+
ComboBoxValue = Products[--newProductIndex].Id;
101+
}
102+
else
103+
{
104+
ComboBoxValue = default;
105+
}
106+
107+
ComboBoxRef?.Rebind();
108+
}
109+
}
110+
111+
protected override void OnInitialized()
112+
{
113+
for (int i = 1; i <= 10; i++)
114+
{
115+
var enabled = i % 3 != 0;
116+
117+
Products.Add(new Product()
118+
{
119+
Id = i,
120+
Name = $"{(enabled ? "" : "Disabled ")}Product {i}",
121+
Enabled = enabled
122+
});
123+
}
124+
125+
base.OnInitialized();
126+
}
127+
128+
public class Product
129+
{
130+
public int? Id { get; set; }
131+
public string Name { get; set; } = string.Empty;
132+
public bool Enabled { get; set; } = true;
133+
}
134+
}
135+
````
136+
137+
### DropDownList
138+
139+
>caption Use disabled unselectable items in a DropDownList
140+
141+
````RAZOR
142+
<TelerikDropDownList Data="@Products"
143+
Value="@DropDownListValue"
144+
ValueChanged="@( (int? newValue) => DropDownListValueChanged(newValue) )"
145+
TextField="@nameof(Product.Name)"
146+
ValueField="@nameof(Product.Id)"
147+
DefaultText="Select Product..."
148+
OnItemRender="@OnDropDownListItemRender"
149+
Width="200px">
150+
</TelerikDropDownList>
151+
152+
@code {
153+
private List<Product> Products { get; set; } = new();
154+
155+
private int? DropDownListValue { get; set; }
156+
157+
private void OnDropDownListItemRender(DropDownListItemRenderEventArgs<Product> args)
158+
{
159+
// args.Item is null for the DefaultText item
160+
if (args.Item != null && !args.Item.Enabled)
161+
{
162+
args.Class = "k-disabled";
163+
}
164+
}
165+
166+
private void DropDownListValueChanged(int? newValue)
167+
{
168+
var newProduct = Products.FirstOrDefault(x => x.Id == newValue);
169+
170+
// Select only enabled items or DefaultText
171+
if (newProduct?.Enabled == true || !newValue.HasValue)
172+
{
173+
DropDownListValue = newValue;
174+
}
175+
else
176+
{
177+
// Skip disabled items during keyboard navigation
178+
// For simplicity, this logic does not handle adjacent disabled items
179+
int oldProductIndex = Products.FindIndex(x => x.Id == DropDownListValue);
180+
int newProductIndex = Products.FindIndex(x => x.Id == newValue);
181+
182+
if (newProductIndex > oldProductIndex && Products.Count > newProductIndex + 1)
183+
{
184+
DropDownListValue = Products[++newProductIndex].Id;
185+
}
186+
else if (newProductIndex > 0)
187+
{
188+
DropDownListValue = Products[--newProductIndex].Id;
189+
}
190+
else
191+
{
192+
DropDownListValue = default;
193+
}
194+
}
195+
}
196+
197+
protected override void OnInitialized()
198+
{
199+
for (int i = 1; i <= 10; i++)
200+
{
201+
var enabled = i % 3 != 0;
202+
203+
Products.Add(new Product()
204+
{
205+
Id = i,
206+
Name = $"{(enabled ? "" : "Disabled ")}Product {i}",
207+
Enabled = enabled
208+
});
209+
}
210+
211+
base.OnInitialized();
212+
}
213+
214+
public class Product
215+
{
216+
public int Id { get; set; }
217+
public string Name { get; set; } = string.Empty;
218+
public bool Enabled { get; set; } = true;
219+
}
220+
}
221+
````
222+
223+
### MultiSelect
224+
225+
````RAZOR
226+
<TelerikMultiSelect Data="@Products"
227+
Value="@MultiSelectValues"
228+
ValueChanged="@( (List<int> newValues) => MultiSelectValueChanged(newValues) )"
229+
TextField="@nameof(Product.Name)"
230+
ValueField="@nameof(Product.Id)"
231+
AutoClose="false"
232+
Placeholder="Select Products..."
233+
ShowArrowButton="true"
234+
OnItemRender="@OnMultiSelectItemRender"
235+
Width="600px" />
236+
237+
@code {
238+
private List<Product> Products { get; set; } = new();
239+
private List<int> EnabledProductIds { get; set; } = new();
240+
241+
private int? SelectedValue { get; set; }
242+
243+
private List<int> MultiSelectValues { get; set; } = new();
244+
245+
private void OnMultiSelectItemRender(MultiSelectItemRenderEventArgs<Product> args)
246+
{
247+
if (!args.Item.Enabled)
248+
{
249+
args.Class = "k-disabled";
250+
}
251+
}
252+
253+
private void MultiSelectValueChanged(List<int> newValues)
254+
{
255+
MultiSelectValues = newValues.Where(x => EnabledProductIds.Contains(x)).ToList();
256+
}
257+
258+
protected override void OnInitialized()
259+
{
260+
for (int i = 1; i <= 10; i++)
261+
{
262+
var enabled = i % 3 != 0;
263+
264+
Products.Add(new Product()
265+
{
266+
Id = i,
267+
Name = $"{(enabled ? "" : "Disabled ")}Product {i}",
268+
Enabled = enabled
269+
});
270+
}
271+
272+
EnabledProductIds = Products.Where(x => x.Enabled).Select(x => x.Id).ToList();
273+
274+
base.OnInitialized();
275+
}
276+
277+
public class Product
278+
{
279+
public int Id { get; set; }
280+
public string Name { get; set; } = string.Empty;
281+
public bool Enabled { get; set; } = true;
282+
}
283+
}
284+
````
285+
286+
## See Also
287+
288+
* [ComboBox Events](slug:components/combobox/events)
289+
* [DropDownList Events](slug:components/dropdownlist/events)
290+
* [MultiColumnComboBox Events](slug:multicolumncombobox-events)
291+
* [MultiSelect Events](slug:multiselect-events)

0 commit comments

Comments
 (0)