Drag and drop a file on label
The easiest way, is to append your input[type=file]
directly in your <label>
, and to style this input in a way it covers all the label.
Doing so, you'll be able to drop files directly on the label, and the input's default behavior will take care of it, ultimately, no js is needed in this part:
// only to show it did change
$('#image-event').on('change', function upload(evt) {
console.log(this.files[0]);
});
// only to show where is the drop-zone:
$('#image-event-label').on('dragenter', function() {
this.classList.add('dragged-over');
})
.on('dragend drop dragexit dragleave', function() {
this.classList.remove('dragged-over');
});
#image-event {
position: absolute;
top: 0;
left: 0;
opacity: 0;
width: 100%;
height: 100%;
display: block;
}
#image-event-label {
position: relative;
}
#image-event-label.dragged-over {
border: 1px solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="image-event" id="image-event-label">
Import an image
<input type="file" name="image-event" id="image-event">
</label>
Now, note that it is actually now* possible to set the .files
FileList of an input[type=file]
, but you need to set it to an other FileList object, and fortunately, there is one available in the DataTransfer object that comes along the DropEvent:
function handleDroppedFile(evt) {
evt.preventDefault();
// since we use jQuery we need to grab the originalEvent
var dT = evt.originalEvent.dataTransfer;
var files = dT.files;
if (files && files.length) {
// we set our input's 'files' property
$('#image-event')[0].files = files;
}
}
$('#image-event-label').on({
'drop': handleDroppedFile,
'dragenter': function(e) { e.preventDefault(); },
'dragover': function(e) {
e.preventDefault();
this.classList.add('dragged-over');
}
})
.on('dragleave dragexit', function() {
this.classList.remove('dragged-over')
});
.dragged-over {
border: 1px solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="image-event" id="image-event-label">
Drop a file here
</label> <br><br>
<input type="file" name="image-event" id="image-event">
*IIRC, this is now supported in Chrome, Safari, latests Edge and latests Firefox. I don't think IE does support it though, so beware when using this.