From dc2db0bbc8d4faf0d6a9776523c5aaa9378bfa47 Mon Sep 17 00:00:00 2001 From: Dimo Dimov <961014+dimodi@users.noreply.github.com> Date: Tue, 5 Aug 2025 13:26:14 +0300 Subject: [PATCH 1/5] kb(Dropdowns): Add KB for disabled select items --- knowledge-base/dropdown-disabled-items.md | 291 ++++++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 knowledge-base/dropdown-disabled-items.md diff --git a/knowledge-base/dropdown-disabled-items.md b/knowledge-base/dropdown-disabled-items.md new file mode 100644 index 000000000..73d0e4293 --- /dev/null +++ b/knowledge-base/dropdown-disabled-items.md @@ -0,0 +1,291 @@ +--- +title: Disable Dropdown Item for Selection +description: Learn how to use disabled items in a ComboBox or DropDownList that are visible, but cannot be selected by the user. +type: how-to +page_title: How to Disable ComboBox or DropDownList Item for Selection +slug: dropdown-kb-disabled-items +tags: telerik, blazor, combobox, dropdownlist, multiselect +ticketid: 1474264, 1593235, 1683944, 1695111 +res_type: kb +--- + +## Environment + + + + + + + + +
Product + ComboBox for Blazor,
+ DropDownList for Blazor,
+ MultiSelect for Blazor +
+ +## Description + +This KB also answers the following questions: + +* How to disable certain items in the ComboBox dropdown (popup)? +* How to denote if a DropDownList or MultiSelect item is selectable or disabled? +* How to flag data items in the Blazor ComboBox that are disabled and no longer available and selectable? + +## Solution + +The following algorithm applies to the Telerik Blazor ComboBox, DropDownList, and MultiSelect. Review the examples below for some minor implementation differences. + +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. +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. + +### ComboBox + +Reset the ComboBox value to default and then `Rebind()` the component after overriding the user selection. + +>caption Use disabled unselectable items in a ComboBox + +````RAZOR + + + +@code { + private TelerikComboBox? ComboBoxRef { get; set; } + + private List Products { get; set; } = new(); + + private int? ComboBoxValue { get; set; } + + private void OnComboBoxItemRender(ComboBoxItemRenderEventArgs args) + { + if (!args.Item.Enabled) + { + args.Class = "k-disabled"; + } + } + + private async Task ComboBoxValueChanged(int? newValue) + { + var newProduct = Products.FirstOrDefault(x => x.Id == newValue); + + // Select only enabled items or null + if (newProduct?.Enabled == true || !newValue.HasValue) + { + ComboBoxValue = newValue; + } + else + { + // Skip disabled items during keyboard navigation + // For simplicity, this logic does not handle adjacent disabled items + int oldProductIndex = Products.FindIndex(x => x.Id == ComboBoxValue); + int newProductIndex = Products.FindIndex(x => x.Id == newValue); + + ComboBoxValue = default; + await Task.Delay(1); + + if (newProductIndex > oldProductIndex && Products.Count > newProductIndex + 1) + { + ComboBoxValue = Products[++newProductIndex].Id; + } + else if (newProductIndex > 0) + { + ComboBoxValue = Products[--newProductIndex].Id; + } + else + { + ComboBoxValue = default; + } + + ComboBoxRef?.Rebind(); + } + } + + protected override void OnInitialized() + { + for (int i = 1; i <= 10; i++) + { + var enabled = i % 3 != 0; + + Products.Add(new Product() + { + Id = i, + Name = $"{(enabled ? "" : "Disabled ")}Product {i}", + Enabled = enabled + }); + } + + base.OnInitialized(); + } + + public class Product + { + public int? Id { get; set; } + public string Name { get; set; } = string.Empty; + public bool Enabled { get; set; } = true; + } +} +```` + +### DropDownList + +>caption Use disabled unselectable items in a DropDownList + +````RAZOR + + + +@code { + private List Products { get; set; } = new(); + + private int? DropDownListValue { get; set; } + + private void OnDropDownListItemRender(DropDownListItemRenderEventArgs args) + { + // args.Item is null for the DefaultText item + if (args.Item != null && !args.Item.Enabled) + { + args.Class = "k-disabled"; + } + } + + private void DropDownListValueChanged(int? newValue) + { + var newProduct = Products.FirstOrDefault(x => x.Id == newValue); + + // Select only enabled items or DefaultText + if (newProduct?.Enabled == true || !newValue.HasValue) + { + DropDownListValue = newValue; + } + else + { + // Skip disabled items during keyboard navigation + // For simplicity, this logic does not handle adjacent disabled items + int oldProductIndex = Products.FindIndex(x => x.Id == DropDownListValue); + int newProductIndex = Products.FindIndex(x => x.Id == newValue); + + if (newProductIndex > oldProductIndex && Products.Count > newProductIndex + 1) + { + DropDownListValue = Products[++newProductIndex].Id; + } + else if (newProductIndex > 0) + { + DropDownListValue = Products[--newProductIndex].Id; + } + else + { + DropDownListValue = default; + } + } + } + + protected override void OnInitialized() + { + for (int i = 1; i <= 10; i++) + { + var enabled = i % 3 != 0; + + Products.Add(new Product() + { + Id = i, + Name = $"{(enabled ? "" : "Disabled ")}Product {i}", + Enabled = enabled + }); + } + + base.OnInitialized(); + } + + public class Product + { + public int Id { get; set; } + public string Name { get; set; } = string.Empty; + public bool Enabled { get; set; } = true; + } +} +```` + +### MultiSelect + +````RAZOR + + +@code { + private List Products { get; set; } = new(); + private List EnabledProductIds { get; set; } = new(); + + private int? SelectedValue { get; set; } + + private List MultiSelectValues { get; set; } = new(); + + private void OnMultiSelectItemRender(MultiSelectItemRenderEventArgs args) + { + if (!args.Item.Enabled) + { + args.Class = "k-disabled"; + } + } + + private void MultiSelectValueChanged(List newValues) + { + MultiSelectValues = newValues.Where(x => EnabledProductIds.Contains(x)).ToList(); + } + + protected override void OnInitialized() + { + for (int i = 1; i <= 10; i++) + { + var enabled = i % 3 != 0; + + Products.Add(new Product() + { + Id = i, + Name = $"{(enabled ? "" : "Disabled ")}Product {i}", + Enabled = enabled + }); + } + + EnabledProductIds = Products.Where(x => x.Enabled).Select(x => x.Id).ToList(); + + base.OnInitialized(); + } + + public class Product + { + public int Id { get; set; } + public string Name { get; set; } = string.Empty; + public bool Enabled { get; set; } = true; + } +} +```` + +## See Also + +* [ComboBox Events](slug:components/combobox/events) +* [DropDownList Events](slug:components/dropdownlist/events) +* [MultiColumnComboBox Events](slug:multicolumncombobox-events) +* [MultiSelect Events](slug:multiselect-events) From 30747943b080d950b953c07af33d431bb55a8985 Mon Sep 17 00:00:00 2001 From: Dimo Dimov <961014+dimodi@users.noreply.github.com> Date: Tue, 5 Aug 2025 13:36:26 +0300 Subject: [PATCH 2/5] polishing --- knowledge-base/dropdown-disabled-items.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/knowledge-base/dropdown-disabled-items.md b/knowledge-base/dropdown-disabled-items.md index 73d0e4293..f136391f5 100644 --- a/knowledge-base/dropdown-disabled-items.md +++ b/knowledge-base/dropdown-disabled-items.md @@ -41,7 +41,7 @@ The following algorithm applies to the Telerik Blazor ComboBox, DropDownList, an ### ComboBox -Reset the ComboBox value to default and then `Rebind()` the component after overriding the user selection. +Reset the ComboBox value to default and then [`Rebind()`](slug:common-features-data-binding-overview#refresh-data) the component after overriding the user selection. >caption Use disabled unselectable items in a ComboBox @@ -136,6 +136,8 @@ Reset the ComboBox value to default and then `Rebind()` the component after over ### DropDownList +Unlike the ComboBox, the DropDownList does not need value resetting and `Rebind()` when overriding the user selection. + >caption Use disabled unselectable items in a DropDownList ````RAZOR @@ -222,6 +224,10 @@ Reset the ComboBox value to default and then `Rebind()` the component after over ### MultiSelect +The MultiSelect implementation is simpler, because there is no need to deliberately skip items during keyboard navigation with the arrow keys. + +>caption Use disabled unselectable items in a MultiSelect + ````RAZOR Date: Tue, 5 Aug 2025 13:43:59 +0300 Subject: [PATCH 3/5] Update knowledge-base/dropdown-disabled-items.md --- knowledge-base/dropdown-disabled-items.md | 1 - 1 file changed, 1 deletion(-) diff --git a/knowledge-base/dropdown-disabled-items.md b/knowledge-base/dropdown-disabled-items.md index f136391f5..004165264 100644 --- a/knowledge-base/dropdown-disabled-items.md +++ b/knowledge-base/dropdown-disabled-items.md @@ -293,5 +293,4 @@ The MultiSelect implementation is simpler, because there is no need to deliberat * [ComboBox Events](slug:components/combobox/events) * [DropDownList Events](slug:components/dropdownlist/events) -* [MultiColumnComboBox Events](slug:multicolumncombobox-events) * [MultiSelect Events](slug:multiselect-events) From 9bc6a41b343448768ad8a369759554de88d4a897 Mon Sep 17 00:00:00 2001 From: Dimo Dimov <961014+dimodi@users.noreply.github.com> Date: Tue, 5 Aug 2025 13:44:41 +0300 Subject: [PATCH 4/5] Update knowledge-base/dropdown-disabled-items.md --- knowledge-base/dropdown-disabled-items.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/knowledge-base/dropdown-disabled-items.md b/knowledge-base/dropdown-disabled-items.md index 004165264..a6897ebe6 100644 --- a/knowledge-base/dropdown-disabled-items.md +++ b/knowledge-base/dropdown-disabled-items.md @@ -4,7 +4,7 @@ description: Learn how to use disabled items in a ComboBox or DropDownList that type: how-to page_title: How to Disable ComboBox or DropDownList Item for Selection slug: dropdown-kb-disabled-items -tags: telerik, blazor, combobox, dropdownlist, multiselect +tags: telerik, blazor, combobox, dropdownlist, multiselect, selection ticketid: 1474264, 1593235, 1683944, 1695111 res_type: kb --- From adeef40c8d136eadee1d092f80851fefbc90a58c Mon Sep 17 00:00:00 2001 From: Dimo Dimov <961014+dimodi@users.noreply.github.com> Date: Tue, 5 Aug 2025 14:12:02 +0300 Subject: [PATCH 5/5] Address PR comments --- knowledge-base/dropdown-disabled-items.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/knowledge-base/dropdown-disabled-items.md b/knowledge-base/dropdown-disabled-items.md index a6897ebe6..aeedfbbfb 100644 --- a/knowledge-base/dropdown-disabled-items.md +++ b/knowledge-base/dropdown-disabled-items.md @@ -26,7 +26,9 @@ res_type: kb ## Description -This KB also answers the following questions: +This KB article shows how to use disabled non-selectable items in the Telerik ComboBox, DropDownList, and MultiSelect components for Blazor. + +The page also answers the following questions: * How to disable certain items in the ComboBox dropdown (popup)? * How to denote if a DropDownList or MultiSelect item is selectable or disabled? @@ -76,15 +78,15 @@ Reset the ComboBox value to default and then [`Rebind()`](slug:common-features-d { var newProduct = Products.FirstOrDefault(x => x.Id == newValue); - // Select only enabled items or null + // Select only enabled items or null. if (newProduct?.Enabled == true || !newValue.HasValue) { ComboBoxValue = newValue; } else { - // Skip disabled items during keyboard navigation - // For simplicity, this logic does not handle adjacent disabled items + // Skip disabled items during keyboard navigation. + // For simplicity, this logic does not handle adjacent disabled items. int oldProductIndex = Products.FindIndex(x => x.Id == ComboBoxValue); int newProductIndex = Products.FindIndex(x => x.Id == newValue); @@ -158,7 +160,7 @@ Unlike the ComboBox, the DropDownList does not need value resetting and `Rebind( private void OnDropDownListItemRender(DropDownListItemRenderEventArgs args) { - // args.Item is null for the DefaultText item + // args.Item is null for the DefaultText item. if (args.Item != null && !args.Item.Enabled) { args.Class = "k-disabled"; @@ -169,15 +171,15 @@ Unlike the ComboBox, the DropDownList does not need value resetting and `Rebind( { var newProduct = Products.FirstOrDefault(x => x.Id == newValue); - // Select only enabled items or DefaultText + // Select only enabled items or DefaultText. if (newProduct?.Enabled == true || !newValue.HasValue) { DropDownListValue = newValue; } else { - // Skip disabled items during keyboard navigation - // For simplicity, this logic does not handle adjacent disabled items + // Skip disabled items during keyboard navigation. + // For simplicity, this logic does not handle adjacent disabled items. int oldProductIndex = Products.FindIndex(x => x.Id == DropDownListValue); int newProductIndex = Products.FindIndex(x => x.Id == newValue);