Uploading directory and maintainign structure through JavaScript and HTML5
I'm trying to upload whole folders through the browser. I've done a fair bit of tinkering today and discovered that there are a number of great solutions for uploading folders. However, when testing them, they seem to be making the list of files in the folders ready for upload, sans directory structure.
Is there any recommended tool I can use to drag and drop, or even just select and upload, entire folders from my site (and of course, maintain structure)?
javascript html5
add a comment |
I'm trying to upload whole folders through the browser. I've done a fair bit of tinkering today and discovered that there are a number of great solutions for uploading folders. However, when testing them, they seem to be making the list of files in the folders ready for upload, sans directory structure.
Is there any recommended tool I can use to drag and drop, or even just select and upload, entire folders from my site (and of course, maintain structure)?
javascript html5
add a comment |
I'm trying to upload whole folders through the browser. I've done a fair bit of tinkering today and discovered that there are a number of great solutions for uploading folders. However, when testing them, they seem to be making the list of files in the folders ready for upload, sans directory structure.
Is there any recommended tool I can use to drag and drop, or even just select and upload, entire folders from my site (and of course, maintain structure)?
javascript html5
I'm trying to upload whole folders through the browser. I've done a fair bit of tinkering today and discovered that there are a number of great solutions for uploading folders. However, when testing them, they seem to be making the list of files in the folders ready for upload, sans directory structure.
Is there any recommended tool I can use to drag and drop, or even just select and upload, entire folders from my site (and of course, maintain structure)?
javascript html5
javascript html5
asked Dec 21 '17 at 20:55
mjabraham
493618
493618
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Not really officially yet, but there will probably be, available for us mere web-developers* through the Files and Directory API which specs are still in the process of being written, even though chrome and Firefox already implement something similar through a webkit-API*, which allows us to access and navigate dropped directories.
So if we try to use this webkit-API, we could write something like this:
/* constructs a simple directory view from a filesystem */
async function makedir(entries) {
const systems = entries.map(entry => traverse(entry, {}));
return Promise.all(systems);
async function traverse(entry, fs) {
if (entry.isDirectory) {
fs[entry.name] = {};
let dirReader = entry.createReader();
await new Promise((res, rej) => {
dirReader.readEntries(async entries => {
for (let e of entries) {
await traverse(e, fs[entry.name]);
}
res();
}, rej);
});
} else if (entry.isFile) {
await new Promise((res, rej) => {
entry.file(file => {
fs[entry.name] = file;
res();
}, rej);
});
}
return fs;
}
}
function readDropped(dT) {
const entries = [...dT.items].map(item => {
return item.webkitGetAsEntry ? item.webkitGetAsEntry() : null;
})
.filter(entry => entry);
if (entries.length) {
makedir(entries)
.then(output)
.catch(handleSecurityLimitation);
} else notadir();
}
function notadir() {
_log.textContent = "wasn't a directory, or webkitdirectory is not supported";
}
dropzone.ondragover = e => {
e.preventDefault();
dropzone.classList.add('over');
}
dropzone.ondragexit = dropzone.ondragend = e => dropzone.classList.remove('over');
dropzone.ondrop = e => {
e.preventDefault();
dropzone.classList.remove('over');
readDropped(e.dataTransfer);
}
function output(system_trees) {
console.log(system_trees);
_log.textContent = JSON.stringify(system_trees, checkFile, 2);
function checkFile(key, value) {
if (value instanceof File) {
return '{[File] ' + value.name + ', ' + value.size + 'b}';
} else return value;
}
}
function handleSecurityLimitation(error) {
console.error(error);
document.body.innerHTML = `
<h2>Faced security limitations</h2>
<a href="https://jsfiddle.net/x85vtnef/">Please go to this fiddle</a>`;
}
#dropzone {
border: 1px solid;
width: 90vw;
height: 90vh;
margin: 2vmin;
padding: 2vmin;
overflow: auto;
}
#dropzone.over {
background-color: rgba(0, 0, 0, .2);
}
<div id="dropzone">
Drop some directory here.
<pre id="_log"></pre>
</div>
And as fiddle for chrome
*chrome code (extensions and plugins) generally already have access to a FileSystem API.
*"webkit-API" here means experimental, i.e which behavior may change any time and may not be the same on every browsers.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f47932586%2fuploading-directory-and-maintainign-structure-through-javascript-and-html5%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Not really officially yet, but there will probably be, available for us mere web-developers* through the Files and Directory API which specs are still in the process of being written, even though chrome and Firefox already implement something similar through a webkit-API*, which allows us to access and navigate dropped directories.
So if we try to use this webkit-API, we could write something like this:
/* constructs a simple directory view from a filesystem */
async function makedir(entries) {
const systems = entries.map(entry => traverse(entry, {}));
return Promise.all(systems);
async function traverse(entry, fs) {
if (entry.isDirectory) {
fs[entry.name] = {};
let dirReader = entry.createReader();
await new Promise((res, rej) => {
dirReader.readEntries(async entries => {
for (let e of entries) {
await traverse(e, fs[entry.name]);
}
res();
}, rej);
});
} else if (entry.isFile) {
await new Promise((res, rej) => {
entry.file(file => {
fs[entry.name] = file;
res();
}, rej);
});
}
return fs;
}
}
function readDropped(dT) {
const entries = [...dT.items].map(item => {
return item.webkitGetAsEntry ? item.webkitGetAsEntry() : null;
})
.filter(entry => entry);
if (entries.length) {
makedir(entries)
.then(output)
.catch(handleSecurityLimitation);
} else notadir();
}
function notadir() {
_log.textContent = "wasn't a directory, or webkitdirectory is not supported";
}
dropzone.ondragover = e => {
e.preventDefault();
dropzone.classList.add('over');
}
dropzone.ondragexit = dropzone.ondragend = e => dropzone.classList.remove('over');
dropzone.ondrop = e => {
e.preventDefault();
dropzone.classList.remove('over');
readDropped(e.dataTransfer);
}
function output(system_trees) {
console.log(system_trees);
_log.textContent = JSON.stringify(system_trees, checkFile, 2);
function checkFile(key, value) {
if (value instanceof File) {
return '{[File] ' + value.name + ', ' + value.size + 'b}';
} else return value;
}
}
function handleSecurityLimitation(error) {
console.error(error);
document.body.innerHTML = `
<h2>Faced security limitations</h2>
<a href="https://jsfiddle.net/x85vtnef/">Please go to this fiddle</a>`;
}
#dropzone {
border: 1px solid;
width: 90vw;
height: 90vh;
margin: 2vmin;
padding: 2vmin;
overflow: auto;
}
#dropzone.over {
background-color: rgba(0, 0, 0, .2);
}
<div id="dropzone">
Drop some directory here.
<pre id="_log"></pre>
</div>
And as fiddle for chrome
*chrome code (extensions and plugins) generally already have access to a FileSystem API.
*"webkit-API" here means experimental, i.e which behavior may change any time and may not be the same on every browsers.
add a comment |
Not really officially yet, but there will probably be, available for us mere web-developers* through the Files and Directory API which specs are still in the process of being written, even though chrome and Firefox already implement something similar through a webkit-API*, which allows us to access and navigate dropped directories.
So if we try to use this webkit-API, we could write something like this:
/* constructs a simple directory view from a filesystem */
async function makedir(entries) {
const systems = entries.map(entry => traverse(entry, {}));
return Promise.all(systems);
async function traverse(entry, fs) {
if (entry.isDirectory) {
fs[entry.name] = {};
let dirReader = entry.createReader();
await new Promise((res, rej) => {
dirReader.readEntries(async entries => {
for (let e of entries) {
await traverse(e, fs[entry.name]);
}
res();
}, rej);
});
} else if (entry.isFile) {
await new Promise((res, rej) => {
entry.file(file => {
fs[entry.name] = file;
res();
}, rej);
});
}
return fs;
}
}
function readDropped(dT) {
const entries = [...dT.items].map(item => {
return item.webkitGetAsEntry ? item.webkitGetAsEntry() : null;
})
.filter(entry => entry);
if (entries.length) {
makedir(entries)
.then(output)
.catch(handleSecurityLimitation);
} else notadir();
}
function notadir() {
_log.textContent = "wasn't a directory, or webkitdirectory is not supported";
}
dropzone.ondragover = e => {
e.preventDefault();
dropzone.classList.add('over');
}
dropzone.ondragexit = dropzone.ondragend = e => dropzone.classList.remove('over');
dropzone.ondrop = e => {
e.preventDefault();
dropzone.classList.remove('over');
readDropped(e.dataTransfer);
}
function output(system_trees) {
console.log(system_trees);
_log.textContent = JSON.stringify(system_trees, checkFile, 2);
function checkFile(key, value) {
if (value instanceof File) {
return '{[File] ' + value.name + ', ' + value.size + 'b}';
} else return value;
}
}
function handleSecurityLimitation(error) {
console.error(error);
document.body.innerHTML = `
<h2>Faced security limitations</h2>
<a href="https://jsfiddle.net/x85vtnef/">Please go to this fiddle</a>`;
}
#dropzone {
border: 1px solid;
width: 90vw;
height: 90vh;
margin: 2vmin;
padding: 2vmin;
overflow: auto;
}
#dropzone.over {
background-color: rgba(0, 0, 0, .2);
}
<div id="dropzone">
Drop some directory here.
<pre id="_log"></pre>
</div>
And as fiddle for chrome
*chrome code (extensions and plugins) generally already have access to a FileSystem API.
*"webkit-API" here means experimental, i.e which behavior may change any time and may not be the same on every browsers.
add a comment |
Not really officially yet, but there will probably be, available for us mere web-developers* through the Files and Directory API which specs are still in the process of being written, even though chrome and Firefox already implement something similar through a webkit-API*, which allows us to access and navigate dropped directories.
So if we try to use this webkit-API, we could write something like this:
/* constructs a simple directory view from a filesystem */
async function makedir(entries) {
const systems = entries.map(entry => traverse(entry, {}));
return Promise.all(systems);
async function traverse(entry, fs) {
if (entry.isDirectory) {
fs[entry.name] = {};
let dirReader = entry.createReader();
await new Promise((res, rej) => {
dirReader.readEntries(async entries => {
for (let e of entries) {
await traverse(e, fs[entry.name]);
}
res();
}, rej);
});
} else if (entry.isFile) {
await new Promise((res, rej) => {
entry.file(file => {
fs[entry.name] = file;
res();
}, rej);
});
}
return fs;
}
}
function readDropped(dT) {
const entries = [...dT.items].map(item => {
return item.webkitGetAsEntry ? item.webkitGetAsEntry() : null;
})
.filter(entry => entry);
if (entries.length) {
makedir(entries)
.then(output)
.catch(handleSecurityLimitation);
} else notadir();
}
function notadir() {
_log.textContent = "wasn't a directory, or webkitdirectory is not supported";
}
dropzone.ondragover = e => {
e.preventDefault();
dropzone.classList.add('over');
}
dropzone.ondragexit = dropzone.ondragend = e => dropzone.classList.remove('over');
dropzone.ondrop = e => {
e.preventDefault();
dropzone.classList.remove('over');
readDropped(e.dataTransfer);
}
function output(system_trees) {
console.log(system_trees);
_log.textContent = JSON.stringify(system_trees, checkFile, 2);
function checkFile(key, value) {
if (value instanceof File) {
return '{[File] ' + value.name + ', ' + value.size + 'b}';
} else return value;
}
}
function handleSecurityLimitation(error) {
console.error(error);
document.body.innerHTML = `
<h2>Faced security limitations</h2>
<a href="https://jsfiddle.net/x85vtnef/">Please go to this fiddle</a>`;
}
#dropzone {
border: 1px solid;
width: 90vw;
height: 90vh;
margin: 2vmin;
padding: 2vmin;
overflow: auto;
}
#dropzone.over {
background-color: rgba(0, 0, 0, .2);
}
<div id="dropzone">
Drop some directory here.
<pre id="_log"></pre>
</div>
And as fiddle for chrome
*chrome code (extensions and plugins) generally already have access to a FileSystem API.
*"webkit-API" here means experimental, i.e which behavior may change any time and may not be the same on every browsers.
Not really officially yet, but there will probably be, available for us mere web-developers* through the Files and Directory API which specs are still in the process of being written, even though chrome and Firefox already implement something similar through a webkit-API*, which allows us to access and navigate dropped directories.
So if we try to use this webkit-API, we could write something like this:
/* constructs a simple directory view from a filesystem */
async function makedir(entries) {
const systems = entries.map(entry => traverse(entry, {}));
return Promise.all(systems);
async function traverse(entry, fs) {
if (entry.isDirectory) {
fs[entry.name] = {};
let dirReader = entry.createReader();
await new Promise((res, rej) => {
dirReader.readEntries(async entries => {
for (let e of entries) {
await traverse(e, fs[entry.name]);
}
res();
}, rej);
});
} else if (entry.isFile) {
await new Promise((res, rej) => {
entry.file(file => {
fs[entry.name] = file;
res();
}, rej);
});
}
return fs;
}
}
function readDropped(dT) {
const entries = [...dT.items].map(item => {
return item.webkitGetAsEntry ? item.webkitGetAsEntry() : null;
})
.filter(entry => entry);
if (entries.length) {
makedir(entries)
.then(output)
.catch(handleSecurityLimitation);
} else notadir();
}
function notadir() {
_log.textContent = "wasn't a directory, or webkitdirectory is not supported";
}
dropzone.ondragover = e => {
e.preventDefault();
dropzone.classList.add('over');
}
dropzone.ondragexit = dropzone.ondragend = e => dropzone.classList.remove('over');
dropzone.ondrop = e => {
e.preventDefault();
dropzone.classList.remove('over');
readDropped(e.dataTransfer);
}
function output(system_trees) {
console.log(system_trees);
_log.textContent = JSON.stringify(system_trees, checkFile, 2);
function checkFile(key, value) {
if (value instanceof File) {
return '{[File] ' + value.name + ', ' + value.size + 'b}';
} else return value;
}
}
function handleSecurityLimitation(error) {
console.error(error);
document.body.innerHTML = `
<h2>Faced security limitations</h2>
<a href="https://jsfiddle.net/x85vtnef/">Please go to this fiddle</a>`;
}
#dropzone {
border: 1px solid;
width: 90vw;
height: 90vh;
margin: 2vmin;
padding: 2vmin;
overflow: auto;
}
#dropzone.over {
background-color: rgba(0, 0, 0, .2);
}
<div id="dropzone">
Drop some directory here.
<pre id="_log"></pre>
</div>
And as fiddle for chrome
*chrome code (extensions and plugins) generally already have access to a FileSystem API.
*"webkit-API" here means experimental, i.e which behavior may change any time and may not be the same on every browsers.
/* constructs a simple directory view from a filesystem */
async function makedir(entries) {
const systems = entries.map(entry => traverse(entry, {}));
return Promise.all(systems);
async function traverse(entry, fs) {
if (entry.isDirectory) {
fs[entry.name] = {};
let dirReader = entry.createReader();
await new Promise((res, rej) => {
dirReader.readEntries(async entries => {
for (let e of entries) {
await traverse(e, fs[entry.name]);
}
res();
}, rej);
});
} else if (entry.isFile) {
await new Promise((res, rej) => {
entry.file(file => {
fs[entry.name] = file;
res();
}, rej);
});
}
return fs;
}
}
function readDropped(dT) {
const entries = [...dT.items].map(item => {
return item.webkitGetAsEntry ? item.webkitGetAsEntry() : null;
})
.filter(entry => entry);
if (entries.length) {
makedir(entries)
.then(output)
.catch(handleSecurityLimitation);
} else notadir();
}
function notadir() {
_log.textContent = "wasn't a directory, or webkitdirectory is not supported";
}
dropzone.ondragover = e => {
e.preventDefault();
dropzone.classList.add('over');
}
dropzone.ondragexit = dropzone.ondragend = e => dropzone.classList.remove('over');
dropzone.ondrop = e => {
e.preventDefault();
dropzone.classList.remove('over');
readDropped(e.dataTransfer);
}
function output(system_trees) {
console.log(system_trees);
_log.textContent = JSON.stringify(system_trees, checkFile, 2);
function checkFile(key, value) {
if (value instanceof File) {
return '{[File] ' + value.name + ', ' + value.size + 'b}';
} else return value;
}
}
function handleSecurityLimitation(error) {
console.error(error);
document.body.innerHTML = `
<h2>Faced security limitations</h2>
<a href="https://jsfiddle.net/x85vtnef/">Please go to this fiddle</a>`;
}
#dropzone {
border: 1px solid;
width: 90vw;
height: 90vh;
margin: 2vmin;
padding: 2vmin;
overflow: auto;
}
#dropzone.over {
background-color: rgba(0, 0, 0, .2);
}
<div id="dropzone">
Drop some directory here.
<pre id="_log"></pre>
</div>
/* constructs a simple directory view from a filesystem */
async function makedir(entries) {
const systems = entries.map(entry => traverse(entry, {}));
return Promise.all(systems);
async function traverse(entry, fs) {
if (entry.isDirectory) {
fs[entry.name] = {};
let dirReader = entry.createReader();
await new Promise((res, rej) => {
dirReader.readEntries(async entries => {
for (let e of entries) {
await traverse(e, fs[entry.name]);
}
res();
}, rej);
});
} else if (entry.isFile) {
await new Promise((res, rej) => {
entry.file(file => {
fs[entry.name] = file;
res();
}, rej);
});
}
return fs;
}
}
function readDropped(dT) {
const entries = [...dT.items].map(item => {
return item.webkitGetAsEntry ? item.webkitGetAsEntry() : null;
})
.filter(entry => entry);
if (entries.length) {
makedir(entries)
.then(output)
.catch(handleSecurityLimitation);
} else notadir();
}
function notadir() {
_log.textContent = "wasn't a directory, or webkitdirectory is not supported";
}
dropzone.ondragover = e => {
e.preventDefault();
dropzone.classList.add('over');
}
dropzone.ondragexit = dropzone.ondragend = e => dropzone.classList.remove('over');
dropzone.ondrop = e => {
e.preventDefault();
dropzone.classList.remove('over');
readDropped(e.dataTransfer);
}
function output(system_trees) {
console.log(system_trees);
_log.textContent = JSON.stringify(system_trees, checkFile, 2);
function checkFile(key, value) {
if (value instanceof File) {
return '{[File] ' + value.name + ', ' + value.size + 'b}';
} else return value;
}
}
function handleSecurityLimitation(error) {
console.error(error);
document.body.innerHTML = `
<h2>Faced security limitations</h2>
<a href="https://jsfiddle.net/x85vtnef/">Please go to this fiddle</a>`;
}
#dropzone {
border: 1px solid;
width: 90vw;
height: 90vh;
margin: 2vmin;
padding: 2vmin;
overflow: auto;
}
#dropzone.over {
background-color: rgba(0, 0, 0, .2);
}
<div id="dropzone">
Drop some directory here.
<pre id="_log"></pre>
</div>
edited Dec 27 '17 at 5:38
answered Dec 22 '17 at 2:51
Kaiido
38.9k45799
38.9k45799
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f47932586%2fuploading-directory-and-maintainign-structure-through-javascript-and-html5%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown