I just started playing around with Blazor and I can already see the great potential of this new framework.
I'm wondering, though, how it will handle doing simple things like setting focus on an input control? For instance, after I handle a click event, I want to set the focus to a text input control. Do I have to use JQuery for something like that, or will Blazor have some built-in methods for that sort of thing?
Thanks
Update: I posted an answer below with an example of how to set the focus to a control by invoking a JavaScript function from the .Net code.
As of right now (Blazor 0.9.0) you create your JavaScript functions in the Index.html (or reference them from Index.html) and then in your Blazor page or component you call JsRuntime.InvokeAsync("functionName", parms);
https://docs.microsoft.com/en-us/aspnet/core/razor-components/javascript-interop
Blazor Server has as a built-in feature the maintenance of app code securely and privately on the server. In the client-side model (Blazor WebAssembly), the Blazor app, its dependencies, and the . NET runtime are downloaded to the browser, and the app is executed directly on the browser UI thread.
Blazor does not have support to manipulate DOM elements directly, but we can still achieve it by using JavaScript interop. By creating a reference to an element, we can send it as a parameter to the JavaScript method via interop.
EventCallback. A common scenario with nested components executes a parent component's method when a child component event occurs. An onclick event occurring in the child component is a common use case. To expose events across components, use an EventCallback.
Blazor is just the replacement (to be more precise "value addition") to JavaScript. It is a client-side only solution (but it might add some easy binding to ASP.NET in the future).
Still, it's completely based on HTML and CSS. C# is replacing the JS part using web assembly. So nothing has changed on how you access / modify HTML controls.
As of now (version 0.1.0) you have to rely on HTML DOM focus()
Method to do what you intend to do (yes you have to use JavaScript as of now :( ).
// Not tested code // This is JavaScript. // Put this inside the index.html. Just below <script type="blazor-boot"></script> <script> Blazor.registerFunction('Focus', (controlId) => { return document.getElementById(controlId).focus(); }); </script> //and then wrap it for calls from .NET: // This is C# public static object Focus(string controlId) { return RegisteredFunction.Invoke<object>("Focus", controlId); //object type is used since Invoke does not have a overload for void methods. Don't know why. //this will return undefined according to js specs }
For more information, you can refer to below.
If you want to improve the packaging of JS neatly, you can do something like this: https://stackoverflow.com/a/49521216/476609
public class BlazorExtensionScripts : Microsoft.AspNetCore.Blazor.Components.BlazorComponent { protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder) { builder.OpenElement(0, "script"); builder.AddContent(1, "Blazor.registerFunction('Focus', (controlId) => { document.getElementById(controlId).focus(); });"); builder.CloseElement(); } public static void Focus(string controlId) { RegisteredFunction.Invoke<object>("Focus", controlId); } }
then add this component to the root: (App.cshtml
):
<BlazorExtensionScripts></BlazorExtensionScripts> <Router AppAssembly=typeof(Program).Assembly />
I want to add a more up-to-date (as of 0.9.0) example of calling a JavaScript function to set the focus to another control after some event, like clicking on a button. This might be helpful for someone just starting out with Blazor (like me).
This example builds on the example code in the Blazor documentation "Build Your First Blazor Components App" at https://docs.microsoft.com/en-us/aspnet/core/tutorials/build-your-first-razor-components-app?view=aspnetcore-3.0
First, follow all the instructions in the documentation. When you have a working To-Do List page, then add the following:
<script> window.MySetFocus = (ctrl) => { document.getElementById(ctrl).focus(); return true; } </script>
@inject IJSRuntime JsRuntime;
async void Focus(string controlId) { var obj = JsRuntime.InvokeAsync<string>( "MySetFocus", controlId); }
void AddTodo() { if (!string.IsNullOrWhiteSpace(newTodo)) { todos.Add(new TodoItem { Title = newTodo }); newTodo = string.Empty; Focus("todoItem"); // this is the new code } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With