I am at beginner level for using Jquery.
Problem : so the problem is that, I have to add "choose file" for each of the element's inside a tag. And display the image after selecting it inside the tag. But Has this is this list of elements using for each loop, it cannot different between the id property. please see the images and code for reference and help me out, Thank You !!!
[.cshtml]
@if (Model.DailyMenuProducts != null && Model.DailyMenuProducts.Count > 0)
{
@for (int i = 0; i < Model.DailyMenuProducts.Count; i )
{
<li >
<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 >
<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!"); }
}
});
});
CodePudding user response:
HTML id attribute should be unique. In your code, only the first element with id=productImage
is being replaced.
What you could do is use $(this).find(selector)
. This will find the element inside the current element.
In the code below, the current element is .uploadFile
and .find()
will search inside that element.
$(".uploadFile").on("change", function () {
var file_data = $(this).find("#productImage").prop("files")[0];
...
$(this).find("#imageViewer").attr("src", window.URL.createObjectURL(files[0]));
...
}
If the above code doesn't work, just replace the id with classes;
<img width="50" height="50" style="border: 1px solid #000000; cursor:pointer;" />
<input asp-for="@Model.DailyMenuProducts[i].ProductImage" asp-for-ProductId="@Model.DailyMenuProducts[i].ProductId" type="file" style="display:none; visibility:none" onchange="getImage(this.value);"/>
Then in your script, use the class name instead of id;
$(".uploadFile").on("change", function () {
var file_data = $(this).find(".productImage").prop("files")[0];
...
$(this).find(".imageViewer").attr("src", window.URL.createObjectURL(files[0]));
...
}
If you want to use your label as file input, you could add a click event to your label that triggers the click on your input field.
// add file-label to your class
<label ></label>
// add this script to your js file
$(".file-label").click(function(){
var parent = $(this).parent();
var target = $(parent).find(".productImage");
$(target).click();
});