diff --git a/src/BootstrapBlazor.Server/Components/Samples/Table/TablesColumnList.razor b/src/BootstrapBlazor.Server/Components/Samples/Table/TablesColumnList.razor index ec2a6072130..4a07405604e 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Table/TablesColumnList.razor +++ b/src/BootstrapBlazor.Server/Components/Samples/Table/TablesColumnList.razor @@ -18,14 +18,33 @@

@((MarkupString)Localizer["VisibleP3"].Value)

@((MarkupString)Localizer["VisibleP4"].Value)

@((MarkupString)Localizer["ResetVisibleColumnsDesc"].Value)

+

@((MarkupString)Localizer["IsPopoverToolbarDropdownButtonDesc"].Value)

+
+
+ + + + + +
+
+ + + + + +
+
diff --git a/src/BootstrapBlazor.Server/Components/Samples/Table/TablesColumnList.razor.cs b/src/BootstrapBlazor.Server/Components/Samples/Table/TablesColumnList.razor.cs index ffe6e3be8ed..c8f56ba7888 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Table/TablesColumnList.razor.cs +++ b/src/BootstrapBlazor.Server/Components/Samples/Table/TablesColumnList.razor.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the Apache 2.0 License // See the LICENSE file in the project root for more information. // Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone @@ -27,6 +27,9 @@ public partial class TablesColumnList [NotNull] private Table? TableColumnVisible { get; set; } + private bool _isPopoverToolbarDropdownButton = true; + private bool _showColumnListControls = true; + /// /// OnInitialized 方法 /// @@ -51,7 +54,7 @@ private Task> OnQueryAsync(QueryPageOptions options) IEnumerable items = Items; // 过滤 var isFiltered = false; - if (options.Filters.Any()) + if (options.Filters.Count > 0) { items = items.Where(options.Filters.GetFilterFunc()); isFiltered = true; diff --git a/src/BootstrapBlazor.Server/Locales/en-US.json b/src/BootstrapBlazor.Server/Locales/en-US.json index f8b9deb9d07..dbcc3bdc275 100644 --- a/src/BootstrapBlazor.Server/Locales/en-US.json +++ b/src/BootstrapBlazor.Server/Locales/en-US.json @@ -4559,6 +4559,7 @@ "ShownWithBreakPointP4": "Because the Table component supports mobile adaptation by default, the card mode is used for small screens. In this example, the explicit setting uses RenderMode=\"TableRenderMode. Table\" mode", "ShownWithBreakPointTitle": "Automatically show/hide columns based on screen width", "TablesColumnDescription": "Used to display multiple pieces of data with similar structures, data can be sorted, filtered, compared or other custom operations.", + "IsPopoverToolbarDropdownButtonDesc": "The IsPopoverToolbarDropdownButton parameter controls whether the column list is displayed as a popover or a dropdown menu. The default value is false, which means it is displayed as a dropdown menu. When set to true, it is displayed as a popover.", "TablesColumnTitle": "Table Column", "VisibleIntro": "Set whether the column is displayed by specifying the ShowColumnList attribute", "VisibleP1": "ShowColumnList The default value is false, and if it is explicitly specified as true, the corresponding column adjustment button will appear in the toolbar", diff --git a/src/BootstrapBlazor.Server/Locales/zh-CN.json b/src/BootstrapBlazor.Server/Locales/zh-CN.json index 1bdd5814fe5..21afc4cc7fd 100644 --- a/src/BootstrapBlazor.Server/Locales/zh-CN.json +++ b/src/BootstrapBlazor.Server/Locales/zh-CN.json @@ -4559,6 +4559,7 @@ "ShownWithBreakPointP4": "由于 Table 组件默认是支持移动端适配,所以小屏幕时采用的是卡片式模式,本例中显式设置使用 RenderMode=\"TableRenderMode.Table\" 模式", "ShownWithBreakPointTitle": "根据屏幕宽度自动显示/隐藏列", "TablesColumnDescription": "用于展示多条结构类似的数据,可对数据进行排序、筛选、对比或其他自定义操作。", + "IsPopoverToolbarDropdownButtonDesc": "通过设置 IsPopoverToolbarDropdownButton 属性,工具栏列下拉框显示为气泡弹窗形式", "TablesColumnTitle": "Table 表格", "VisibleIntro": "通过指定 ShowColumnList 属性设置列是否显示", "VisibleP1": "ShowColumnList 默认值为 false,显式指定为 true 后工具栏出现相应列调整按钮", diff --git a/src/BootstrapBlazor/Components/Table/Table.razor.cs b/src/BootstrapBlazor/Components/Table/Table.razor.cs index 61b2722903a..432c56e238a 100644 --- a/src/BootstrapBlazor/Components/Table/Table.razor.cs +++ b/src/BootstrapBlazor/Components/Table/Table.razor.cs @@ -941,8 +941,11 @@ public async Task ExpandDetailRow(TItem item) private string? DropdownListClassString => CssBuilder.Default("dropdown-menu dropdown-menu-end shadow") .AddClass("dropdown-menu-controls", ShowColumnListControls) + .AddClass("dropdown-menu-popover", IsPopoverToolbarDropdownButton) .Build(); + private bool _lastIsPopoverToolbarDropdownButtonValue = false; + /// /// /// @@ -1151,6 +1154,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) if (firstRender) { + _lastIsPopoverToolbarDropdownButtonValue = IsPopoverToolbarDropdownButton; await ProcessFirstRender(); } @@ -1208,6 +1212,13 @@ protected override async Task OnAfterRenderAsync(bool firstRender) await InvokeVoidAsync("scrollTo", Id); } + // 如果 ColumnList 显示状态改变重置 ColumnList 渲染模式 + if (_lastIsPopoverToolbarDropdownButtonValue != IsPopoverToolbarDropdownButton) + { + _lastIsPopoverToolbarDropdownButtonValue = IsPopoverToolbarDropdownButton; + await InvokeVoidAsync("resetColumnList", Id); + } + // 增加去重保护 _loop 为 false 时执行 if (!_loop && IsAutoRefresh && AutoRefreshInterval > 500) { diff --git a/src/BootstrapBlazor/Components/Table/Table.razor.js b/src/BootstrapBlazor/Components/Table/Table.razor.js index 5d9f7316d8e..5066ea5f35a 100644 --- a/src/BootstrapBlazor/Components/Table/Table.razor.js +++ b/src/BootstrapBlazor/Components/Table/Table.razor.js @@ -1,11 +1,11 @@ export { getResponsive } from '../../modules/responsive.js' import { copy, drag, getDescribedElement, getOuterHeight, getWidth, isVisible } from '../../modules/utility.js' -import browser from '../../modules/browser.min.mjs' +import browser from '../../modules/browser.min.mjs' import Data from '../../modules/data.js' import EventHandler from '../../modules/event-handler.js' import Popover from "../../modules/base-popover.js" -export function init(id, invoke, options) { +export async function init(id, invoke, options) { const el = document.getElementById(id) if (el === null) { return @@ -18,7 +18,7 @@ export function init(id, invoke, options) { } Data.set(id, table) - reset(id) + await reset(id) } export function saveColumnList(tableName, columns) { @@ -121,7 +121,6 @@ export async function reset(id) { table.pages = [...table.el.children].find(i => i.classList.contains('nav-pages')); - setColumnToolboxListener(table); if (isVisible(table.el) === false) { @@ -824,8 +823,7 @@ const calcCellWidth = cell => { document.body.appendChild(div); const cellStyle = getComputedStyle(cell); - 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; - return width; + 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; } const closeAllTips = (columns, self) => { @@ -1003,6 +1001,33 @@ const setToolbarDropdown = (table, toolbar) => { }) } +export function resetColumnList(id) { + const table = Data.get(id); + if (table) { + const { toolbar } = table; + if (toolbar) { + const dropdown = toolbar.querySelector('.dropdown-column'); + if (dropdown) { + const button = dropdown.querySelector('.dropdown-toggle'); + const dropdownToggle = bootstrap.Dropdown.getInstance(button); + if (dropdownToggle) { + dropdownToggle.dispose(); + } + const p = table.popovers.find(i => i.el === dropdown); + if (p) { + table.popovers = table.popovers.filter(i => i !== p); + Popover.dispose(p); + } + if (button.getAttribute('data-bs-toggle') === 'bb.dropdown') { + table.popovers.push(Popover.init(dropdown, { + isDisabled: () => false + })); + } + } + } + } +} + const saveColumnWidth = table => { const cols = table.columns const tableWidth = table.tables[0].offsetWidth diff --git a/src/BootstrapBlazor/Components/Table/Table.razor.scss b/src/BootstrapBlazor/Components/Table/Table.razor.scss index 7591f140041..e5ff775a1e0 100644 --- a/src/BootstrapBlazor/Components/Table/Table.razor.scss +++ b/src/BootstrapBlazor/Components/Table/Table.razor.scss @@ -1,3 +1,7 @@ +.dropdown-menu-popover { + --bb-table-columnlist-max-height: var(--bb-dropdown-max-height); +} + .table-container { --bb-table-td-padding-x: .5rem; --bb-table-td-padding-y: .5rem; @@ -307,7 +311,8 @@ margin-block-end: .5rem; } -.table-toolbar .dropdown-column .dropdown-menu { +.table-toolbar .dropdown-column .dropdown-menu, +.dropdown-menu-popover { &:not(.dropdown-menu-controls) { max-height: var(--bb-table-columnlist-max-height); diff --git a/src/BootstrapBlazor/wwwroot/modules/base-popover.js b/src/BootstrapBlazor/wwwroot/modules/base-popover.js index ad08a187f43..61d47ebb8e8 100644 --- a/src/BootstrapBlazor/wwwroot/modules/base-popover.js +++ b/src/BootstrapBlazor/wwwroot/modules/base-popover.js @@ -1,4 +1,4 @@ -import { getDescribedElement, getDescribedOwner, hackTooltip, hackPopover, isDisabled, registerBootstrapBlazorModule } from "./utility.js" +import { getDescribedElement, getDescribedOwner, hackTooltip, hackPopover, isDisabled, registerBootstrapBlazorModule } from "./utility.js" import EventHandler from "./event-handler.js" const Popover = { @@ -74,7 +74,7 @@ const Popover = { popover.triggerHideCallback = () => { if (popover.hideCallback) { popover.hideCallback(); - }; + } } if (popover.isPopover) { diff --git a/test/UnitTest/Components/TableTest.cs b/test/UnitTest/Components/TableTest.cs index 602cc7aff1d..8fc51946753 100644 --- a/test/UnitTest/Components/TableTest.cs +++ b/test/UnitTest/Components/TableTest.cs @@ -747,7 +747,7 @@ public async Task ShowColumnList_Ok() pb.Add(a => a.RenderMode, TableRenderMode.Table); pb.Add(a => a.ShowToolbar, true); pb.Add(a => a.ShowColumnList, true); - pb.Add(a => a.IsPopoverToolbarDropdownButton, true); + pb.Add(a => a.IsPopoverToolbarDropdownButton, false); pb.Add(a => a.AllowResizing, true); pb.Add(a => a.ShowColumnWidthTooltip, true); pb.Add(a => a.ColumnWidthTooltipPrefix, "test"); @@ -775,6 +775,7 @@ public async Task ShowColumnList_Ok() }); }); cut.Contains("Test_Column_List"); + cut.DoesNotContain("dropdown-menu-popover"); var item = cut.FindComponents>()[0]; await cut.InvokeAsync(item.Instance.OnToggleClick); @@ -782,6 +783,13 @@ public async Task ShowColumnList_Ok() await cut.InvokeAsync(item.Instance.OnToggleClick); Assert.False(show); + + var table = cut.FindComponent>(); + table.Render(pb => + { + pb.Add(a => a.IsPopoverToolbarDropdownButton, true); + }); + table.Contains("dropdown-menu-popover"); } [Fact]