Creating a dropzone to enable drag and drop file upload
7 mins read
This tutorial will show how to enable a particular div
(or any other tag) on a webpage to accept files that are dropped on them.
We all have encountered websites that allow us to upload files (mostly images) to their servers by directly dragging the file from some application (mainly file explorer of the OS) to a desginated area on the web page. This a replacement of the good old <input type="file" />
elements inside forms. Drag and drop is an HTML5 standard.
Browser support
- All of the modern browsers fully support drag and drop HTML5 API except IE (partially supported).
Getting started
As Drag n Drop is a new feature, we will also implement a fallback method to add support to older browsers so that users can upload files regardless of drag and drop is supported by their browsers or not.
We will create a function that will accept a DOM node and a callback function that is passed the list of files.
-
The signature of the function will be
makeDroppable(element, callback)
. -
Inside the
makeDroppable
function,- We will first create an ‘input’ element of type
file
. - Set its display to none so that it is not visible on the page.
- Add a listener to its
change
event that will call the functiontriggerCallback
discussed further - Append it to the
element
provided. - This is to implement a fallback method in browsers that do not support drag n drop. This will also provide an additional functionality that the users can click the
element
to add files if they want, instead of drag n drop.
- We will first create an ‘input’ element of type
Now, we will add listeners to the element
.
- The
dragover
event:- This event is called when files are being dragged over the
element
and are yet to be dropped. - We call the event’s
preventDefault
method to prevent the browser from triggering its default behavior, i.e, it will try to open the file directly. - We call
stopPropagation
method to prevent the event from bubbling up the DOM tree (this will prevent the triggering ofdragover
event of any of the parent ofelement
). - To add an effect to notify users that the
element
can accept files, we will add the classdragover
to it that will have a slight different styling (like background color).
- This event is called when files are being dragged over the
- The
dragleave
event:- This event is fired when something was being dragged on the
element
but has been taken out instead of being dropped. - We call both the
preventDefault
andstopPropagation
method as indragover
for the same reasons. - To notify that the files being dragged has been removed, we remove the class that we added in the
dragover
event so thatelement
can return to its initial styling.
- This event is fired when something was being dragged on the
- The
drop
event:- This event is fired when the files being dragged are finally dropped on the
element
. - We call both the
preventDefault
andstopPropagation
method as above. - We will then remove the
dragover
class to return theelement
to its inital style. - Now we call the
triggerCallback
function to handle the files.
- This event is fired when the files being dragged are finally dropped on the
- The
click
event:- Since the
input
element that we previously created is hidden on the page, we will addclick
event to theelement
so that we can trigger the file chooser window to allow users to choose files by browsing their file explorer instead of dragging and dropping. - We set the value of
input
to null. - Then we call the
input
’sclick
method to open the file chooser.
- Since the
- The
triggerCallback
function:- This function handles both the dropped files and the files selected through file chooser window.
- We first create a variable
files
that will have the list of files chosen and will be passed to thecallback
provided. - Then we check if the event that called this function has a
dataTransfer
object or not. - If it has, that means the files were selected by dropping them on
element
. We assign thee.dataTransfer.files
to thefiles
variable. - If there is no
dataTransfer
object, that means the files were selected through the file chooser window. So we assigne.target.files
to thefiles
variable. - Now we pass the
files
variable to thecallback
function provided. - The
files
variable passed to thecallback
is an array ofFile
objects. EachFile
object has the following main properties:lastModified
: Integer timestampname
: The name of the file.size
: Size of file in bytes.type
: Mime-type of the file. (For ex: image/png for png files)
Full code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
function makeDroppable(element, callback) {
var input = document.createElement('input');
input.setAttribute('type', 'file');
input.setAttribute('multiple', true);
input.style.display = 'none';
input.addEventListener('change', triggerCallback);
element.appendChild(input);
element.addEventListener('dragover', function(e) {
e.preventDefault();
e.stopPropagation();
element.classList.add('dragover');
});
element.addEventListener('dragleave', function(e) {
e.preventDefault();
e.stopPropagation();
element.classList.remove('dragover');
});
element.addEventListener('drop', function(e) {
e.preventDefault();
e.stopPropagation();
element.classList.remove('dragover');
triggerCallback(e);
});
element.addEventListener('click', function() {
input.value = null;
input.click();
});
function triggerCallback(e) {
var files;
if(e.dataTransfer) {
files = e.dataTransfer.files;
} else if(e.target) {
files = e.target.files;
}
callback.call(null, files);
}
}
Usage:
We use the makeDroppable
function like this:
- First create a
div
(or any other) element:<div class="droppable">Drop your files here.</div>
- Add style to the
div
:.droppable { background: #08c; color: #fff; padding: 100px 0; text-align: center; }
- Create another class
dragover
that will override the background of.droppable
..droppable.dragover { background: #00CC71; }
- Call the
makeDroppable
:
Uses:
This implementation can be used for several purposes:
- Showing a preview of image files (or videos) to the users
- Upload the file list to the server through ajax call.
- Read the files on the browser itself using
FileReader
(a topic for another tutorial).
Uploading the files through ajax (jQuery.ajax for simplicity)
The callback
function that we defined earlier simply logs the FileList
to console. We can modify that function to upload the dropped/selected files to the server.