There are a couple of ways to set focus on an element the Blazor native way. Here's one:
Create a class that derives from the InputBase<string>
which is the base class of InputText
with the same functionality of InputText. In short, copy the code of InputText to your newly created class, and add the necessary functionality. Here's the new class: TextBox.cs
public class TextBox : InputBase<string>
{
private ElementReference InputRef;
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
builder.OpenElement(0, "input");
builder.AddMultipleAttributes(1, AdditionalAttributes);
builder.AddAttribute(2, "class", CssClass);
builder.AddAttribute(3, "value", BindConverter.FormatValue(CurrentValue));
builder.AddAttribute(4, "onchange", EventCallback.Factory.CreateBinder<string>
(this, __value => CurrentValueAsString = __value, CurrentValueAsString));
builder.AddElementReferenceCapture(5, (value) => {
InputRef = value; } );
builder.CloseElement();
}
[Inject] IJSRuntime JSRuntime { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await JSRuntime.InvokeVoidAsync("exampleJsFunctions.focusElement", InputRef);
}
}
protected override bool TryParseValueFromString(string value, out string result, out string validationErrorMessage)
{
result = value;
validationErrorMessage = null;
return true;
}
}
}
Place this script at the bottom of the _Host.cshtml file, just below
<script src="_framework/blazor.server.js"></script>
<script>
window.exampleJsFunctions =
{
focusElement: function (element) {
element.focus();
}
};
</script>
Things to note:
1. Define an ElementReference variable to hold reference to the input element.
2. In the BuildRenderTree method I've added code to capture a reference to the
input element
3. Call the focusElement JavaScript function from the OnAfterRenderAsync method.
This is performed only once. Note that I cannot use the OnInitializedAsync
method which is executed only once, but the ElementReference variable may
contain null.
4. Note that you cannot run any of the forms components without EditForm...
IMPORTANT: Pressing Ctrl+F5, when your browser is in a minimized state may interfere with seeing the cursor in the text element.
Code for usage:
<EditForm Model="@employee" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<TextBox @bind-Value="@employee.Name"/>
<button type="submit">Submit</button>
</EditForm>
@code {
private Employee employee = new Employee();
private void HandleValidSubmit()
{
Console.WriteLine("OnValidSubmit");
}
public class Employee
{
public int ID { get; set; } = 1;
public string Name { get; set; } = "Nancy";
}
}