I have to implement drag&drop upload with JS and Symphony. The backend part is not done by me and I have almost no control on it.
So far it uploads only the last files uploaded, either with drag&drop or through standard file input; what I need is that the user can upload files with both methods, then press the upload (submit) button and transfer all.
This is my HTML code:
<div id="drop-area">
<form id="dragAndDropForm" class="my-form" enctype="multipart/form-data" method="post" >
<section class="input-area">
<div class="input-area-upload">
<p>Upload multiple files with the file dialog or by dragging and dropping images onto the dashed region</p>
<input type="file" id="fileElem" multiple accept="image/*" name="images[]" onchange="handleFiles(this.files)">
<label class="button" for="fileElem">Select some files</label>
</div>
<input type="submit" class="submit" value="upload"/>
</section>
</form>
<div id="gallery"></div>
</div>
and this id my JS:
let dropArea = document.getElementById('drop-area');
let uploadInput = document.getElementById('fileElem');
let uploadArray = [];
const form = document.getElementById('dragAndDropForm');
let transferVar = document.getElementById('fileElem');
let formData = new FormData();
;['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
dropArea.addEventListener(eventName, preventDefaults, false)
})
function preventDefaults(e) {
e.preventDefault()
e.stopPropagation()
}
['dragenter', 'dragover'].forEach(eventName => {
dropArea.addEventListener(eventName, highlight, false)
});
['dragleave', 'drop'].forEach(eventName => {
dropArea.addEventListener(eventName, unhighlight, false)
});
function highlight(e) {
dropArea.classList.add('highlight')
}
function unhighlight(e) {
dropArea.classList.remove('highlight')
}
dropArea.addEventListener('drop', handleDrop, false);
function handleDrop(e) {
const uFiles = e.dataTransfer.files;
transferVar.files = uFiles;
handleFiles(uFiles)
}
function handleFiles(uFiles) {
uFiles = ([...uFiles])
/* uFiles.forEach(file => {
formData.append('images[]', file.name)
}) */
uFiles.forEach(previewFile)
}
function previewFile(file) {
let reader = new FileReader()
reader.readAsDataURL(file);
reader.onloadend = function() {
const enclosure = document.createElement('figure')
const img = document.createElement('img')
const ul = document.createElement('ul')
const fileProperties = {
"File name: ": file.name,
"File size: ": formatSize(file.size),
"File type: ": file.type
}
const fragment = document.createDocumentFragment();
img.src = reader.result;
fragment.appendChild(enclosure);
if (!uploadArray.includes(file.name)) {
enclosure.appendChild(img)
Object.keys(fileProperties).forEach((key) => {
const fragment_li = document.createElement('figcaption')
const fragment_span = document.createElement('span')
fragment_li.innerText = fileProperties[key]
fragment_span.innerText = key
enclosure.appendChild(fragment_li).prepend(fragment_span);
})
uploadArray.push(file.name)
} else {
return
}
document.getElementById('gallery').appendChild(fragment)
}
//console.log(uploadArray)
function formatSize(size) {
const units = [' B', ' Kb', ' Mb', ' Gb']
const divider = [1, 1024, Math.pow(2, 20), Math.pow(1024, 3)]
let multiplier = 0 ? 0 : Math.floor(Math.log(size) / Math.log(1024))
let output = +(size / divider[multiplier]).toFixed(multiplier === 0 ? 0 : multiplier - 1) + units[multiplier]
return output
}
}
I need to find a way to add to the dataTransfer both the files coming from Drag&Drop and from the upload input.
Thanks in advance for any help