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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: FluentAutocomplete does not have an ElementReference #1226

Closed
aco-mreble opened this issue Dec 27, 2023 · 4 comments
Closed

fix: FluentAutocomplete does not have an ElementReference #1226

aco-mreble opened this issue Dec 27, 2023 · 4 comments

Comments

@aco-mreble
Copy link
Contributor

馃悰 Bug Report

I want to set focus on a FluentAutocomplete control. Unfortunately the Element property won't be set correctly

馃捇 Repro or Code Sample

@page "/test"

<FluentAutocomplete
    @ref="AutocompleteReference"
    TOption="string"
    AutoComplete="off"
    Width="250px"
    OnOptionsSearch="@OnSearchAsync"
    MaximumSelectedOptions="1"
    @bind-SelectedOptions="@SelectedItems"/>

<p>
    <b>Selected</b>: @(String.Join(" - ", SelectedItems))
</p>

@code
{
    public FluentAutocomplete<string> AutocompleteReference { get; set; }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
            //This will fail: System.InvalidOperationException: ElementReference has not been configured correctly.
            //Element.Id and Element.Context are null
            await AutocompleteReference.Element.FocusAsync();
    }

    IEnumerable<string> SelectedItems = Array.Empty<string>();

    private async Task OnSearchAsync(OptionsSearchEventArgs<string> e)
    {
        var allCountries = new string[] { "germany, usa, france, sweden" };
        e.Items = allCountries.Where(i => i.StartsWith(e.Text, StringComparison.OrdinalIgnoreCase))
            .Order();
    }
}

馃 Expected Behavior

It should create a valid ElementReference for the Element Property

馃槸 Current Behavior

No ElementReference will be set.
Exception

System.InvalidOperationException: ElementReference has not been configured correctly.
at Microsoft.AspNetCore.Components.ElementReferenceExtensions.GetJSRuntime(ElementReference elementReference)
at Microsoft.AspNetCore.Components.ElementReferenceExtensions.FocusAsync(ElementReference elementReference, Boolean preventScroll)
at ACO.Smart.Frontend.Blazor.Components.Pages.Remove.OnAfterRenderAsync(Boolean firstRender) in

馃拋 Possible Solution

It would be also nice and probably even better if FluentAutocomplete would implement FocusAsync method like #157

馃實 Your Environment

.net 8 and FluentUi 4.2.1

@aco-mreble
Copy link
Contributor Author

aco-mreble commented Dec 28, 2023

For anyone interested in the Foucs method, here is a workaround:

public class MyAutoComplete<TOption> : FluentAutocomplete<TOption> where TOption : notnull
{
	[Inject] private IJSRuntime JsRuntime { get; set; } = default!;

        //only call after rendered (e.g. in OnAfterRender)
	public async Task Focus()
	{
		ArgumentNullException.ThrowIfNull(Id);
		await OnDropDownExpandedAsync();// this will open the menu
		await JsRuntime.FocusElementById(Id);// this will focus the input
		await InvokeAsync(StateHasChanged);// this will notify blazor that the element has changed
	}
}
//...
public static class JsRuntimeExtensions
{
	public static async Task FocusElementById(this IJSRuntime jsRuntime, string id)
	{
		var element = await jsRuntime.InvokeAsync<IJSObjectReference>("document.getElementById", id);
		await element.InvokeVoidAsync("focus");
	}
}

and then in your razor file just use MyAutoComplete instead of FluentAutoComplete

@aco-mreble aco-mreble changed the title fix: FluentAutocomplete does not have a ElementReference fix: FluentAutocomplete does not have an ElementReference Dec 28, 2023
@vnbaaij
Copy link
Collaborator

vnbaaij commented Dec 28, 2023

Hi Max,

This isn't working at the moment because the @ref gets created on the FluentAutoComplete component itself where in this case you want to target the FluentTextFiled inside the autocomplete. I have a fix for that and am checking with @dvoituron if it meets our standards. If it does, we will include it in the next release and then you can just keep on using

 if (firstRender)
     AutocompleteReference?.Element?.FocusAsync();

(Both AutocompleteReference and Element are nullable in this case. FocusAsync is declared as async void and does not have to be awaited. Itwill be made proper async Task in next major)

@kzu
Copy link

kzu commented Jan 9, 2024

Would be great to get milestones attached to issues to know when a given fix has shipped. Thanks! 馃檹

@vnbaaij
Copy link
Collaborator

vnbaaij commented Jan 10, 2024

I've added two milestones (for now):
image

Let's see how well we are going to tag issues...

vnbaaij added a commit that referenced this issue Jan 17, 2024
Fix #1226: Add Element to AutoComplete TextField
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants