Skip to content

Commit

Permalink
refactor(AutoFill): add IsLikeMatch/IgnoreCase parameter (#5014)
Browse files Browse the repository at this point in the history
* feat: 增加 IsLikeMatch IgnoreCase 参数

* refactor: 增加 Value 空判断

* doc: 精简代码

* test: 增加单元测试

* test: 更新单元测试

* chore: 更新依赖 9.1.5

Co-Authored-By: Alex chow <[email protected]>
  • Loading branch information
ArgoZhang and densen2014 authored Jan 1, 2025
1 parent c9a3d03 commit a69614f
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
<PackageReference Include="BootstrapBlazor.Markdown" Version="9.0.0" />
<PackageReference Include="BootstrapBlazor.MaterialDesign" Version="9.0.0" />
<PackageReference Include="BootstrapBlazor.MaterialDesign.Extensions" Version="9.1.0" />
<PackageReference Include="BootstrapBlazor.MeiliSearch" Version="9.1.4" />
<PackageReference Include="BootstrapBlazor.MeiliSearch" Version="9.1.5" />
<PackageReference Include="BootstrapBlazor.Mermaid" Version="9.0.3" />
<PackageReference Include="BootstrapBlazor.MindMap" Version="9.1.1" />
<PackageReference Include="BootstrapBlazor.MouseFollower" Version="9.0.1" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
<div class="col-12 col-sm-6">
<BootstrapInputGroup>
<BootstrapInputGroupLabel DisplayText="AutoFill" />
<AutoFill TValue="Foo" Items="AufoFillItems" IsLikeMatch="true" OnGetDisplayText="@(foo => foo.Name ?? "")">
<AutoFill Items="AufoFillItems" IsLikeMatch="true" OnGetDisplayText="@(foo => foo.Name)">
<ItemTemplate>
<div class="d-flex">
<div>
Expand Down
22 changes: 21 additions & 1 deletion src/BootstrapBlazor/Components/AutoFill/AutoFill.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,18 @@ public partial class AutoFill<TValue>
[NotNull]
public int? DisplayCount { get; set; }

/// <summary>
/// 获得/设置 是否开启模糊查询,默认为 false
/// </summary>
[Parameter]
public bool IsLikeMatch { get; set; }

/// <summary>
/// 获得/设置 匹配时是否忽略大小写,默认为 true
/// </summary>
[Parameter]
public bool IgnoreCase { get; set; } = true;

/// <summary>
/// 获得/设置 获得焦点时是否展开下拉候选菜单 默认 true
/// </summary>
Expand Down Expand Up @@ -108,7 +120,7 @@ protected override void OnParametersSet()
LoadingIcon ??= IconTheme.GetIconByKey(ComponentIcons.LoadingIcon);

OnGetDisplayText ??= v => v?.ToString();
_displayText = OnGetDisplayText(Value);
_displayText = Value is null ? "" : OnGetDisplayText(Value);

FilterItems ??= Items?.ToList() ?? [];
}
Expand Down Expand Up @@ -139,6 +151,14 @@ public async Task TriggerOnChange(string val)
var items = await OnCustomFilter(val);
FilterItems = items.ToList();
}
else
{
var comparisionType = IgnoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
FilterItems = IsLikeMatch
? Items.Where(i => OnGetDisplayText(i)?.Contains(val, comparisionType) ?? false).ToList()
: Items.Where(i => OnGetDisplayText(i)?.StartsWith(val, comparisionType) ?? false).ToList();
}

if (DisplayCount != null)
{
FilterItems = FilterItems.Take(DisplayCount.Value).ToList();
Expand Down
75 changes: 69 additions & 6 deletions test/UnitTest/Components/AutoFillTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,33 +157,96 @@ public async Task OnSelectedItemChanged_Ok()
}

[Fact]
public void OnGetDisplayText_Ok()
public async Task OnGetDisplayText_Ok()
{
var cut = Context.RenderComponent<AutoFill<Foo>>(pb =>
{
pb.Add(a => a.Value, Model);
pb.Add(a => a.Items, Items);
pb.Add(a => a.OnGetDisplayText, foo => foo.Name);
pb.Add(a => a.Items, new List<Foo> { null!, new() { Name = "Test" } });
pb.Add(a => a.OnGetDisplayText, foo => foo?.Name);
});
var input = cut.Find("input");
Assert.Equal("张三 1000", input.Attributes["value"]?.Value);

cut.SetParametersAndRender(pb =>
{
pb.Add(a => a.OnGetDisplayText, null!);
});
await cut.InvokeAsync(() => cut.Instance.TriggerOnChange("t"));

cut.SetParametersAndRender(pb =>
{
pb.Add(a => a.IsLikeMatch, true);
});
await cut.InvokeAsync(() => cut.Instance.TriggerOnChange("t"));
}

[Fact]
public async Task DisplayCount_Ok()
public async Task IgnoreCase_Ok()
{
var items = new List<Foo>() { new() { Name = "task1" }, new() { Name = "Task2" }, new() { Name = "task3" }, new() { Name = "Task4" } };
var items = new List<Foo>() { new() { Name = "task1" }, new() { Name = "task2" }, new() { Name = "Task3" }, new() { Name = "Task4" } };
var cut = Context.RenderComponent<AutoFill<Foo>>(builder =>
{
builder.Add(a => a.Items, items);
builder.Add(a => a.DisplayCount, 2);
builder.Add(a => a.IgnoreCase, true);
builder.Add(a => a.OnGetDisplayText, foo => foo.Name);
});

await cut.InvokeAsync(() => cut.Instance.TriggerOnChange("t"));
var menus = cut.FindAll(".dropdown-item");
Assert.Equal(4, menus.Count);

cut.SetParametersAndRender(pb =>
{
pb.Add(a => a.DisplayCount, 2);
});
await cut.InvokeAsync(() => cut.Instance.TriggerOnChange("t"));
menus = cut.FindAll(".dropdown-item");
Assert.Equal(2, menus.Count);

cut.SetParametersAndRender(pb =>
{
pb.Add(a => a.IgnoreCase, false);
pb.Add(a => a.DisplayCount, null);
});
await cut.InvokeAsync(() => cut.Instance.TriggerOnChange("t"));
menus = cut.FindAll(".dropdown-item");
Assert.Equal(2, menus.Count);
}

[Fact]
public async Task IsLikeMatch_Ok()
{
var items = new List<Foo>() { new() { Name = "task1" }, new() { Name = "task2" }, new() { Name = "Task3" }, new() { Name = "Task4" } };
var cut = Context.RenderComponent<AutoFill<Foo>>(builder =>
{
builder.Add(a => a.Items, items);
builder.Add(a => a.IsLikeMatch, false);
builder.Add(a => a.OnGetDisplayText, foo => foo.Name);
});

await cut.InvokeAsync(() => cut.Instance.TriggerOnChange("t"));
var menus = cut.FindAll(".dropdown-item");
Assert.Equal(4, menus.Count);

cut.SetParametersAndRender(pb =>
{
pb.Add(a => a.DisplayCount, 2);
});
await cut.InvokeAsync(() => cut.Instance.TriggerOnChange("t"));
menus = cut.FindAll(".dropdown-item");
Assert.Equal(2, menus.Count);

cut.SetParametersAndRender(pb =>
{
pb.Add(a => a.IsLikeMatch, true);
pb.Add(a => a.DisplayCount, null);
});
await cut.InvokeAsync(() => cut.Instance.TriggerOnChange("a"));
menus = cut.FindAll(".dropdown-item");
Assert.Equal(4, menus.Count);
}

[Fact]
public void ShowDropdownListOnFocus_Ok()
{
Expand Down

0 comments on commit a69614f

Please sign in to comment.