10

I am trying to alter ctrlq's code (found here: http://ctrlq.org/code/19747-google-forms-upload-files) in order to upload multiple files instead of 1.

Here is what I have so far: HTML:

    <form id="myForm">
    <input type="text" name="myName" placeholder="Name">
    <input type="password" name="psw" placeholder="Password">
    <input type="text" name="myFolder" placeholder="Folder Name">
    <input type="file" name="myFile" id="filesID" multiple>
    <input type="submit" value="Upload File" 
           onclick="this.value='Uploading..';
                    google.script.run.withSuccessHandler(fileUploaded)
                    .uploadFiles(this.parentNode);
                    return false;">
</form>

<div id="output"></div>

<script>
    function fileUploaded(status) {
        document.getElementById('myForm').style.display = 'none';
        document.getElementById('output').innerHTML = status;
    }
</script>

<style>
 input { display:block; margin: 20px; }
</style>

Google Scripts:

function doGet(e) {
  return HtmlService.createHtmlOutputFromFile('form.html');
}

function uploadFiles(form) {

  try {
    var input = document.getElementById('filesID');
    var dropbox = "User Files";
    var folder, folders = DriveApp.getFoldersByName(dropbox);

    if (folders.hasNext()) {
      folder = folders.next();
    } else {
      folder = DriveApp.createFolder(dropbox);
    }

    for (var i = 0; i < input.length; i++) {
      var file = folder.createFile(input.input[i]);    
      file.setDescription("Uploaded by " + form.myName);
    }
    return "File uploaded successfully " + file.getUrl();

  } catch (error) {

    return error.toString();
  }

}

I'm getting errors saying that the function createFile won't run. I expect it is because the variable myFile isn't originally an array. How can I put all the files uploaded into an array and then run the createFile for each file?

Thanks

Mogsdad
  • 44,709
  • 21
  • 151
  • 275
John Olsen
  • 125
  • 10
  • 1
    Here is how I handle multiple file upload: http://stackoverflow.com/questions/28147486/handling-multiple-files-from-an-input-element-in-an-array-with-google-apps-scrip/28161468#28161468 – Spencer Easton Aug 31 '15 at 15:43

1 Answers1

1

First of all be aware that the multiple attribute on the HTML <input> tag is introduced on HTML5, and supported only by modern browsers (for example, in the case of Firefox from Gecko 1.9.2, which would be from version 3.6)

Now, in order to set up an HTML form for multiple file upload, you must:

  • Explicitly specify your HTML document is HTML5. Your document must start with:

    <!DOCTYPE html>

  • In order to properly upload files to your server you must set your form enctype attribute to multipart/form-data:

    <form id="myForm" enctype="multipart/form-data">

  • You must also specify your file input tag as a multiple file input tag by using the multiple attribute. You seem to have this right, but just in case try:

    <input type="file" name="myFile" id="filesID" multiple="multiple" />

    instead.

There are also (at least) a couple of problems in the for loop of your Javascript code for handling the selected files; You are referencing input.length and input.input[i] when you should be referencing input.files.length and input.files[i] instead:

for (var i = 0; i < input.files.length; i++) {
      var file = folder.createFile(input.files[i]);    
      file.setDescription("Uploaded by " + form.myName);
}

I strongly recommend you check out the super useful MDN's mini tutorial on handling file uploads for details and examples.

Also, if you are willing to add libraries and plugins, bootstrap fileinput is quite a useful one, pretty simple to incorporate and use on any form you want.

In any case, you'll end up with a form sending an array of files you can also access on the client as a FileList object stored on the files property of the input element containing File objects instead of just a single file element. As shown on the code above, you can access any file in this FileList object as an array (input.files[i]).

NotGaeL
  • 8,344
  • 5
  • 40
  • 70
  • for some reason this gives me the error "ReferenceError: "document" is not defined" – John Olsen Sep 09 '15 at 22:19
  • you are calling a function that needs the reference to the current document before the document is loaded. Use chrome dev tools to debug the script. If you do a backtrace from the line that gives you the error you will see where you are making the call that you should put inside a `document.addEventListener("DOMContentLoaded", function(event) { }` – NotGaeL Sep 09 '15 at 23:50