Reputation: 418
I have two elements, an InputFile and a button. And I want to simulate a click on InputFile upon clicking the button. I have it working with Js now but would like to know if there's a blazor way of doing it. An example gif
and this is the current blazor code
<InputFile id="filePicker" />
<button type="button" @onclick="OpenFilePicker">or Select</button>
private async Task OpenFilePicker() => await JsRuntime.InvokeVoidAsync("clickElement");
and with this Js code I can make it work though,
clickElement = () => document.getElementById('filePicker').click();
Is there a better solution without Js dependency ?
Upvotes: 14
Views: 12294
Reputation: 342
There actually is a pure C# solution that does not require adding any <script>
tag.
<InputFile id="filePicker" @ref="_filePicker" />
<button type="button" @onclick="OpenFilePicker">or Select</button>
@code {
private InputFile _filePicker;
private async Task OpenFilePicker()
=> await JsRuntime.InvokeVoidAsync("HTMLElement.prototype.click.call",
_filePicker.Element);
}
The key point of this trick is to use .call
to make the HTMLElement.prototype.click
member function static then pass the element reference back as the thisArg
.
There are some more details about this trick on this post.
Upvotes: 5
Reputation: 2907
I don't think it's possible to trigger a click event from blazor without using javascript.
You can use the ref directive to get a reference to an element from blazor but you'll still need javascrit to trigger the click on the element.
<InputFile @ref="filePicker"></InputFile>
<button type="button" @onclick="() => click()">Select a file</button>
<script>
window.triggerClick = (elt) => elt.click();
</script>
@code {
InputFile filePicker;
async Task click() {
await js.InvokeAsync<object>("triggerClick", filePicker.Element);
}
}
But since you're trying to trigger a click on an input there's a pure html way to do it using a label
<InputFile id="filePicker"></InputFile>
<label for="filePicker">
<button type="button" style="pointer-events: none;">Select a file</button>
</label>
Upvotes: 14