diff --git a/Radzen.Blazor.Tests/DropDownTests.cs b/Radzen.Blazor.Tests/DropDownTests.cs index 3ce126e462d..bfdd2ccb821 100644 --- a/Radzen.Blazor.Tests/DropDownTests.cs +++ b/Radzen.Blazor.Tests/DropDownTests.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using AngleSharp.Dom; using Bunit; @@ -14,18 +15,20 @@ class DataItem { public string Text { get; set; } public int Id { get; set; } + public bool Disabled { get; set; } = false; } private static IRenderedComponent> DropDown(TestContext ctx, Action>> configure = null) { - var data = new [] { + var data = new[] { new DataItem { Text = "Item 1", Id = 1 }, new DataItem { Text = "Item 2", Id = 2 }, }; var component = ctx.RenderComponent>(); - component.SetParametersAndRender(parameters => { + component.SetParametersAndRender(parameters => + { parameters.Add(p => p.Data, data); parameters.Add(p => p.TextProperty, nameof(DataItem.Text)); @@ -100,7 +103,8 @@ public void DropDown_AppliesSelectionStyleForStringValue() ctx.JSInterop.Mode = JSRuntimeMode.Loose; - var component = DropDown(ctx, parameters => { + var component = DropDown(ctx, parameters => + { parameters.Add(p => p.ValueProperty, nameof(DataItem.Text)); }); @@ -123,7 +127,8 @@ public void DropDown_Respects_ItemEqualityComparer() List boundCollection = [new() { Text = "Item 2" }]; - var component = DropDown(ctx, parameters => { + var component = DropDown(ctx, parameters => + { parameters.Add(p => p.ItemComparer, new DataItemComparer()); parameters.Add(p => p.Multiple, true); parameters.Add(p => p.Value, boundCollection); @@ -150,7 +155,8 @@ public void DropDown_AppliesSelectionStyleWhenMultipleSelectionIsEnabled() ctx.JSInterop.Mode = JSRuntimeMode.Loose; - var component = DropDown(ctx, parameters => { + var component = DropDown(ctx, parameters => + { parameters.Add(p => p.ValueProperty, nameof(DataItem.Text)); parameters.Add(p => p.Multiple, true); }); @@ -275,6 +281,50 @@ public void DropDown_AppliesValueTemplateOnMultipleSelectionChips() Assert.Collection(selectedItems, item => Assert.Contains("value: Item 1", item.Text()), item => Assert.Contains("value: Item 2", item.Text())); } + [Theory] + [InlineData(false, true, false, true, "false")] + [InlineData(true, false, true, false, "true")] + [InlineData(true, false, false, false, "false")] + [InlineData(true, false, false, true, "true")] + [InlineData(false, false, false, true, "false")] + public void DropDown_AllSelectedFalseIfListIsAllDisabled(bool item1Selected, bool item1Disabled, bool item2Selected, bool item2Disabled, string expectedAriaCheckedValue) + { + using var ctx = new TestContext(); + ctx.JSInterop.Mode = JSRuntimeMode.Loose; + + var data = new[] { + new DataItem { Text = "Item 1", Id = 1, Disabled = item1Disabled }, + new DataItem { Text = "Item 2", Id = 2, Disabled = item2Disabled }, + }; + + List selectedValues = []; + if (item1Selected) + { + selectedValues.Add(data[0].Id); + } + if (item2Selected) + { + selectedValues.Add(data[1].Id); + } + + var component = ctx.RenderComponent>(parameters => parameters + .Add(p => p.Data, data) + .Add(p => p.Value, selectedValues) + .Add(p => p.Multiple, true) + .Add(p => p.AllowSelectAll, true) + .Add(p => p.TextProperty, nameof(DataItem.Text)) + .Add(p => p.DisabledProperty, nameof(DataItem.Disabled)) + .Add(p => p.ValueProperty, nameof(DataItem.Id))); + + Assert.NotNull(component); + var highlightedItems = component.FindAll(".rz-state-highlight"); + Assert.Equal(selectedValues.Count, highlightedItems.Count); + + + var selectAllCheckBox = component.Find(".rz-multiselect-header input[type='checkbox']"); + + Assert.Equal(expectedAriaCheckedValue, selectAllCheckBox.GetAttribute("aria-checked")); + } class DataItemComparer : IEqualityComparer, IEqualityComparer { diff --git a/Radzen.Blazor/DropDownBase.cs b/Radzen.Blazor/DropDownBase.cs index 515e8a20a5f..521149d8a0a 100644 --- a/Radzen.Blazor/DropDownBase.cs +++ b/Radzen.Blazor/DropDownBase.cs @@ -341,15 +341,17 @@ protected virtual async System.Threading.Tasks.Task SelectAll() internal bool IsAllSelected() { + List notDisabledItemsInList = View.Cast().ToList() + .Where(i => disabledPropertyGetter == null || disabledPropertyGetter(i) as bool? != true) + .ToList(); + if (LoadData.HasDelegate && !string.IsNullOrEmpty(ValueProperty)) { - return View != null && View.Cast().ToList() - .Where(i => disabledPropertyGetter != null ? disabledPropertyGetter(i) as bool? != true : true) + return View != null && notDisabledItemsInList.Count > 0 && notDisabledItemsInList .All(i => IsItemSelectedByValue(GetItemOrValueFromProperty(i, ValueProperty))); } - return View != null && selectedItems.Count == View.Cast().ToList() - .Where(i => disabledPropertyGetter != null ? disabledPropertyGetter(i) as bool? != true : true).Count(); + return View != null && notDisabledItemsInList.Count > 0 && selectedItems.Count == notDisabledItemsInList.Count; } ///