如何为列表的每个元素使用文件选项,并使用 jQuery 将其值传递给控制器

How to use file option for each elements of list, and pass its value into controllers using jQuery

我处于使用 Jquery 的初级水平。

问题:所以问题是,我必须为标签内的每个元素添加“选择文件”。并在标签内选择图像后显示图像。但是这是用于每个循环的元素列表,它不能在 id 属性 之间不同。 请查看图片和代码以供参考并帮助我, 谢谢!!!

[.cshtml]
@if (Model.DailyMenuProducts != null && Model.DailyMenuProducts.Count > 0)
{
@for (int i = 0; i < Model.DailyMenuProducts.Count; i++)
{
 <li class="list-group-item">
    <input asp-for="@Model.DailyMenuProducts[i].IsChecked" type="checkbox" />
    <label asp-for="@Model.DailyMenuProducts[i].ProductId">  @Model.DailyMenuProducts[i].ProductName</label>
    <input type="hidden" asp-for="@Model.DailyMenuProducts[i].ProductId"/>
    <input type="hidden" asp-for="@Model.DailyMenuProducts[i].ProductName" asp-route-productId/>
        <div  class="uploadFile float-end">
            <label for="productImage">
                <img id="imageViewer" width="50" height="50" style="border: 1px solid #000000; cursor:pointer;" />
            </label>
            <input asp-for="@Model.DailyMenuProducts[i].ProductImage" asp-for-ProductId="@Model.DailyMenuProducts[i].ProductId" type="file" id="productImage" style="display:none; visibility:none" onchange="getImage(this.value);"/>
         </div>
</li>
}

[.js]

$(".uploadFile").on('change', function () {
        console.log('new file uploaded')
        //var array = $("#productImage").getIdArray();
        var file_data = $("#productImage").prop("files")[0];
        var files = event.target.files
        $("#imageViewer").attr("src", window.URL.createObjectURL(files[0]));
        var form_data = new FormData();
        var product_Id = (this.ProductId) ;
        var viewModel = { ProductId: product_Id, ProductImage: file_data};
        form_data.append("file", file_data);
        $.ajax({
            url: "/DailyMenuPlanner/AddPhoto",
            cache: false,
            contentType: false,
            processData: false,
            data: viewModel,
            type: 'post',
            success: function (result) {
                if (result.success == true) { alert("success!"); }
                else { alert("fail!"); }
            }
        });
        
    });

In this image you can see that each elements have choose file option, and i have selected image for the first one and so the image is reflecting there! but if i select image for 2nd element then it effect only for 1st element and image of 1st element will change not for the 2nd element

After applying the suggestion by @JerdineSabio & replaced 'id' with 'class' now each element getting image separatly but i want to use as file input

HTML id 属性应该是唯一的。在您的代码中,只有带有 id=productImage 的第一个元素被替换。

您可以使用 $(this).find(selector)。这将找到当前元素内的元素。

在下面的代码中,当前元素是 .uploadFile.find() 将在该元素内搜索。

$(".uploadFile").on("change", function () {
   var file_data = $(this).find("#productImage").prop("files")[0];
   ...
   $(this).find("#imageViewer").attr("src", window.URL.createObjectURL(files[0]));
   ...
}

如果上面的代码不行,就把id换成classes;

<img class="imageViewer" width="50" height="50" style="border: 1px solid #000000; cursor:pointer;" />
<input class="productImage" asp-for="@Model.DailyMenuProducts[i].ProductImage" asp-for-ProductId="@Model.DailyMenuProducts[i].ProductId" type="file" style="display:none; visibility:none" onchange="getImage(this.value);"/>

然后在您的脚本中,使用 class 名称而不是 id;

$(".uploadFile").on("change", function () {
   var file_data = $(this).find(".productImage").prop("files")[0];
   ...
   $(this).find(".imageViewer").attr("src", window.URL.createObjectURL(files[0]));
   ...
}

如果您想将您的标签用作文件输入,您可以向您的标签添加一个点击事件,以触发点击您的输入字段。

// add file-label to your class
<label class="file-label"></label>

// add this script to your js file
$(".file-label").click(function(){
   var parent = $(this).parent();
   var target = $(parent).find(".productImage");
   $(target).click();
});