I am trying to get files from user using <input type="file"/>. Multiple files can be uploaded. After upload I have used this code I found on stack which allows me to show the uploaded images. Initially the code was to upload one image and show it.
For multiple display, I have tried to clone the main div element and assign a new id to it and using the FileReader object I have tried to assign src to image tag. This is my code.
HTML code :
<div id="picsContainer" style="display:flex;">
<div style="display:none;" id="showPic">
<img class="file-upload-image" src="#" id="imgTag0" alt="your image" />
<div class="image-title-wrap">
<button type="button" onclick="removeUpload()" class="remove-image">Remove <span class="image-title"> Image</span></button>
</div>
</div>
</div>
JS Code :
function previewImage(element){
if(element.files[0]){
console.log(element)
for(i=0;i<element.files.length;i++){
var main=document.getElementById("showPic");
var cloned=main.cloneNode(true)
const reader = new FileReader();
console.log(reader)
reader.readAsDataURL(element.files[i])
cloned.id="showPic"+i;
cloned.children[0].id=i;
reader.onload=()=>{
cloned.children[0].src=reader.result;
}
cloned.style.display="block";
document.getElementById("picsContainer").appendChild(cloned);
}
}
}
The function gets called at the time of image upload using onchange. Problem is that in this code only the last added clone element is showing the image preview and all the other elements before that are not even getting anything in their src attribute. It just shows a "#" in src attribute.
What am I doing wrong here?
FileList {0: File, 1: File, 2: File, length: 3}
0: File {name: 'Screenshot (4).png', lastModified: 1633166516919, lastModifiedDate: Sat Oct 02 2021 14:51:56 GMT+0530 (India Standard Time), webkitRelativePath: '', size: 716548, …}
1: File {name: 'Screenshot (5).png', lastModified: 1633166527063, lastModifiedDate: Sat Oct 02 2021 14:52:07 GMT+0530 (India Standard Time), webkitRelativePath: '', size: 511571, …}
2: File {name: 'Screenshot (6).png', lastModified: 1633166534410, lastModifiedDate: Sat Oct 02 2021 14:52:14 GMT+0530 (India Standard Time), webkitRelativePath: '', size: 649065, …}
length: 3
This is what I am seeing if I log the element.files in console
It seems to me that you might be overwriting your images array, but I can't say for sure without taking a look at the rest of your code.
My suggestion is instead of cloning the div, map your images array and create the components as needed.
Maybe something like this (ES6):
const previewImage = (element) => {
const container = document.GetElementById('picsContainer')
const reader = new FileReader();
return element.files.map((image, index) => {
// Create a new div
const newElement = document.createElement('div')
newElement.key = index
newElement.id = `showPic${index}`
newElement.style.display = 'block'
// Create the image component
const img = document.createElement('img')
newElement.appendChiled(img)
reader.readAsDataURL(image)
reader.onload = () => {
img.src = reader.result;
}
container.appendChild(newElement)
}
}
This should work, but if you get any errors let me know and I'll try to help you again. Also, instead of using file reader, you could create a blob for each new image and get a custom url for them.
UPDATE
Since your FileList is an object with each file key being a number, and a length at the end, you can adapt my solution like this:
const previewImage = (element) => {
const container = document.getElementById('picsContainer')
for (let i=0; i<element.files.FileList.length; i++){
const reader = new FileReader();
// Create a new div
const newElement= document.createElement('div')
newElement.key = i
newElement.id = `showPic${i}`
newElement.style.display = 'block'
// Create the image component
const img = document.createElement('img')
newElement.appendChild(img)
reader.readAsDataURL(element.files.FileList[i])
reader.onload = () => {
img.src = reader.result;
}
container.appendChild(newElement)
}
}
I'll leave the original solution since it should work for an array of files.