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 @@ -6071,6 +6071,13 @@
<member name="M:Microsoft.FluentUI.AspNetCore.Components.FluentAutocomplete`1.InputHandlerAsync(Microsoft.AspNetCore.Components.ChangeEventArgs)">
<summary />
</member>
<member name="M:Microsoft.FluentUI.AspNetCore.Components.FluentAutocomplete`1.InvokeOptionsSearchAsync">
<summary>
Performs the search operation and displays the available values. The search takes into account any previously
entered text which has updated the <see cref="P:Microsoft.FluentUI.AspNetCore.Components.FluentAutocomplete`1.ValueText"/>.
</summary>
<returns></returns>
</member>
<member name="M:Microsoft.FluentUI.AspNetCore.Components.FluentAutocomplete`1.KeyDownHandlerAsync(Microsoft.FluentUI.AspNetCore.Components.FluentKeyCodeEventArgs)">
<summary />
</member>
Expand Down
41 changes: 25 additions & 16 deletions src/Core/Components/List/FluentAutocomplete.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -292,27 +292,37 @@ protected override async Task InputHandlerAsync(ChangeEventArgs e)
if (MaximumSelectedOptions > 0 && SelectedOptions?.Count() >= MaximumSelectedOptions)
{
IsReachedMaxItems = true;
RenderComponent();
await RenderComponentAsync();
return;
}

IsReachedMaxItems = false;
IsMultiSelectOpened = true;

var args = new OptionsSearchEventArgs<TOption>()
{
Items = Items ?? Array.Empty<TOption>(),
Text = ValueText,
};

if (ImmediateDelay > 0)
{
await _debounce.RunAsync(ImmediateDelay, () => InvokeAsync(() => OnOptionsSearch.InvokeAsync(args)));
await _debounce.RunAsync(ImmediateDelay, () => InvokeAsync(() => InvokeOptionsSearchAsync()));
}
else
{
await OnOptionsSearch.InvokeAsync(args);
await this.InvokeOptionsSearchAsync();
}
}

/// <summary>
/// Performs the search operation and displays the available values. The search takes into account any previously
/// entered text which has updated the <see cref="ValueText"/>.
/// </summary>
/// <returns></returns>
public async Task InvokeOptionsSearchAsync()
{
var args = new OptionsSearchEventArgs<TOption>()
{
Items = Items ?? Array.Empty<TOption>(),
Text = ValueText,
};

await OnOptionsSearch.InvokeAsync(args);

Items = args.Items?.Take(MaximumOptionsSearch);

Expand All @@ -325,14 +335,13 @@ protected override async Task InputHandlerAsync(ChangeEventArgs e)
await VirtualizationContainer.RefreshDataAsync();
}

RenderComponent();
await RenderComponentAsync();
}

// Activate the rendering
void RenderComponent()
{
_shouldRender = true;
StateHasChanged();
}
private async Task RenderComponentAsync()
{
_shouldRender = true;
await InvokeAsync(StateHasChanged);
}

private ValueTask<ItemsProviderResult<TOption>> LoadFilteredItemsAsync(ItemsProviderRequest request)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

<div class=" fluent-autocomplete-multiselect" style="width: 100%;" b-hg72r5b4ox="">
<fluent-text-field style="width: 100%; min-width: 100%;" placeholder="" id="xxx" value="" current-value="" appearance="outline" blazor:onchange="1" role="combobox" aria-expanded="true" aria-controls="myComponent-popup" aria-label="1-Denis Voituron (1 of 1)" blazor:onclick="2" blazor:oninput="3" blazor:elementreference="">
<svg slot="end" style="width: 16px; fill: var(--accent-fill-rest); cursor: pointer;" focusable="true" tabindex="0" role="button" viewBox="0 0 16 16" blazor:onkeydown="4" blazor:onclick="5" blazor:onfocus="6">
<title>Search</title>
<path d="M9.1 10.17a4.5 4.5 0 1 1 1.06-1.06l3.62 3.61a.75.75 0 1 1-1.06 1.06l-3.61-3.61Zm.4-3.67a3 3 0 1 0-6 0 3 3 0 0 0 6 0Z"></path>
</svg>
</fluent-text-field>
<div class="fluent-overlay" style="cursor: auto; position: fixed; display: flex; align-items: center; justify-content: center; z-index: 9900;" blazor:onclick="7" blazor:oncontextmenu="8" blazor:oncontextmenu:preventdefault="" b-xkrr7evqik="">
<div b-xkrr7evqik=""></div>
</div>
<fluent-anchored-region anchor="xxx" horizontal-positioning-mode="dynamic" horizontal-default-position="right" horizontal-inset="" horizontal-threshold="0" horizontal-scaling="content" vertical-positioning-mode="dynamic" vertical-default-position="unset" vertical-threshold="0" vertical-scaling="content" auto-update-mode="auto" style="z-index: 9999;" b-2ov9fhztky="" blazor:elementreference="">
<div style="z-index: 9999; background-color: var(--neutral-layer-floating); box-shadow: var(--elevation-shadow-flyout); margin-top: 10px; border-radius: calc(var(--control-corner-radius) * 2px); background-color: var(--neutral-layer-floating);" b-2ov9fhztky="">
<div id="xxx" role="listbox" style="width: 100%;" tabindex="0" b-hg72r5b4ox="">
<fluent-option id="xxx" value="1-Denis Voituron" blazor:onclick="9" aria-selected="true" selectable="" blazor:elementreference="">1-Denis Voituron</fluent-option>
</div>
</div>
</fluent-anchored-region>
</div>
30 changes: 30 additions & 0 deletions tests/Core/List/FluentAutocompleteTests.razor
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,36 @@
cut.Verify();
}

[Fact]
public async Task FluentAutocomplete_InvokeSearchOptions()
{
// Arrange
FluentAutocomplete<Customer> fluentAutoComplete = default!;

var externalSearchString = string.Empty;
var customers = Customers.Get();

async Task OnSearchValueChanged(OptionsSearchEventArgs<Customer> e)
{
e.Items = customers;
if (!string.IsNullOrWhiteSpace(externalSearchString))
e.Items = customers.Where(x => x.Name.Contains(externalSearchString));
}

var cut = Render(@<FluentAutocomplete Id="myComponent" @ref=fluentAutoComplete OnOptionsSearch="OnSearchValueChanged" TOption="Customer" />);

// Act
var input = cut.Find("fluent-text-field");
input.Click();

externalSearchString = "Denis";

await fluentAutoComplete.InvokeOptionsSearchAsync();

// Assert
cut.Verify();
}

[Theory()]
[InlineData("Escape")]
[InlineData("Backspace")]
Expand Down
Loading