21

I'm trying to use one file input element to upload multiple files to Drive using html form. This seems to work only for one file, although the file picker allows selecting multiple files. Back in the script log viewer, I only see one file captured of the two I uploaded. Is this unsupported, or am I going the wrong way about it?

Code.gs:

function logForm(form) {
  Logger.log(JSON.stringify(form));
  return true;
}

index.html:

<html>
  <form id="uploadTest" enctype="multipart/form-data">
    <input type="file" multiple="multiple" name="fileUpload">
    <input type="button" id="upload" value="upload"
    onclick="google.script.run.logForm(document.getElementById('uploadTest'));">
  </form>
</html>

Log view:

{"fileUpload":{"contents":"GIF87a\u0001\u0000\u0001\u0000�
\u0000\u0000��̖��,\u0000\u0000\u0000\u0000\u0001\u0000
\u0001\u0000\u0000\u0002\u0002D\u0001\u0000;",
"type":"image/gif","name":"1x1.gif","length":35}}
Danny Beckett
  • 20,529
  • 24
  • 107
  • 134
jad
  • 552
  • 2
  • 9
  • 19

3 Answers3

8

The multiple file select in the dialog when you click on the browse button of the file field happens only for the new browsers supporting HTML5. It wont allow multiple select for old browsers. For older browsers the only good solutions are flash or javascript plugins. Here is a good resource for jquery uploaders ( some support multiple files ): http://creativefan.com/10-ajax-jquery-file-uploaders/. Hence my suggestion is use some plugin so that its supported on old as well as the new browsers.

Matthew Lock
  • 13,144
  • 12
  • 92
  • 130
Ujwal Abhishek
  • 328
  • 1
  • 6
  • 1
    Thank you Ujwal, I've tried [jQuery Multiple File Upload Plugin](http://www.fyneworks.com/jquery/multiple-file-upload/#) from the link you provided and it worked perfect!. I was aware of the browser limitation, but thought it's weird that I was allowed to select multiple files but only one was assigned to the element. As a last resort I was going to add + and - buttons to create/remove additional elements, but this is way more elegant :) – jad Apr 03 '13 at 06:31
7

I'm using possibility to send array of files. Just add [] to name atrribute:

<form action="/" enctype="multipart/form-data" method="post">
    <input type="file" name="files[]" />
    <input type="file" name="files[]" />
    // etc.
    <input type="submit">
</form>

You will have array of arrays in $_FILES

Array
(
    [files] => Array
        (
            [name] => Array
                (
                    [0] => 1.png
                    [1] => 2.png
                )

            [type] => Array
                (
                    [0] => image/png
                    [1] => image/png
                )

            [tmp_name] => Array
                (
                    [0] => /tmp/phpDQOZWD
                    [1] => /tmp/phpCELeSw
                )

            [error] => Array
                (
                    [0] => 0
                    [1] => 0
                )

            [size] => Array
                (
                    [0] => 32209
                    [1] => 64109
                )

        )

)

Of course, you you'll have to upload them one by one. Not convenient to a large number of files, but works in all browsers. For example,using jQuery you can add one more input each time last files[] input was changed.

function addOneMoreInput() {
    $('input[type=file]').last().change(function() {
        $(this).after('<input type="file" name="files[]" />');
        $(this).off('change');
        addOneMoreInput();
    });
}
addOneMoreInput();
vladkras
  • 16,483
  • 4
  • 45
  • 55
0

How about this sample script?

In this sample, the following flow is run.

  1. Select files at browser.
  2. Upload the files every file.
  3. Save each file in Google Drive.
  4. In this sample script, the file IDs of created files are returned to the console.

When you use this, please copy and paste the Google Apps Script and HTML to the script editor, and run the HTML using the dialog, sidebar and Web Apps.

Code.gs: Google Apps Script

function saveFile(obj) {
  var blob = Utilities.newBlob(Utilities.base64Decode(obj.data), obj.mimeType, obj.fileName);
  return DriveApp.createFile(blob).getId();
}

index.html: HTML and Javascript

<input name="file" id="files" type="file" multiple>
<input type='button' value='Upload' onclick='getFiles()'>

<script>
function getFiles() {
  const f = document.getElementById('files');
  [...f.files].forEach((file, i) => {
    const fr = new FileReader();
    fr.onload = (e) => {
      const data = e.target.result.split(",");
      const obj = {fileName: f.files[i].name, mimeType: data[0].match(/:(\w.+);/)[1], data: data[1]};
      google.script.run.withSuccessHandler((id) => {
        console.log(id);
      }).saveFile(obj);
    }
    fr.readAsDataURL(file);
  });
}
</script>

Note:

Tanaike
  • 181,128
  • 11
  • 97
  • 165