Creating a drag drop upload area

Drag and drop functionality has traditionally been a pain for developers to support. But with advances in browser compatibility it is really easy to support.

Here we will look at a quick way to implement drag/drop uploads without any external libraries/code.

First off we need an area in which the user can drop files. This could be the entire page, or just a target area depending on your site. For this example we will use a div containing a file input:

<div class="area">
    <input type="file" id="upload" />
</div>

Now we want to style up the area to look like a dropzone by adding a dashed border and upload icon:

.area {
    width: 100%;
    height: 100%;
    position: absolute;
    border: 4px dashed #000;
    background-image: url("http://kmtlondon.com/img/upload.png");
    background-position: center;
    background-repeat: no-repeat;
    background-size: 64px 64px;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    filter: alpha(opacity=50);
    -khtml-opacity: 0.5;
    -moz-opacity: 0.5;
    opacity: 0.5;
    text-align: center;
}

.area:hover,
.area.dragging,
.area.uploading {
    filter: alpha(opacity=100);
    -khtml-opacity: 1;
    -moz-opacity: 1;
    opacity: 1;
}

Next we need to use the form input for uploads, but hide the buttons so we can use our custom icon:

.area input {
    width: 400%;
    height: 100%;
    margin-left: -300%;
    border: none;
    cursor: pointer;
}

.area input:focus {
    outline: none;
}

Now some vanilla javascript to bring the form input to life:

var upload = document.getElementById('upload');

function onFile() {
    var me = this,
        file = upload.files[0],
        name = file.name.replace(/\.[^/.]+$/, '');
    console.log('upload code goes here', file, name);
}

upload.addEventListener('dragenter', function (e) {
    upload.parentNode.className = 'area dragging';
}, false);

upload.addEventListener('dragleave', function (e) {
    upload.parentNode.className = 'area';
}, false);

upload.addEventListener('dragdrop', function (e) {
    onFile();
}, false);

upload.addEventListener('change', function (e) {
    onFile();
}, false);

If you would like to add file size/type checking, you can use the following code inside your upload function:

if (file.type === 'audio/mp3' || file.type === 'audio/mpeg') {
    if (file.size < (3000 * 1024)) {
        upload.parentNode.className = 'area uploading';
    } else {
        window.alert('File size is too large, please ensure you are uploading a file of less than 3MB');
    }
} else {
    window.alert('File type ' + file.type + ' not supported');
}

Here is an example with the code running:

http://jsfiddle.net/kmturley/xf4vLyew/