I'm building a web app to take files from a web form and put them in a Google Drive folder. Upon submitting the form, I want to run a cloud function with google.script.run while passing through the form object as a parameter.
My question is how can I access the files in Code.gs after passing through the form object? I want to get the file names and maybe other data. My code below:
index.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form id="myForm" onsubmit="handleFormSubmit(this)">
<label for="FormControlFile">Select File:</label>
<input name="myFile" type="file" id="FormControlFile" multiple />
<button type="submit">Submit</button>
</form>
<?!= include('script'); ?>
</body>
</html>
Code.gs:
const folderId = "my folder id";
const folder = DriveApp.getFolderById(folderId);
function doGet() {
return HtmlService.createTemplateFromFile("index").evaluate();
}
function include(fileName) {
return HtmlService.createHtmlOutputFromFile(fileName).getContent();
}
function uploadFiles(formObject) {
//formObject.files??
}
script.html:
<script>
function preventFormSubmit() {
const form = document.getElementById("myForm")
form.addEventListener("submit", (e) => {
e.preventDefault();
});
}
window.addEventListener("load", preventFormSubmit);
function handleFormSubmit(formObject) {
google.script.run.uploadFiles(formObject);
}
</script>
Thanks
multiple
at <input name="myFile" type="file" id="FormControlFile" multiple />
. From this situation, I guessed that in your situation, multiple files might be uploaded.In the current stage, unfortunately, google.script.run
cannot parse multiple files from the input tag. So, in this case, it is required to parse the files on the Javascript side.
When this is reflected in your script, it becomes as follows.
Code.gs
In this case, the function uploadFiles
is modified.
const folderId = "my folder id";
const folder = DriveApp.getFolderById(folderId);
function doGet() {
return HtmlService.createTemplateFromFile("index").evaluate();
}
function include(fileName) {
return HtmlService.createHtmlOutputFromFile(fileName).getContent();
}
function uploadFiles(formObject) {
if (formObject.length == 0) {
return "No files";
}
return formObject.map(e => folder.createFile(Utilities.newBlob(...e)).getId());
}
index.html
This is not modified.
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form id="myForm" onsubmit="handleFormSubmit(this)">
<label for="FormControlFile">Select File:</label>
<input name="myFile" type="file" id="FormControlFile" multiple />
<button type="submit">Submit</button>
</form>
<?!= include('script'); ?>
</body>
</html>
script.html
In this case, the function handleFormSubmit
is modified.
<script>
function preventFormSubmit() {
const form = document.getElementById("myForm")
form.addEventListener("submit", (e) => {
e.preventDefault();
});
}
window.addEventListener("load", preventFormSubmit);
function handleFormSubmit(formObject) {
Promise.all([...formObject.myFile.files].map(file => {
const fr = new FileReader();
return new Promise(r => {
fr.onload = e => r([[...new Int8Array(e.target.result)], file.type, file.name]);
fr.readAsArrayBuffer(file);
});
}))
.then(obj => google.script.run.withSuccessHandler(console.log).uploadFiles(obj));
}
</script>
When you modify the Google Apps Script of Web Apps, please modify the deployment as a new version. By this, the modified script is reflected in Web Apps. Please be careful about this.
You can see the details of this in my report "Redeploying Web Apps without Changing URL of Web Apps for new IDE (Author: me)".