Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,22 @@ private AttributeItem[] GetAttributes() =>
DefaultValue = "false"
},
new()
{
Name = nameof(Table<Foo>.IsKeepSelectedRows),
Description = Localizer["IsKeepSelectedRowsAttr"],
Type = "boolean",
ValueList = "true / false",
DefaultValue = "false"
},
new()
{
Name = nameof(Table<Foo>.IsKeepSelectedRowAfterAdd),
Description = Localizer["IsKeepSelectedRowAfterAddAttr"],
Type = "boolean",
ValueList = "true / false",
DefaultValue = "false"
},
new()
{
Name = "ClickToSelect",
Description = Localizer["ClickToSelectAttr"],
Expand Down
2 changes: 2 additions & 0 deletions src/BootstrapBlazor.Server/Locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -4894,6 +4894,8 @@
"IsTreeAttr": "Is it tree data",
"IsDetailsAttr": "Whether it is a detail row table, use DetailRowTemplate for logical judgment when not set",
"IsHideFooterWhenNoDataAttr": "Whether to show Footer when no data is available",
"IsKeepSelectedRowsAttr": "Whether to keep the selected row after switch page index",
"IsKeepSelectedRowAfterAddAttr": "Whether to keep the selected row after call add method",
"ClickToSelectAttr": "Click on the line to select the line",
"ShowCheckboxTextAttr": "Selection column that displays text",
"ShowFooterAttr": "Show feet",
Expand Down
2 changes: 2 additions & 0 deletions src/BootstrapBlazor.Server/Locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -4894,6 +4894,8 @@
"IsTreeAttr": "是否为树形数据",
"IsDetailsAttr": "是否为明细行表格,未设置时使用 DetailRowTemplate 进行逻辑判断",
"IsHideFooterWhenNoDataAttr": "无数据时是否显示 Footer",
"IsKeepSelectedRowsAttr": "翻页后是否保持选中行数据",
"IsKeepSelectedRowAfterAddAttr": "新建数据后是否保持选中行",
"ClickToSelectAttr": "点击行即选中本行",
"ShowCheckboxTextAttr": "显示文字的选择列",
"ShowFooterAttr": "是否显示表脚",
Expand Down
2 changes: 1 addition & 1 deletion src/BootstrapBlazor/BootstrapBlazor.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<Version>8.10.2-beta03</Version>
<Version>8.10.2-beta04</Version>
</PropertyGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
Expand Down
6 changes: 6 additions & 0 deletions src/BootstrapBlazor/Components/Table/Table.razor.Checkbox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ public partial class Table<TItem>
[Parameter]
public bool IsKeepSelectedRows { get; set; }

/// <summary>
/// 获得/设置 新建数据是否保持原选择行,默认为 false 不保持
/// </summary>
[Parameter]
public bool IsKeepSelectedRowAfterAdd { get; set; }

/// <summary>
/// 获得 表头行是否选中状态
/// </summary>
Expand Down
21 changes: 9 additions & 12 deletions src/BootstrapBlazor/Components/Table/Table.razor.Edit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -287,21 +287,18 @@ private async Task InternalOnAddAsync()
[Parameter]
public Func<TItem>? CreateItemCallback { get; set; }

private TItem CreateTItem()
private TItem CreateTItem() => CreateItemCallback?.Invoke() ?? CreateInstance();

private TItem CreateInstance()
{
var item = CreateItemCallback?.Invoke();
if (item == null)
try
{
try
{
item = Activator.CreateInstance<TItem>();
}
catch (Exception)
{
throw new InvalidOperationException($"{typeof(TItem)} missing new() method. Please provider {nameof(CreateItemCallback)} create the {typeof(TItem)} instance. {typeof(TItem)} 未提供无参构造函数 new() 请通过 {nameof(CreateItemCallback)} 回调方法创建实例");
}
return Activator.CreateInstance<TItem>();
}
catch (Exception)
{
throw new InvalidOperationException($"{typeof(TItem)} missing new() method. Please provider {nameof(CreateItemCallback)} create the {typeof(TItem)} instance. {typeof(TItem)} 未提供无参构造函数 new() 请通过 {nameof(CreateItemCallback)} 回调方法创建实例");
}
return item;
}

/// <summary>
Expand Down
8 changes: 6 additions & 2 deletions src/BootstrapBlazor/Components/Table/Table.razor.Toolbar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -486,8 +486,12 @@ public async Task AddAsync()
// 数据源为 DataTable 新建后重建行与列
await DynamicContext.AddAsync(SelectedRows.OfType<IDynamicObject>());
ResetDynamicContext();
SelectedRows.Clear();
await OnSelectedRowsChanged();

if (!IsKeepSelectedRowAfterAdd)
{
SelectedRows.Clear();
await OnSelectedRowsChanged();
}
}
else if (IsExcel)
{
Expand Down
33 changes: 31 additions & 2 deletions test/UnitTest/Components/TableTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ await cut.InvokeAsync(() =>
[Theory]
[InlineData(InsertRowMode.First)]
[InlineData(InsertRowMode.Last)]
public void Items_EditForm_Add(InsertRowMode insertMode)
public async Task Items_EditForm_Add(InsertRowMode insertMode)
{
var updated = false;
var localizer = Context.Services.GetRequiredService<IStringLocalizer<Foo>>();
Expand All @@ -206,7 +206,7 @@ public void Items_EditForm_Add(InsertRowMode insertMode)
});
});
var table = cut.FindComponent<Table<Foo>>();
_ = table.Instance.AddAsync();
await cut.InvokeAsync(table.Instance.AddAsync);
Assert.True(updated);
Assert.Equal(2, table.Instance.Rows.Count);
}
Expand Down Expand Up @@ -6046,6 +6046,35 @@ public async Task DynamicContext_Add()
await cut.InvokeAsync(() => delete.Instance.OnConfirm());
}

[Fact]
public async Task IsKeepSelectedRowAfterAdd_Ok()
{
var localizer = Context.Services.GetRequiredService<IStringLocalizer<Foo>>();
var items = Foo.GenerateFoo(localizer, 2);
var cut = Context.RenderComponent<BootstrapBlazorRoot>(pb =>
{
pb.AddChildContent<Table<DynamicObject>>(pb =>
{
pb.Add(a => a.RenderMode, TableRenderMode.Table);
pb.Add(a => a.IsMultipleSelect, true);
pb.Add(a => a.IsKeepSelectedRowAfterAdd, true);
pb.Add(a => a.DynamicContext, CreateDynamicContext(localizer));
});
});

var table = cut.FindComponent<Table<DynamicObject>>();

// 选中第一行数据
var input = cut.Find("tbody .form-check-input");
await cut.InvokeAsync(() => input.Click());
var selectedRow = table.Instance.SelectedRows.FirstOrDefault();
Assert.NotNull(selectedRow);

await cut.InvokeAsync(() => table.Instance.AddAsync());
selectedRow = table.Instance.SelectedRows.FirstOrDefault();
Assert.NotNull(selectedRow);
}

[Fact]
public async Task DynamicContext_Edit()
{
Expand Down