I need, in Blazor, get a reference to a component by its ID. Note: Not using ElementReference, as it is for generic code.
I've used this JS Interop script to do a focus and it works fine for me:
public async Task Focus(string elementId){
await js.InvokeVoidAsync("eval", $@"document.getElementById(""elementId}"").focus()");
}
But what I need from Blazor is get only a reference to the element (the component), that is, the return of: document.getElementById(""{elementId}"")
sending it elementId as a parameter.
Is it possible?
Edit: I've tried with this script but always returns null when calling it from Blazor:
<script>
window.GetElementById = (myId) => {
return document.getElementById(myId);
}
</script>
To specifically answer your question.
You're calling with InvokeVoidAsync which returns a void as you see. If you call with InvokeAsync you get an empty JsonDocument object returned.
So no, you can't get a usable reference back from the js call.
============================================================
If I read your question correctly, you want to set the focus to an html element id that you're generating "generically".
The answer below shows how to set the focus using either Element or id.
Add a site.js to wwwroot with the following code:
window.SetElementFocus = function (element) {
element.focus();
return element === true;
}
window.SetFocusByElementId = function (elementId) {
var element = document.getElementById(elementId);
element.focus();
return element === true;
}
Reference the js file in your startup file (this is for server)
<script src="/site.js"></script>
<script src="_framework/blazor.server.js"></script>
And then here's a demo page.
@page "/Test6"
<div class="m-2">
<input type="text" @ref="Input1" placeholder="Input 1" id="input1" />
</div>
<div class="m-2">
<input type="text" @ref="Input2" placeholder="Input 2" id="input2" />
</div>
<div class="m-2">
<input type="text" @ref="Input3" placeholder="Input 3" id="input3" />
</div>
<div class="m-2 p-2">
<button class="btn btn-dark me-1" @onclick="() => Focus(1)">Element Focus 1</button>
<button class="btn btn-dark me-1" @onclick="() => Focus(2)">Element Focus 2</button>
<button class="btn btn-dark me-1" @onclick="() => Focus(3)">Element Focus 3</button>
</div>
<div class="m-2 p-2">
<button class="btn btn-secondary me-1" @onclick="() => FocusById(1)">Id Focus 1</button>
<button class="btn btn-secondary me-1" @onclick="() => FocusById(2)">Id Focus 2</button>
<button class="btn btn-secondary me-1" @onclick="() => FocusById(3)">Id Focus 3</button>
</div>
@code {
[Inject] private IJSRuntime _js { get; set; }
private ElementReference Input1;
private ElementReference Input2;
private ElementReference Input3;
private async Task Focus(int no)
{
var input = no switch
{
1 => Input1,
2 => Input2,
_ => Input3
};
await _js.InvokeAsync<bool>("SetElementFocus", input);
}
private async Task FocusById(int no)
{
var input = no switch
{
1 => "input1",
2 => "input2",
_ => "input3"
};
await _js.InvokeAsync<bool>("SetFocusByElementId", input);
}
}
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