4

I have a component using an Blazor InputFile component as a sub-component.

When I select a file the OnChange handler is called as expected. However, if I select the same file twice the OnChange handler is not called again (which I guess is as intended since the selection did not change, however my use case needs this).

So, I figure if I can select a file and get a call to the OnChange handler and in the OnChange handler "reset" the selected file, then I should get a new call to the handler even if the same file is selected again.

I cant figure out how to reset the file selection in InputFile (sub)component. Calling this.StateHasChanged() in the handler doesn't cause the InputFile component to re-render.

Is this possible to do without JSInterop and manually setting the value-field of the DOM input element to "" (would that even work)?

My component:

@using stuff;

<div class="drag-drop-area">
    Drag and drop file here
    <InputFile OnChange="@OnInputFileChange"></InputFile>
</div>

@code {

    [Parameter]
    public String SomeParam { get; set; } = "";

    private async Task OnInputFileChange(InputFileChangeEventArgs e) {
        // do stuff with file

        // do _something_ here to reset InputFile

        this.StateHasChanged(); //<-- this doesn't cause InputFile re-render
    }

My attempts to do this so far includes:

  • Following various tips/tricks related to this. StateHasChanged(), i.e.
    • await Task.Delay(1);
    • await InvokeAsync(StateHasChanged);
  • Adding values to InputFile using AdditionalAttributes.Add(..) to see if that could force a re-render
  • Looked at dynamically adding the InputFile component using RenderFragment, but I cant pass the OnChanged param (handler) when creating a new instance of InputFile in code, which means I wont the a callback with InputFileChangeEventArgs
  • Looked at wrapping the InputFile in a EditForm to reset the form (Blazor EditForms apparently doesnt have reset functionality?)
  • [EDIT] Used both Task and void for OnInputFileChange
MSurrow
  • 851
  • 1
  • 7
  • 19

1 Answers1

0

Try using a conditional statement and render identical content under both conditions. Changing the conditional should force an update.

@if (@reviewMechanism == "IMPORT")
{
    <div>
        <u>Import</u>
        <br />
        <br />
        <div>

            <div class="btn  btn-sm" style="background-color: lightgray; margin-bottom: 5px; width: 250px; margin-left: 0px ">
                <span>
                    <button class="btn  btn-sm" style=" font: smaller; border: solid; border-color: gray; border-width: thin;  background-color: rgba(239, 239, 239, 1.00);  margin-left: 0px"
                            @onclick="DownloadTemplate">
                        Download
                    </button>
                    ReviewTemplate.csv
                </span>
            </div>
            <br />
            <div class="btn  btn-sm" style="font: smaller;  margin-bottom: 5px;  width: 250px ; background-color: lightgray;height: 40px">
                <InputFile OnChange="@LoadFiles" style=" margin-left: 10px"> Pick a File </InputFile>
            </div>
        </div>


    </div>
}
else if (@reviewMechanism == "IMPORT2")
{
    <div>
        <u>Import</u>
        <br />
        <br />
        <div>

            <div class="btn  btn-sm" style="background-color: lightgray; margin-bottom: 5px; width: 250px; margin-left: 0px ">
                <span>
                    <button class="btn  btn-sm" style=" font: smaller; border: solid; border-color: gray; border-width: thin;  background-color: rgba(239, 239, 239, 1.00);  margin-left: 0px"
                            @onclick="DownloadTemplate">
                        Download
                    </button>
                    ReviewTemplate.csv
                </span>
            </div>
            <br />
            <div class="btn  btn-sm" style="font: smaller;  margin-bottom: 5px;  width: 250px ; background-color: lightgray;height: 40px">
                <InputFile OnChange="@LoadFiles" style=" margin-left: 10px"> Pick a File </InputFile>
            </div>
        </div>


    </div>
}

When change desired:

    loadedFiles = new Dictionary<IBrowserFile, string>();


    if (reviewMechanism == "IMPORT")
    {
        reviewMechanism = "IMPORT2"; //force render
    }
    else
    {
        if (reviewMechanism == "IMPORT2") reviewMechanism = "IMPORT"; //force render
    }