Search code examples
asp.net-corefocusblazortypeahead.jsblazor-client-side

How to set focus on Blazor.Typeahead component?


I'm using the BlazorTypeahead component in my project. I would like to set focus on the typeahead textbox, but can't seem to figure out how to do it. Here's my page. The search and value changed methods work fine, so I'm leaving them out.

@page "/"
@using Microsoft.JSInterop
@using Microsoft.AspNetCore.Components
@inject IJSRuntime jsRuntime
@inject Blazored.LocalStorage.ILocalStorageService localStore

<BlazoredTypeahead SearchMethod="SearchMyModel" TItem="MyModel" TValue="MyModel" Value="SelectedMyModel" ValueChanged="MyModelChanged" ValueExpression="@(() => SelectedMyModel)" placeholder="My Model name..." @ref="NewElementHere">
    <SelectedTemplate>
        @context.Name
    </SelectedTemplate>
    <ResultTemplate>
        @context.Name (@context.AnotherProperty)
    </ResultTemplate>
</BlazoredTypeahead>
    
    
@code {
    //public BlazoredTypeahead<MyModel, MyModel> NewElementHere { get; set; }
    ElementReference NewElementHere;
    
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            // Focus the element
            await jsRuntime.InvokeAsync<object>("BlazorFocusElement", NewElementHere);
        }
    }
}

The index.html file has this script in the header.

window.BlazorFocusElement = (element) => {
    if (element instanceof HTMLElement) {
        element.focus();
    }
};

The code above produces the following compile time error:

Error CS0029 Cannot implicitly convert type 'Blazored.Typeahead.BlazoredTypeahead<MyModel, MyModel>' to 'Microsoft.AspNetCore.Components.ElementReference'

If I remove the ElementReference and instead enable [i.e., remove comment] the property in the @code, it'll build, but I get a runtime error An unhandled error has occurred. If I look in the web debugger console it says:

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100] Unhandled exception rendering component: Derived classes must implement it System.NotImplementedException: Derived classes must implement it


Solution

  • You can't apply ElementReference to component... BlazoredTypeahead is a component, so you can't do it. The author of the BlazoredTypeahead should have provided a way to do it... Review the methods and properties of this component. Perhaps this component provide such functionality via one of its attributes...

    In any case, you can't use the ElementReference here. But I guess you can still use JSInterop to set the focus, even if the input text you want to set focus to has no id attribute. Just look at the Html source, identify the input text element, and contrive a way to set the focus.

    Note that if you're using .Net 5.0, you can set the focus from Blazor.