Welcome to 2023! Where drag and drop file uploads are sane and easy. It might have actually come way before but I'm just discovering it now and it's pretty cool.
The first step is to set up an area that you will hook into for the drag events.
<div id="dropzone" ondrop="drop(event)" ondragover="dragover(event)">
<div>Drop files here!</div>
</div>
And some CSS so we can see the area:
#dropzone {
display: flex;
justify-content: center;
align-items: center;
height: 300px;
color: white;
background-color: rebeccapurple;
}
Now for the javascript:
async function drop(e) {
e.preventDefault();
let items = e.dataTransfer.items;
for (let item of items) {
if (item.kind !== "file") continue;
let file = item.getAsFile();
let formData = new FormData();
formData.append(file.name, file);
let response = await fetch("/uploads-1", {
method: "POST",
body: formData,
});
console.log(response);
}
}
function dragover(e) {
e.preventDefault();
}
We can capture the items and then loop over them. This is if we drop multiple files into the area. While looping, we can then add it to the form and submit it to our endpoint. This way as things are added, they are automatically uploaded.
One thing to note here is that the event name is mandatory which I found a bit weird. The dragover disabling is also important.
You can see a working example at:
https://nivethan.dev/workbooks/web/file-upload.html
Open the console to see the 404s being return from the fetch call. I also keep a list in the front end when something is dropped onto the drop zone.
Not sure if I'll make my file upload site yet, I'm not a fan of the idea and it does seem troublesome.
Writing this exact thing in sveltekit is very similar but there are differences which annoyed me. Though I could probably just use my raw logic instead of trying to do it the svelte way.