I understand that file upload is possible with Angular Js. But I researched and found no provisions for an entire folder to be uploaded. I am working on ASP.NET Core.
Is folder uploading possible with AngularJS. Alternatives are welcome as well. Also I am wondering what is the equivalent of FolderBrowserDialog in ASP.NET Core.
Modern browsers support the File and Directory Entries API which allows handling of directories (folders). At the time of writing, this works in Chrome, Firefox, Edge and Safari TP (no old IE support).
You have at least two ways to implement this (brownie points for doing both for best UX!).
Give the standard input
element the power to handle directories via the webkitdirectory
attribute:
<input
#folderInput
type="file"
(change)="filesPicked(folderInput.files)"
webkitDirectory
>
Note: the above HTML snippet assumes Angular 2+, but you can easily do the same thing in Angular 1
folderInput.files
will be a flat list of all files within the folder, no need to recursively walk the tree or anything like that. Just iterate through the files in a simple loop like this:
function filesPicked(files) {
for (let i = 0; i < files.length; i++) {
const file = files[i];
const path = file.webkitRelativePath.split('/');
// upload file using path
...
}
}
The property webkitRelativePath
, as the name suggests, contains a path of the file relative to the ancestor directory the user selected.
Another part of the same File and Directory Entries API is DataTransferItem.webkitGetAsEntry()
which returns a FileSystemFileEntry
or FileSystemDirectoryEntry
. If it's a directlry, you can read it via a FileSystemDirectoryReader
retrieved by calling FileSystemDirectoryEntry.createReader()
. Here's a brief example of handling the drop event:
function drop(event) {
const items = event.dataTransfer.items;
for (let i = 0; i < items.length; i++) {
const item = items[i];
if (item.kind === 'file') {
const entry = item.webkitGetAsEntry();
if (entry.isFile) {
return new Promise((resolve, reject) => {
entry.file(
file => {
resolve(file);
},
err => {
reject(err);
}
);
});
} else if (entry.isDirectory) {
const directoryReader = entry.createReader();
return new Promise((resolve, reject) => {
directoryReader.readEntries(
entries => {
resolve(entries);
},
err => {
reject(err);
}
);
});
}
}
}
}
My coworker wrote a short article explaining the approach in more detail (disclaimer: I work for that company).
Here's a fully working Plunkr demo from the article: https://plnkr.co/edit/rFC9Ln
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With