Blazor Autofocus on Input field

My use case is that when a data entry form is displayed I want the first input field to have the focus set on it.

In a straight HTML application you can just use the autofocus html attribute.  But as the writing of this post, Blazor does not support the autofocus attribute naturally or with using the @attribute dictionary assignment.  In order to meet this use case, we will need to use JSInterop.  This is a little disappointing but it does show the flexibility of Blazor.

To achieve the experience we want, we will use java-script to set the autofocus attribute on the input field we want.  We will create a function and pass in the CSS to look for.

In the java-script, we will use a selector to find the CSS class name passed in and then set the autofocus attribute:

    function focusInputFromBlazor(selector) {
        var input = document.querySelector(selector);
        if (!focusInput(input)) {
            input = input.querySelector("input");
            focusInput(input);
        }
    }

    function focusInput(input) {
        if (input && input.focus) {
            input.focus();
        }
        else {
            return false;
        }
    }

We will need to place the java-script file in the WWWRoot folder of the Blazor project.  We will then need to add the link to that file in the _Host.cshtml page  in a Blazor server application.  In the index.html page for a Blazor client application:

    <script src="/autofocus.js"></script>

On our razor form where we want to set the autofocus field we need to:
    1. Inject the JSRuntime:

        @inject IJSRuntime JsInterop

    2. Set the CSS class name to the value we will pass to the a unique value that we will be passing to the java-script to use.  You can use any class name you want, but it should be unique on the form:

        <InputText id="city" @bind-Value="city.City" class="defaultFocus" />

    3. In the code section, we will need to have a OnAfterRender method to call the java-script.  We need to call the script only on the firstRender so we can bind the attribute to the HTML Element:

      protected override async Task OnAfterRenderAsync(bool firstRender)
      {
          await base.OnAfterRenderAsync(firstRender);
          if (firstRender)
          {
              await JsInterop.InvokeVoidAsync("focusInputFromBlazor", new[] { ".defaultFocus" });
          }
      }

That all we need to do.  Now when the page is displayed, the City input field will show focus.



That will complete our use case and we have autofocus on our Blazor forms.


[Source Code]

Comments

Popular posts from this blog

Yes, Blazor Server can scale!

Blazor new and improved Search Box

Blazor Wizard Step Component