To enable directory upload, certain new APIs are needed which are outlined in the directory upload spec proposal. There are two ways we can upload files and directories: a file input with the "directory" attribute, or an element with a drop event listener. Below are examples of these methods in action using the new APIs (the polyfill only works in Chrome).
<input type="file" id="fileInput" allowdirs multiple />
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function(event) {
document.getElementById('fileInput').addEventListener('change', function() {
var uploadFile = function(file, path) {
console.log(path, file);
// handle file uploading
};
var iterateFilesAndDirs = function(filesAndDirs, path) {
for (var i = 0; i < filesAndDirs.length; i++) {
if (typeof filesAndDirs[i].getFilesAndDirectories === 'function') {
var path = filesAndDirs[i].path;
// this recursion enables deep traversal of directories
filesAndDirs[i].getFilesAndDirectories().then(function(subFilesAndDirs) {
// iterate through files and directories in sub-directory
iterateFilesAndDirs(subFilesAndDirs, path);
});
} else {
uploadFile(filesAndDirs[i], path);
}
}
};
// begin by traversing the chosen files and directories
if ('getFilesAndDirectories' in this) {
this.getFilesAndDirectories().then(function(filesAndDirs) {
iterateFilesAndDirs(filesAndDirs, '/');
});
}
});
});
</script>
<div id="dropDiv">Drag & drop your files here!</div>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function(event) {
document.getElementById('dropDiv').addEventListener('drop', function (e) {
e.stopPropagation();
e.preventDefault();
var uploadFile = function(file, path) {
console.log(path, file);
// handle file uploading
};
var iterateFilesAndDirs = function(filesAndDirs, path) {
for (var i = 0; i < filesAndDirs.length; i++) {
if (typeof filesAndDirs[i].getFilesAndDirectories === 'function') {
var path = filesAndDirs[i].path;
// this recursion enables deep traversal of directories
filesAndDirs[i].getFilesAndDirectories().then(function(subFilesAndDirs) {
// iterate through files and directories in sub-directory
iterateFilesAndDirs(subFilesAndDirs, path);
});
} else {
uploadFile(filesAndDirs[i], path);
}
}
};
// begin by traversing the chosen files and directories
if ('getFilesAndDirectories' in e.dataTransfer) {
e.dataTransfer.getFilesAndDirectories().then(function(filesAndDirs) {
iterateFilesAndDirs(filesAndDirs, '/');
});
}
});
});
</script>