Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(AutoComplete): improved the TriggerChange/TriggerFilter method to update CurrentValue #5531

Merged
merged 3 commits into from
Mar 6, 2025
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
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>9.4.6</Version>
<Version>9.4.7-beta01</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
56 changes: 36 additions & 20 deletions src/BootstrapBlazor/Components/AutoComplete/AutoComplete.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,82 +8,82 @@
namespace BootstrapBlazor.Components;

/// <summary>
/// AutoComplete 组件
/// AutoComplete component
/// </summary>
public partial class AutoComplete
{
/// <summary>
/// 获得 组件样式
/// Gets the component style
/// </summary>
private string? ClassString => CssBuilder.Default("auto-complete")
.AddClassFromAttributes(AdditionalAttributes)
.Build();

/// <summary>
/// 获得/设置 通过输入字符串获得匹配数据集合
/// Gets or sets the collection of matching data obtained by inputting a string
/// </summary>
[Parameter]
[NotNull]
public IEnumerable<string>? Items { get; set; }

/// <summary>
/// 获得/设置 自定义集合过滤规则 默认 null
/// Gets or sets custom collection filtering rules, default is null
/// </summary>
[Parameter]
public Func<string, Task<IEnumerable<string>>>? OnCustomFilter { get; set; }

/// <summary>
/// 获得/设置 图标
/// Gets or sets the icon
/// </summary>
[Parameter]
public string? Icon { get; set; }

/// <summary>
/// 获得/设置 加载图标
/// Gets or sets the loading icon
/// </summary>
[Parameter]
public string? LoadingIcon { get; set; }

/// <summary>
/// 获得/设置 匹配数据时显示的数量
/// Gets or sets the number of items to display when matching data
/// </summary>
[Parameter]
[NotNull]
public int? DisplayCount { get; set; }

/// <summary>
/// 获得/设置 是否开启模糊查询,默认为 false
/// Gets or sets whether to enable fuzzy search, default is false
/// </summary>
[Parameter]
public bool IsLikeMatch { get; set; }

/// <summary>
/// 获得/设置 匹配时是否忽略大小写,默认为 true
/// Gets or sets whether to ignore case when matching, default is true
/// </summary>
[Parameter]
public bool IgnoreCase { get; set; } = true;

/// <summary>
/// 获得/设置 获得焦点时是否展开下拉候选菜单 默认 true
/// Gets or sets whether to expand the dropdown candidate menu when focused, default is true
/// </summary>
[Parameter]
public bool ShowDropdownListOnFocus { get; set; } = true;

/// <summary>
/// 获得/设置 是否显示无匹配数据选项 默认 true 显示
/// Gets or sets whether to show the no matching data option, default is true
/// </summary>
[Parameter]
public bool ShowNoDataTip { get; set; } = true;

/// <summary>
/// IStringLocalizer 服务实例
/// IStringLocalizer service instance
/// </summary>
[Inject]
[NotNull]
private IStringLocalizer<AutoComplete>? Localizer { get; set; }

/// <summary>
/// 获得 获得焦点自动显示下拉框设置字符串
/// Gets the string setting for automatically displaying the dropdown when focused
/// </summary>
private string? ShowDropdownListOnFocusString => ShowDropdownListOnFocus ? "true" : null;

Expand Down Expand Up @@ -115,7 +115,7 @@ protected override void OnParametersSet()
}

/// <summary>
/// 鼠标点击候选项时回调此方法
/// Callback method when a candidate item is clicked
/// </summary>
private async Task OnClickItem(string val)
{
Expand All @@ -129,12 +129,15 @@ private async Task OnClickItem(string val)
private List<string> Rows => _filterItems ?? [.. Items];

/// <summary>
/// TriggerFilter 方法
/// TriggerFilter method
/// </summary>
/// <param name="val"></param>
[JSInvokable]
public override async Task TriggerFilter(string val)
{
// Store the current input value to prevent it from being overwritten
var currentInputValue = val;

if (OnCustomFilter != null)
{
var items = await OnCustomFilter(val);
Expand All @@ -157,20 +160,33 @@ public override async Task TriggerFilter(string val)
{
_filterItems = [.. _filterItems.Take(DisplayCount.Value)];
}
await TriggerChange(val);

// Use currentInputValue here instead of potentially stale val
CurrentValue = currentInputValue;

// Only trigger StateHasChanged if no binding is present
if (!ValueChanged.HasDelegate)
{
StateHasChanged();
}
}

/// <summary>
/// TriggerChange 方法
/// TriggerChange method
/// </summary>
/// <param name="val"></param>
[JSInvokable]
public override Task TriggerChange(string val)
{
CurrentValue = val;
if (!ValueChanged.HasDelegate)
// Only update CurrentValue if the value has actually changed
// This prevents overwriting the user's input
if (CurrentValue != val)
{
StateHasChanged();
CurrentValue = val;
if (!ValueChanged.HasDelegate)
{
StateHasChanged();
}
}
return Task.CompletedTask;
}
Expand Down