Uploading files is a common feature in modern web applications. Traditionally, file inputs have been implemented using the standard HTML element. In this article, you will see how to create a standard drag & drop file uploader user interface(UI) in javascript. Drag and drop upload makes it much easier for the user to upload the files.
Here to create a drag-and-drop uploader, we are going to use basic HTML, CSS, and Javascript.
Drag and drop meaning
Drag and drop is a method of moving computer files, images, videos, etc. from one place to another by clicking on them with the mouse and moving them across the screen. We can also say, Drag and drop is a functionality by which users can select an image or file and can move it to the desired location, and “drop” it there.
The following set of sequences is involved in the drag-and-drop process:
Move the pointer to the object (images, files, etc.)
Press, and hold down, the button on the mouse or other pointing device, to “grab” the object
“Drag” the object to the desired location by moving the pointer to this one
“Drop” the object by releasing the button
Drag and drop file upload HTML CSS
Here, we will create a drag-and-drop file upload user interface using basic HTML and CSS only.
Basic HTML
First of all, we define the basic HTML for file upload:
Let’s understand the above HTML,
Here we defined an upload container area to drop uploading files.
The HTML element is defined with an attribute type=»file» to hold the uploading file.
The HTML element is defined to submit the uploading files.
Drag and drop multiple file upload
We can also upload multiple files at a time using drag and drop. We just need to modify the to accept multiple files. We have to add the attribute «multiple» like the below code. The attribute multiple=»true» is defined to accept one or more than one file at a time.
Basic CSS for the file upload
Let’s define the basic CSS for the above HTML structure to provide the look and feel of the drag-and-drop file uploader.
Define the below CSS code in the tag of the HTML page:
Now we will use Javascript code to read the uploading files and submit them to upload.
Define the below javascript code in tag of the HTML page:
function uploadFiles() < var files = document.getElementById('file_upload').files; if(files.length==0)< alert("Please first choose or drop any file(s). "); return; >var filenames=""; for(var i=0;i alert("Selected file(s) :\n____________________\n"+filenames); >
The above-defined function uploadFiles() will be called to submit the uploading file when the user clicks on submit button.
Drag and drop file upload example with submit button
Now, we can put all code together in a single HTML page like the below filesupload.html file:
If you open the above HTML page in the browser it will look like the below image:
Live Demo
Conclusion
Implementing Drag & Drop and Browse file upload functionalities in JavaScript can significantly enhance the file uploading experience for users. While the Browse file upload is the standard method and works well in most cases, Drag & Drop adds a touch of interactivity and modernity.
You can use this UI to upload single as well as multiple files to the server by using any backend technologies such as Servlet, Spring boot, etc. Visit the link if you want to do file upload in Spring Boot, Spring Boot File Upload with Advance Progress bar in Ajax
Visit the link to do the file upload in Java Servlet, Ajax File Upload with Advance Progress Bar in Java
Simple Drag-and-Drop File Upload In JS HTML (Free Download)
Welcome to a quick tutorial on how to create a simple drag-and-drop file upload with Javascript and HTML. Forget those old boring “select a file” uploads. The Stone Age of the Internet is long over and it is time to create more exciting uploads. A drag-and-drop upload is actually not really that difficult to implement, and we can do it with just pure simple vanilla Javascript. Read on to find out how!
TABLE OF CONTENTS
JAVASCRIPT DRAG-AND-DROP UPLOAD
All right, let us now get into a demo and the details of how the drag-and-drop uploader works.
DRAG-DROP UPLOAD DEMO
For you guys who just want to use this as a “plugin”:
Captain Obvious, load the CSS and Javascript.
Define an empty to generate the uploader.
Use ddup.init() to attach the uploader.
target Required, HTML to generate the uploader.
action Required, server-side script that will be handling the upload.
data Optional, additional data to POST to the server.
size Optional, max allowed file size.
types Optional, allowed file extensions.
P.S. No actual upload will happen here, this demo will only show that drag-and-drop works.
< e.preventDefault(); e.stopPropagation(); instance.hzone.classList.add("highlight"); >; instance.hzone.ondragleave = e => < e.preventDefault(); e.stopPropagation(); instance.hzone.classList.remove("highlight"); >; // (A4) DROP TO UPLOAD FILE instance.hzone.ondragover = e => < e.preventDefault(); e.stopPropagation(); >; instance.hzone.ondrop = e => < e.preventDefault(); e.stopPropagation(); instance.hzone.classList.remove("highlight"); ddup.queue(instance, e.dataTransfer.files); >; >,
You already know this one, we call ddup.init() to attach the uploader to an HTML . A quick walkthrough:
(A1) Take extra note of the instance.upqueue and instance.uplock here, these are necessary for the upload queue later.
(A2) We generate 2 more sections within the target: .
The “dropzone”, drop files here to upload.
Upload status.
PART B) UPLOAD QUEUE
// (B) UPLOAD QUEUE // * AJAX IS ASYNCHRONOUS, UPLOAD QUEUE PREVENTS SERVER FLOOD queue : (instance, files) => < // (B1) PUSH FILES INTO QUEUE + GENERATE HTML ROW for (let f of files) < // (B1-1) CREATE HTML FILE ROW f.hstat = document.createElement("div"); f.hstat.className = "uprow"; f.hstat.innerHTML = `
bytes)
`; f.hbar = f.hstat.querySelector(".upbar"); f.hpercent = f.hstat.querySelector(".uppercent"); instance.hstat.appendChild(f.hstat); // (B1-2) FILE SIZE CHECK if (instance.size!=0 && f.size>instance.size) < f.hpercent.classList.add("bad"); f.hpercent.innerHTML = `Over upload limit of $bytes`; > // (B1-3) FILE TYPE CHECK else if (instance.types.length>0 && !instance.types.includes(f.name.split(".").pop().toLowerCase())) < f.hpercent.classList.add("bad"); f.hpercent.innerHTML = `File type not allowed`; >// (B1-4) CHECKS OK - ADD TO UPLOAD QUEUE else < instance.upqueue.push(f); >> // (B2) UPLOAD! ddup.go(instance); >,
Create the corresponding HTML file upload status.
Push the file into instance.upqueue , if it passes the checks.
The reason for this “gimmick” is simple – AJAX is asynchronous. It will be bad if the user drops hundreds of files, and the server has to handle hundreds of parallel uploads at once. So instead of a parallel upload, we will loop through instance.upqueue and upload one-by-one instead.
PART C) AJAX UPLOAD
// (C) AJAX UPLOAD go : instance => < if (!instance.uplock && instance.upqueue.length!=0) < // (C1) UPLOAD STATUS UPDATE instance.uplock = true; // (C2) PLUCK OUT FIRST FILE IN QUEUE let thisfile = instance.upqueue[0]; instance.upqueue.shift(); // (C3) UPLOAD DATA let data = new FormData(); data.append("upfile", thisfile); if (instance.data) < for (let [k, v] of Object.entries(instance.data)) < data.append(k, v); >> // (C4) AJAX UPLOAD let xhr = new XMLHttpRequest(); xhr.open("POST", instance.action); // (C5) UPLOAD PROGRESS let percent = 0, width = 0; xhr.upload.onloadstart = e => < thisfile.hbar.style.width = 0; thisfile.hpercent.innerHTML = "0%"; >; xhr.upload.onloadend = e => < thisfile.hbar.style.width = "100%"; thisfile.hpercent.innerHTML = "100%"; >; xhr.upload.onprogress = e => < percent = Math.ceil((e.loaded / e.total) * 100) + "%"; thisfile.hbar.style.width = percent; thisfile.hpercent.innerHTML = percent; >; // (C6) UPLOAD COMPLETE xhr.onload = function () < // (C6-1) ERROR if (this.response!= "OK" || this.status!=200) < thisfile.hpercent.innerHTML = this.response; >// (C6-2) NEXT BETTER PLAYER! else < thisfile.hbar.style.width = "100%"; thisfile.hpercent.innerHTML = "100%"; instance.uplock = false; ddup.go(instance); >>; // (C7) GO! xhr.send(data); >>
Lastly, the ddup.go() function is the one that does the actual upload. Nothing special here, just the good old AJAX. Also, remember using the uplock flag to restrict one at a time? Just take a small note of how the lock engages at the start of the function and unlocks when the upload ends.
DOWNLOAD & NOTES
Here is the download link to the example code, so you don’t have to copy-paste everything.
SUPPORT
600+ free tutorials & projects on Code Boxx and still growing. I insist on not turning Code Boxx into a «paid scripts and courses» business, so every little bit of support helps.
EXAMPLE CODE DOWNLOAD
Click here for the source code on GitHub gist, just click on “download zip” or do a git clone. I have released it under the MIT license, so feel free to build on top of it or use it in your own project.
EXTRA BITS & LINKS
That’s all for this tutorial, and here is a small section on some extras and links that may be useful to you.
HOW ABOUT THE SERVER SIDE!?
It’s all up to you to handle the upload on the server side, but if you are using PHP, here is a very simple upload handler:
FILE UPLOAD RESTRICTIONS
Yes, we can check the file size and extension in Javascript. But any experienced Code Ninja will be smart enough to open the developer’s console and change the Javascript. It is best to do the file checks on the server side as well.
COMPATIBILITY CHECKS
This drag-and-drop AJAX upload tutorial will work on all modern browsers.
LINKS & REFERENCES
HTML Drag and Drop API– MDN
AJAX Beginner’s Tutorial – Code-Boxx
Restrict Upload File Type In PHP – Code Boxx
Restrict Upload File Size In PHP – Code Boxx
Example On CodePen – Drag-Drop File Upload
THE END
Thank you for reading, and we have come to the end of this tutorial. I hope that it has solved your upload woes, and if you have anything to add to this guide, please feel free to comment below. Good luck and happy coding!
37 thoughts on “Simple Drag-and-Drop File Upload In JS HTML (Free Download)”
Hello! Tank you very much, is a awesome script. I trying to add click function on the drag and drop zone to browse for a file but I lost… ¿Can anyone help? Excuse my poor english… Thanks!!
Hi. Awesome code, managed to change the uploads destination too. Is there a way to validate filesize and filetype with this script? 😎
1) As above – . 2) We can also use Javascript to check the file size before uploading – Will add these in a future update. 3) But it’s better to do these checks on the server side.
Let me know if you are interested in a small task.
Hi there, and thank you for creating this very useful tool. I’ve just tried it out on a website I manage and it works perfectly. As expected, it uploads the files into the same directory that contains the dd-upload files.
I’m wondering if it would be possible for me to modify dd-upload.js so as to specify a different destination folder for the uploads. Example: I currently have all the dd-upload files in a directory called “upload_test”, which lives in the website’s root (“htdocs”) folder. I would like the script to deposit the uploaded files into a separate folder (called “weekly audio”), which is also in the “htdocs” folder.
I’m guessing that achieving this would involve me modifying/adding to the “C3 UPLOAD DATA” section, but I’m not sure what string of code to use. Whatever help you may be able to provide would be greatly appreciated.
Many thanks, Ken Cumberlidge Norwich, UK
EDIT: The entire widget has been rewritten.
But the server-side script is the one that controls where to save the uploaded file, not the Javascript. If you are using the above dummy PHP upload handler, just change $destination – https://www.php.net/manual/en/function.move-uploaded-file.php
Hi. Could you please expand on that reply. widget updated or code above? I’ve tried adding that code between various lines in the C3 category, but no luck.
Thank you for this tutorial I am not familiar with AJAX so I don’t understand even thought everything else seems to work fine, when it is integrated to a larger form with the same file handling the upload ( form action=”” ), when submitted, the content of the form appears duplicated, inside the original page as many time as there files to upload. Just like if submitting form target was in a new iframe for each file, instead of loading in a blank page. Is there a way to prevent that and have the form behave more conventionally ?
Don’t use iframe, such an outdated and confusing technique. Go back to the basics, don’t skip it.