Directory Upload Demo

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).

1. File Input

Code Example

<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>

2. Drag & Drop

Drag & drop your files here!

Code Example

<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>

Output