Home > Software design >  Mudblazor - How to use InputFile on a MudTable?
Mudblazor - How to use InputFile on a MudTable?

Time:07-20

I am trying to add an image upload functionality for each element of a list of objects displayed using MudTable. Here's how I tried doing it:

<MudTable Items="Data" Dense="true">
    <HeaderContent>
        <MudTh>Value</MudTh>
        <MudTh>Image</MudTh>
        <MudTh>Delete</MudTh>
    </HeaderContent>
    <RowTemplate Context="aa">
        <MudTd DataLabel="Value">
            <MudTextField @bind-Value="@aa.Value" For="@(()=>aa.Value)" HelperText="Required" />
        </MudTd>
        <MudTd DataLabel="Image">
            <div>
                <MudImage Src="@aa.ImageBase64" Height="50" Width="50" Elevation="25" Class="rounded my-2"></MudImage>
                <InputFile id="fileInput" OnChange="@((e)=> OnFileChange(aa,e))" hidden multiple accept=".jpg, .jpeg, .png"/>
                <MudButton HtmlTag="label"
                       Variant="Variant.Filled" Color="Color.Primary"
                       StartIcon="@Icons.Filled.CloudUpload"
                       for="fileInput">
                    Upload Image
                </MudButton>
            </div>
        </MudTd>
        <MudTd>
            <MudIconButton OnClick="@(()=>DeleteAnswer(aa))" Icon="@Icons.Filled.Delete" />
        </MudTd>
    </RowTemplate>
</MudTable>

The thing with the File Upload implementation of Mudblazor is that it uses a hidden InputFile with a specific id. So if I placed it on a table, the instance of that InputFile will only be valid for the 1st element, so if the Upload Image Button for the 2nd element is clicked, the one being modified will be the 1st element, not the current second element.

I know I should place the InputFile outside of the MudTable but the thing is, I need to pass the instance of each element on the OnChange event of the InputFile. An alternative I was thinking of is to not link the Upload Image Button with the InputFile but to pass the instance of the current element to a variable when the button is clicked instead. then call the click event of the hidden InputFile manually. But I'd like to avoid that so are there any suggestions on how to do this better?

CodePudding user response:

You could define a InputFile for each of your row items in your table. Just be sure to use unique id and for values:

<RowTemplate>
  ...
  <MudTd DataLabel="Image">
    <InputFile
      id="@($"file-{context.Id}")"
      OnChange="@(e => this.UploadFiles(e, context))"
      hidden
      multiple />
    <MudFab
      HtmlTag="label"
      Color="@Color.Success"
      Icon="@Icons.Filled.AttachFile"
      Size="@Size.Small"
      for="@($"file-{context.Id}")"/>
  </MudTd>
</RowTemplate>

A working demo:

<MudTable Items="@this.items" Class="mt-5">

  <HeaderContent>
    <MudTh>Id</MudTh>
    <MudTh>Name</MudTh>
    <MudTh>Images</MudTh>
    <MudTh></MudTh>
  </HeaderContent>

  <RowTemplate>
    <MudTd DataLabel="Id">
      @context.Id
    </MudTd>
    <MudTd DataLabel="Name">
      @context.Name
    </MudTd>
    <MudTd DataLabel="Images">
      @context.Images
    </MudTd>
    <MudTd DataLabel="Image">
      <InputFile
        id="@($"file-{context.Id}")"
        OnChange="@(e => this.UploadFiles(e, context))"
        hidden
        multiple />
      <MudFab
        HtmlTag="label"
        Color="@Color.Success"
        Icon="@Icons.Filled.AttachFile"
        Size="@Size.Small"
        for="@($"file-{context.Id}")"/>
    </MudTd>
  </RowTemplate>

</MudTable>

@code {
  private List<Item> items = new();
  private List<IBrowserFile> files = new();

  protected override void OnInitialized()
  {
    this.items = new List<Item>
    {
      new() { Id = "123", Name = "something" },
      new() { Id = "456", Name = "another" }
    };
  }

  private void UploadFiles(InputFileChangeEventArgs e, Item item)
  {
    item.Images = string.Join(", ", e.GetMultipleFiles().Select(f => f.Name));
  }

  public class Item
  {
    public string Id { get; set; }

    public string Name { get; set; }

    public string Images { get; set; } = string.Empty;
  }
}

enter image description here

Try online: https://try.mudblazor.com/snippet/wumGuBvXQJffyjIA

  • Related