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
7 changes: 7 additions & 0 deletions src/BootstrapBlazor/Components/Select/Select.razor.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ export function hide(id) {
}
}

export function resetValue(id, value) {
const input = document.getElementById(id);
if (input) {
input.value = value;
}
}

export function dispose(id) {
const select = Data.get(id)
Data.remove(id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<div class="dropdown-toggle" data-bs-toggle="@ToggleString" data-bs-placement="@PlacementString" data-bs-offset="@OffsetString" data-bs-custom-class="@CustomClassString">
@if (DisplayTemplate != null)
{
<div id="@InputId" class="@InputClassString" tabindex="0">
<div id="@InputId" class="@InputClassString">
@DisplayTemplate(SelectedRow)
</div>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,11 @@ public partial class SelectGeneric<TValue> : ISelectGeneric<TValue>, IModelEqual

/// <summary>
/// 获得/设置 选项输入更新后转换为 Value 回调方法 默认 null
/// <para>返回值为 null 时放弃操作</para>
/// </summary>
/// <remarks>设置 <see cref="IsEditable"/> 后生效</remarks>
[Parameter]
public Func<string, Task<TValue>>? TextConvertToValueCallback { get; set; }
public Func<string, Task<TValue?>>? TextConvertToValueCallback { get; set; }

/// <summary>
/// 获得/设置 选项模板支持静态数据
Expand Down Expand Up @@ -486,17 +487,24 @@ private async Task OnChange(ChangeEventArgs args)

if (item == null)
{
TValue val = default!;
TValue? val = default;
if (TextConvertToValueCallback != null)
{
val = await TextConvertToValueCallback(v);
}
item = new SelectedItem<TValue>(val, v);

var items = new List<SelectedItem<TValue>>() { item };
items.AddRange(Items);
Items = items;
CurrentValue = val;
if (val is not null)
{
item = new SelectedItem<TValue>(val, v);
var items = new List<SelectedItem<TValue>>() { item };
items.AddRange(Items);
Items = items;
CurrentValue = val;
}
else
{
await InvokeVoidAsync("resetValue", InputId, SelectedRow?.Text);
}
}
else
{
Expand Down
21 changes: 19 additions & 2 deletions test/UnitTest/Components/SelectGenericTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -856,14 +856,31 @@ public async Task IsEditable_Ok()
});
pb.Add(a => a.TextConvertToValueCallback, v =>
{
return Task.FromResult(v);
return Task.FromResult(v)!;
});
});
Assert.False(input.IsReadOnly());

await cut.InvokeAsync(() => { input.Change("Test3"); });
Assert.Equal("Test3", cut.Instance.Value);
Assert.True(updated);

// 覆盖返回 null 逻辑
cut.SetParametersAndRender(pb =>
{
pb.Add(a => a.TextConvertToValueCallback, async v =>
{
await Task.Yield();
return null;
});
});
await cut.InvokeAsync(() => { input.Change("Test4"); });

cut.SetParametersAndRender(pb =>
{
pb.Add(a => a.Value, null);
});
await cut.InvokeAsync(() => { input.Change("Test5"); });
}

[Fact]
Expand All @@ -881,7 +898,7 @@ public async Task IsEditable_Generic()
pb.Add(a => a.IsEditable, true);
pb.Add(a => a.TextConvertToValueCallback, v =>
{
return Task.FromResult(new Foo() { Id = 3, Address = "Foo3" });
return Task.FromResult(new Foo() { Id = 3, Address = "Foo3" })!;
});
});

Expand Down