Search code examples
javascripthtmlgoogle-apps-script

App Script how to read a form object passed through cloud function


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


Solution

  • Modification points:

    • When I saw your HTML, I noticed that you use 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.

    Modified script:

    Google Apps Script: 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());
    }
    

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

    Javascript: 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 this modified script is used when you open the HTML multiple files are selected and click "Submit" button, and the files are uploaded to Google Drive. And, you can see the uploaded file IDs in the console.

    Note:

    References: