Skip to content

Commit cd23901

Browse files
authored
feat(Table): support ResetColumnList method (#7665)
* style: 更新弹窗样式 * refactor: 格式化代码 * feat: 增加 resetColumnList 回调方法 * doc: 更新示例 * doc: 增加变量示例 * refactor: 更新文件编码 * refactor: 更新销毁逻辑 * test: 更新单元测试 * refactor: 代码格式化 * refactor: 重构代码
1 parent 0947e68 commit cd23901

File tree

9 files changed

+87
-14
lines changed

9 files changed

+87
-14
lines changed

src/BootstrapBlazor.Server/Components/Samples/Table/TablesColumnList.razor

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,33 @@
1818
<p>@((MarkupString)Localizer["VisibleP3"].Value)</p>
1919
<p>@((MarkupString)Localizer["VisibleP4"].Value)</p>
2020
<p>@((MarkupString)Localizer["ResetVisibleColumnsDesc"].Value)</p>
21+
<p>@((MarkupString)Localizer["IsPopoverToolbarDropdownButtonDesc"].Value)</p>
22+
<div class="row form-inline g-3">
23+
<div class="col-12 col-sm-6">
24+
<BootstrapInputGroup>
25+
<BootstrapInputGroupLabel DisplayText="IsPopoverToolbarDropdownButton"></BootstrapInputGroupLabel>
26+
<Switch @bind-Value="_isPopoverToolbarDropdownButton">
27+
</Switch>
28+
</BootstrapInputGroup>
29+
</div>
30+
<div class="col-12 col-sm-6">
31+
<BootstrapInputGroup>
32+
<BootstrapInputGroupLabel DisplayText="ShowColumnListControls"></BootstrapInputGroupLabel>
33+
<Switch @bind-Value="_showColumnListControls">
34+
</Switch>
35+
</BootstrapInputGroup>
36+
</div>
37+
</div>
2138
</section>
2239
<Button Text="@Localizer["ResetVisibleColumnsButtonText"]" OnClickWithoutRender="ResetVisibleColumns"></Button>
2340

2441
<Table TItem="Foo" @ref="TableColumnVisible"
2542
IsPagination="true" PageItemsSource="@PageItemsSource"
26-
IsStriped="true" IsBordered="true" IsMultipleSelect="true" ShowColumnListControls="true"
43+
ShowColumnList="true" ShowColumnListControls="_showColumnListControls"
44+
IsPopoverToolbarDropdownButton="_isPopoverToolbarDropdownButton"
45+
IsStriped="true" IsBordered="true" IsMultipleSelect="true"
2746
ShowToolbar="true" ShowAddButton="false" ShowEditButton="false" ShowDeleteButton="false"
28-
ShowExtendButtons="false" ShowColumnList="true" ClientTableName="test_table"
47+
ShowExtendButtons="false" ClientTableName="test_table"
2948
OnQueryAsync="@OnQueryAsync">
3049
<TableColumns>
3150
<TableColumn @bind-Field="@context.DateTime" Width="180" />

src/BootstrapBlazor.Server/Components/Samples/Table/TablesColumnList.razor.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Licensed to the .NET Foundation under one or more agreements.
1+
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the Apache 2.0 License
33
// See the LICENSE file in the project root for more information.
44
// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone
@@ -27,6 +27,9 @@ public partial class TablesColumnList
2727
[NotNull]
2828
private Table<Foo>? TableColumnVisible { get; set; }
2929

30+
private bool _isPopoverToolbarDropdownButton = true;
31+
private bool _showColumnListControls = true;
32+
3033
/// <summary>
3134
/// OnInitialized 方法
3235
/// </summary>
@@ -51,7 +54,7 @@ private Task<QueryData<Foo>> OnQueryAsync(QueryPageOptions options)
5154
IEnumerable<Foo> items = Items;
5255
// 过滤
5356
var isFiltered = false;
54-
if (options.Filters.Any())
57+
if (options.Filters.Count > 0)
5558
{
5659
items = items.Where(options.Filters.GetFilterFunc<Foo>());
5760
isFiltered = true;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4559,6 +4559,7 @@
45594559
"ShownWithBreakPointP4": "Because the <code>Table</code> component supports mobile adaptation by default, the card mode is used for small screens. In this example, the explicit setting uses <code>RenderMode=\"TableRenderMode. Table\"</code> mode",
45604560
"ShownWithBreakPointTitle": "Automatically show/hide columns based on screen width",
45614561
"TablesColumnDescription": "Used to display multiple pieces of data with similar structures, data can be sorted, filtered, compared or other custom operations.",
4562+
"IsPopoverToolbarDropdownButtonDesc": "The <code>IsPopoverToolbarDropdownButton</code> parameter controls whether the column list is displayed as a popover or a dropdown menu. The default value is <code>false</code>, which means it is displayed as a dropdown menu. When set to <code>true</code>, it is displayed as a popover.",
45624563
"TablesColumnTitle": "Table Column",
45634564
"VisibleIntro": "Set whether the column is displayed by specifying the <code>ShowColumnList</code> attribute",
45644565
"VisibleP1": "<code>ShowColumnList</code> The default value is false, and if it is explicitly specified as true, the corresponding column adjustment button will appear in the toolbar",

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4559,6 +4559,7 @@
45594559
"ShownWithBreakPointP4": "由于 <code>Table</code> 组件默认是支持移动端适配,所以小屏幕时采用的是卡片式模式,本例中显式设置使用 <code>RenderMode=\"TableRenderMode.Table\"</code> 模式",
45604560
"ShownWithBreakPointTitle": "根据屏幕宽度自动显示/隐藏列",
45614561
"TablesColumnDescription": "用于展示多条结构类似的数据,可对数据进行排序、筛选、对比或其他自定义操作。",
4562+
"IsPopoverToolbarDropdownButtonDesc": "通过设置 <code>IsPopoverToolbarDropdownButton</code> 属性,工具栏列下拉框显示为气泡弹窗形式",
45624563
"TablesColumnTitle": "Table 表格",
45634564
"VisibleIntro": "通过指定 <code>ShowColumnList</code> 属性设置列是否显示",
45644565
"VisibleP1": "<code>ShowColumnList</code> 默认值为 false,显式指定为 true 后工具栏出现相应列调整按钮",

src/BootstrapBlazor/Components/Table/Table.razor.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -941,8 +941,11 @@ public async Task ExpandDetailRow(TItem item)
941941

942942
private string? DropdownListClassString => CssBuilder.Default("dropdown-menu dropdown-menu-end shadow")
943943
.AddClass("dropdown-menu-controls", ShowColumnListControls)
944+
.AddClass("dropdown-menu-popover", IsPopoverToolbarDropdownButton)
944945
.Build();
945946

947+
private bool _lastIsPopoverToolbarDropdownButtonValue = false;
948+
946949
/// <summary>
947950
/// <inheritdoc/>
948951
/// </summary>
@@ -1151,6 +1154,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
11511154

11521155
if (firstRender)
11531156
{
1157+
_lastIsPopoverToolbarDropdownButtonValue = IsPopoverToolbarDropdownButton;
11541158
await ProcessFirstRender();
11551159
}
11561160

@@ -1208,6 +1212,13 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
12081212
await InvokeVoidAsync("scrollTo", Id);
12091213
}
12101214

1215+
// 如果 ColumnList 显示状态改变重置 ColumnList 渲染模式
1216+
if (_lastIsPopoverToolbarDropdownButtonValue != IsPopoverToolbarDropdownButton)
1217+
{
1218+
_lastIsPopoverToolbarDropdownButtonValue = IsPopoverToolbarDropdownButton;
1219+
await InvokeVoidAsync("resetColumnList", Id);
1220+
}
1221+
12111222
// 增加去重保护 _loop 为 false 时执行
12121223
if (!_loop && IsAutoRefresh && AutoRefreshInterval > 500)
12131224
{

src/BootstrapBlazor/Components/Table/Table.razor.js

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
export { getResponsive } from '../../modules/responsive.js'
22
import { copy, drag, getDescribedElement, getOuterHeight, getWidth, isVisible } from '../../modules/utility.js'
3-
import browser from '../../modules/browser.min.mjs'
3+
import browser from '../../modules/browser.min.mjs'
44
import Data from '../../modules/data.js'
55
import EventHandler from '../../modules/event-handler.js'
66
import Popover from "../../modules/base-popover.js"
77

8-
export function init(id, invoke, options) {
8+
export async function init(id, invoke, options) {
99
const el = document.getElementById(id)
1010
if (el === null) {
1111
return
@@ -18,7 +18,7 @@ export function init(id, invoke, options) {
1818
}
1919
Data.set(id, table)
2020

21-
reset(id)
21+
await reset(id)
2222
}
2323

2424
export function saveColumnList(tableName, columns) {
@@ -121,7 +121,6 @@ export async function reset(id) {
121121

122122
table.pages = [...table.el.children].find(i => i.classList.contains('nav-pages'));
123123

124-
125124
setColumnToolboxListener(table);
126125

127126
if (isVisible(table.el) === false) {
@@ -824,8 +823,7 @@ const calcCellWidth = cell => {
824823
document.body.appendChild(div);
825824

826825
const cellStyle = getComputedStyle(cell);
827-
const width = div.offsetWidth + parseFloat(cellStyle.getPropertyValue('padding-left')) + parseFloat(cellStyle.getPropertyValue('padding-right')) + parseFloat(cellStyle.getPropertyValue('border-left-width')) + parseFloat(cellStyle.getPropertyValue('border-right-width')) + 1;
828-
return width;
826+
return div.offsetWidth + parseFloat(cellStyle.getPropertyValue('padding-left')) + parseFloat(cellStyle.getPropertyValue('padding-right')) + parseFloat(cellStyle.getPropertyValue('border-left-width')) + parseFloat(cellStyle.getPropertyValue('border-right-width')) + 1;
829827
}
830828

831829
const closeAllTips = (columns, self) => {
@@ -1003,6 +1001,33 @@ const setToolbarDropdown = (table, toolbar) => {
10031001
})
10041002
}
10051003

1004+
export function resetColumnList(id) {
1005+
const table = Data.get(id);
1006+
if (table) {
1007+
const { toolbar } = table;
1008+
if (toolbar) {
1009+
const dropdown = toolbar.querySelector('.dropdown-column');
1010+
if (dropdown) {
1011+
const button = dropdown.querySelector('.dropdown-toggle');
1012+
const dropdownToggle = bootstrap.Dropdown.getInstance(button);
1013+
if (dropdownToggle) {
1014+
dropdownToggle.dispose();
1015+
}
1016+
const p = table.popovers.find(i => i.el === dropdown);
1017+
if (p) {
1018+
table.popovers = table.popovers.filter(i => i !== p);
1019+
Popover.dispose(p);
1020+
}
1021+
if (button.getAttribute('data-bs-toggle') === 'bb.dropdown') {
1022+
table.popovers.push(Popover.init(dropdown, {
1023+
isDisabled: () => false
1024+
}));
1025+
}
1026+
}
1027+
}
1028+
}
1029+
}
1030+
10061031
const saveColumnWidth = table => {
10071032
const cols = table.columns
10081033
const tableWidth = table.tables[0].offsetWidth

src/BootstrapBlazor/Components/Table/Table.razor.scss

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
.dropdown-menu-popover {
2+
--bb-table-columnlist-max-height: var(--bb-dropdown-max-height);
3+
}
4+
15
.table-container {
26
--bb-table-td-padding-x: .5rem;
37
--bb-table-td-padding-y: .5rem;
@@ -307,7 +311,8 @@
307311
margin-block-end: .5rem;
308312
}
309313

310-
.table-toolbar .dropdown-column .dropdown-menu {
314+
.table-toolbar .dropdown-column .dropdown-menu,
315+
.dropdown-menu-popover {
311316

312317
&:not(.dropdown-menu-controls) {
313318
max-height: var(--bb-table-columnlist-max-height);

src/BootstrapBlazor/wwwroot/modules/base-popover.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { getDescribedElement, getDescribedOwner, hackTooltip, hackPopover, isDisabled, registerBootstrapBlazorModule } from "./utility.js"
1+
import { getDescribedElement, getDescribedOwner, hackTooltip, hackPopover, isDisabled, registerBootstrapBlazorModule } from "./utility.js"
22
import EventHandler from "./event-handler.js"
33

44
const Popover = {
@@ -74,7 +74,7 @@ const Popover = {
7474
popover.triggerHideCallback = () => {
7575
if (popover.hideCallback) {
7676
popover.hideCallback();
77-
};
77+
}
7878
}
7979

8080
if (popover.isPopover) {

test/UnitTest/Components/TableTest.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,7 @@ public async Task ShowColumnList_Ok()
747747
pb.Add(a => a.RenderMode, TableRenderMode.Table);
748748
pb.Add(a => a.ShowToolbar, true);
749749
pb.Add(a => a.ShowColumnList, true);
750-
pb.Add(a => a.IsPopoverToolbarDropdownButton, true);
750+
pb.Add(a => a.IsPopoverToolbarDropdownButton, false);
751751
pb.Add(a => a.AllowResizing, true);
752752
pb.Add(a => a.ShowColumnWidthTooltip, true);
753753
pb.Add(a => a.ColumnWidthTooltipPrefix, "test");
@@ -775,13 +775,21 @@ public async Task ShowColumnList_Ok()
775775
});
776776
});
777777
cut.Contains("Test_Column_List");
778+
cut.DoesNotContain("dropdown-menu-popover");
778779

779780
var item = cut.FindComponents<Checkbox<bool>>()[0];
780781
await cut.InvokeAsync(item.Instance.OnToggleClick);
781782
Assert.True(show);
782783

783784
await cut.InvokeAsync(item.Instance.OnToggleClick);
784785
Assert.False(show);
786+
787+
var table = cut.FindComponent<Table<Foo>>();
788+
table.Render(pb =>
789+
{
790+
pb.Add(a => a.IsPopoverToolbarDropdownButton, true);
791+
});
792+
table.Contains("dropdown-menu-popover");
785793
}
786794

787795
[Fact]

0 commit comments

Comments
 (0)