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;
}
}
Try online: https://try.mudblazor.com/snippet/wumGuBvXQJffyjIA