Reputation: 1100
After selecting the files with this,
<input type="file" id="myfile1" name="myfile1" data-preview="preview1"
onchange="readURL(this);" accept="image/*" multiple />
read method should dynamically create the img
tag and view the image uploaded,
function readURL(input) {
if (input.files && input.files.length > 0) {
var index, reader3, file;
for (index = 0; index < input.files.length; index++) {
file = input.files[index];
console.log(file);
if (!!file.type.match(/image.*/)) {
if (window.FileReader) {
reader3 = new FileReader();
reader3.onloadend = function (e) {
$('#floor_plan_preview').append(
'' +
'<div class="col-12 ubw-outer">' +
'<div class="upload-btn-wrapper">' +
'<button class="btn" style="pointer-events: none;">' +
'<img src="" alt=""></button>' +
'<img alt="" id="preview' +
(index) +
'" class="preview"></div></div>'
);
$('#preview' + (index)).attr('src', e.target.result);
};
reader3.readAsDataURL(file);
console.log(index);
}
}
}
}
}
But this loops through files array as expected but only renders the img
tag with same id at every time.
It seems reader3.onloadend
function runs only once how can i fix this ?
Thanks in advance.
Upvotes: 0
Views: 39
Reputation: 10873
The issue here is that when onloaded
callback is executed, the value of index will always be the last one in the loop. To fix that you can wrap the callback into IIFE (Immediately Invoked Function Expression):
function readURL(input) {
if (input.files && input.files.length > 0) {
var index, reader3, file;
for (index = 0; index < input.files.length; index++) {
file = input.files[index];
if (!!file.type.match(/image.*/)) {
if (window.FileReader) {
reader3 = new FileReader();
(function(index) { // wrap the callback into IIFE
reader3.onloadend = function(e) {
$('#floor_plan_preview').append(
'' +
'<div class="col-12 ubw-outer">' +
'<div class="upload-btn-wrapper">' +
'<button class="btn" style="pointer-events: none;">' +
'<img src="" alt=""></button>' +
'<img alt="" id="preview' +
(index + 5) +
'" class="preview"></div></div>'
);
$('#preview' + (index + 5)).attr('src', e.target.result);
};
}(index)) // Pass the current index as an arg, so its value is up-to-date
reader3.readAsDataURL(file);
console.log(index);
}
}
}
}
}
Here's a helpful discussion about this issue in general: JavaScript closure inside loops – simple practical example.
Upvotes: 1