Skip to content

Commit 86405ce

Browse files
feat(transfer): should filter disabled item when click select all (#8147)
* feat(transfer)单击头部CheckBox时Items中IsDisabled为true的元素状态不改变 refactor:OnHeaderCheck方法中过滤IsDisabled=true的子元素 * chore: bump version 10.7.3-beta03 * feat: 增加左右面板区分功能 * doc: 更新示例文档 * doc: 更新示例多语言 * doc: 更新描述信息 * doc: 更新示例 * doc: 更新文档 * test: 更新单元测试 --------- Co-authored-by: Argo Zhang <argo@live.ca>
1 parent f8b77ad commit 86405ce

8 files changed

Lines changed: 67 additions & 6 deletions

File tree

‎src/BootstrapBlazor.Server/Components/Samples/Transfers.razor‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,18 @@
113113
ShowSearch="true" />
114114
</DemoBlock>
115115

116+
<DemoBlock Title="@Localizer["TransferDisabledCallbackTitle"]"
117+
Introduction="@Localizer["TransferDisabledCallbackIntro"]"
118+
Name="DisabledCallback">
119+
<Transfer TValue="string"
120+
Items="@Items7"
121+
OnDisabledCallback="OnDisabledCallback"
122+
LeftPanelText="@Localizer["LeftPanelText"]"
123+
RightPanelText="@Localizer["RightPanelText"]"
124+
LeftButtonText="@Localizer["LeftButtonText"]"
125+
RightButtonText="@Localizer["RightButtonText"]" />
126+
</DemoBlock>
127+
116128
<DemoBlock Title="@Localizer["TransferItemClassTitle"]"
117129
Introduction="@Localizer["TransferItemClassIntro"]"
118130
Name="ItemClass">

‎src/BootstrapBlazor.Server/Components/Samples/Transfers.razor.cs‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,11 @@ private void OnAddItem()
106106
"8" => "bg-warning text-white",
107107
_ => null
108108
};
109+
110+
// 回调参数 item 为 null 时代表头部全选项,返回 false 保证可点击全选
111+
// 其余指定 Value 的选项返回 true 表示禁用,禁用项不可勾选且不参与全选操作
112+
// 例如:左侧禁用 Value 为 2、4、6 的项,右侧禁用 Value 为 5 的项
113+
private static bool OnDisabledCallback(string source, SelectedItem? item) => source == "left"
114+
? item?.Value is "2" or "4" or "6"
115+
: item?.Value is "5";
109116
}

‎src/BootstrapBlazor.Server/Locales/en-US.json‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5704,6 +5704,8 @@
57045704
"TransferCustomerTitle": "Customizable",
57055705
"TransferDisableIntro": "When you set the <code>IsDisabled</code> property value to <code>true</code>, the component suppresses input",
57065706
"TransferDisableTitle": "Disable",
5707+
"TransferDisabledCallbackIntro": "By setting the <code>OnDisabledCallback</code> callback method, you can control whether specific items are disabled. The first argument <code>target</code> identifies the current panel — <code>left</code> for the left panel and <code>right</code> for the right panel — so you can apply different disable rules to each side. The second argument is the <code>SelectedItem</code>, which is <code>null</code> for the header select-all option. In this example the left panel disables <code>2</code> <code>4</code> <code>6</code> and the right panel disables <code>5</code>. Disabled items cannot be checked and are excluded from the select-all/deselect-all operations",
5708+
"TransferDisabledCallbackTitle": "Disable specific items",
57075709
"TransferItemClassIntro": "By setting the <code>OnSetItemClass</code> callback method styles options based on the<code> values of </code>SelectedItem",
57085710
"TransferItemClassTitle": "Set the Item style",
57095711
"TransferMinMaxIntro": "By setting <code>Min</code> <code>Max</code> Parameter to limit the number of options",

‎src/BootstrapBlazor.Server/Locales/zh-CN.json‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5704,6 +5704,8 @@
57045704
"TransferCustomerTitle": "可自定义",
57055705
"TransferDisableIntro": "设置 <code>IsDisabled</code> 属性值为 <code>true</code> 时,组件禁止输入",
57065706
"TransferDisableTitle": "禁用",
5707+
"TransferDisabledCallbackIntro": "通过设置 <code>OnDisabledCallback</code> 回调方法控制指定选项是否禁用。回调首个参数 <code>target</code> 用于标识当前面板,左侧面板为 <code>left</code>、右侧面板为 <code>right</code>,可据此对左右两侧分别设置禁用规则;第二个参数为 <code>SelectedItem</code>,为 <code>null</code> 时代表头部全选项。本例左侧面板禁用 <code>2</code> <code>4</code> <code>6</code>,右侧面板禁用 <code>5</code>。被禁用的选项不可勾选,且不参与全选/取消全选操作",
5708+
"TransferDisabledCallbackTitle": "禁用指定选项",
57075709
"TransferItemClassIntro": "通过设置 <code>OnSetItemClass</code> 回调方法根据 <code>SelectedItem</code> 值设置选项样式",
57085710
"TransferItemClassTitle": "设置 Item 样式",
57095711
"TransferMinMaxIntro": "通过设置 <code>Min</code> <code>Max</code> 参数来限制选项个数",

‎src/BootstrapBlazor/BootstrapBlazor.csproj‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk.Razor">
22

33
<PropertyGroup>
4-
<Version>10.7.3-beta02</Version>
4+
<Version>10.7.3-beta03</Version>
55
</PropertyGroup>
66

77
<ItemGroup>

‎src/BootstrapBlazor/Components/Transfer/Transfer.razor‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<TransferPanel Items="@LeftItems" Text="@LeftPanelText" IsDisabled="@IsDisabled"
1111
ShowSearch="@ShowSearch" SearchPlaceHolderString="@LeftPanelSearchPlaceHolderString"
1212
OnSelectedItemsChanged="@SelectedItemsChanged" OnSetItemClass="OnSetItemClass"
13-
OnDisabledCallback="OnDisabledCallback"
13+
OnDisabledCallback="OnLeftDisabledCallback"
1414
HeaderTemplate="LeftHeaderTemplate" ItemTemplate="LeftItemTemplate">
1515
</TransferPanel>
1616
<div class="transfer-buttons">
@@ -28,7 +28,7 @@
2828
<TransferPanel Items="@RightItems" Text="@RightPanelText" IsDisabled="@IsDisabled" class="@ValidateClass" Id="@Id"
2929
ShowSearch="@ShowSearch" SearchPlaceHolderString="@RightPanelSearchPlaceHolderString"
3030
OnSelectedItemsChanged="@SelectedItemsChanged" OnSetItemClass="OnSetItemClass"
31-
OnDisabledCallback="OnDisabledCallback"
31+
OnDisabledCallback="OnRightDisabledCallback"
3232
HeaderTemplate="RightHeaderTemplate" ItemTemplate="RightItemTemplate">
3333
</TransferPanel>
3434
</div>

‎src/BootstrapBlazor/Components/Transfer/Transfer.razor.cs‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,12 +186,12 @@ public partial class Transfer<TValue>
186186
public Func<SelectedItem, string?>? OnSetItemClass { get; set; }
187187

188188
/// <summary>
189-
/// <para lang="zh">获得/设置 组件是否被禁用回调方法,默认为 null</para>
190-
/// <para lang="en">Gets or sets the callback method for whether the component is disabled. Default is null</para>
189+
/// <para lang="zh">获得/设置 候选项是否被禁用回调方法,默认为 null</para>
190+
/// <para lang="en">Gets or sets the callback method for whether the transfer item is disabled. Default is null</para>
191191
/// <para>v<version>10.7.3</version></para>
192192
/// </summary>
193193
[Parameter]
194-
public Func<SelectedItem?, bool>? OnDisabledCallback { get; set; }
194+
public Func<string, SelectedItem?, bool>? OnDisabledCallback { get; set; }
195195

196196
/// <summary>
197197
/// <para lang="zh">获得/设置 左侧 Panel Header 模板</para>
@@ -425,4 +425,10 @@ private Task SelectedItemsChanged()
425425
}
426426

427427
private static bool GetButtonState(IEnumerable<SelectedItem> source) => !(source.Any(i => i.Active));
428+
429+
private bool OnLeftDisabledCallback(SelectedItem? item) => TriggerDisabledCallback("left", item);
430+
431+
private bool OnRightDisabledCallback(SelectedItem? item) => TriggerDisabledCallback("right", item);
432+
433+
private bool TriggerDisabledCallback(string target, SelectedItem? item) => OnDisabledCallback?.Invoke(target, item) ?? false;
428434
}

‎test/UnitTest/Components/TransferTest.cs‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,38 @@ public void Template_Ok()
273273
cut.Contains("Right-ItemTemplate-Test4");
274274
}
275275

276+
[Fact]
277+
public void OnDisabledCallback_Ok()
278+
{
279+
// 左侧面板仅禁用 Value 为 "1" 的项,右侧面板仅禁用 Value 为 "2" 的项
280+
// 通过 target 参数区分左右面板,验证回调首参正确传入 "left"/"right"
281+
var cut = Context.Render<Transfer<string>>(pb =>
282+
{
283+
pb.Add(a => a.Value, "2");
284+
pb.Add(a => a.Items,
285+
[
286+
new("1", "Test1"),
287+
new("2", "Test2")
288+
]);
289+
pb.Add(a => a.OnDisabledCallback, (target, item) => target == "left"
290+
? item?.Value == "1"
291+
: item?.Value == "2");
292+
});
293+
294+
var panels = cut.FindComponents<TransferPanel>();
295+
296+
// 左侧面板:Header(null) 未禁用,候选项 Test1 被禁用
297+
var leftCheckboxes = panels[0].FindComponents<Checkbox<SelectedItem>>();
298+
Assert.False(leftCheckboxes[0].Instance.IsDisabled);
299+
Assert.True(leftCheckboxes[1].Instance.IsDisabled);
300+
301+
// 右侧面板:Header(null) 未禁用,候选项 Test2 被禁用
302+
// 若 target 未正确传入 "right",则会走 "left" 分支按 Value == "1" 判断,Test2 将不会被禁用
303+
var rightCheckboxes = panels[1].FindComponents<Checkbox<SelectedItem>>();
304+
Assert.False(rightCheckboxes[0].Instance.IsDisabled);
305+
Assert.True(rightCheckboxes[1].Instance.IsDisabled);
306+
}
307+
276308
[Fact]
277309
public void IsWrapItem_Ok()
278310
{

0 commit comments

Comments
 (0)