Google sheets modal doesn't submit form but as a standalone webapp it's working

Viewed 67

I have a custom UI function, that opens a modal dialog in my Google Sheets file. The modal is a simple HTML with a form, that allows the user to choose a file from local hard drive, to upload it into Google Drive. The HTML part for this form is as follows:

<form>
  <input type="file" name="theFile" id="file-check" accept="image/*">
  <input type="button" class="btn btn-info"  value="Add photo" id="add-image">
</form>

And the code for sending the data is as follows:

$("#add-image").click(function(){
      var val = $('#file-check').val();
      if (val == ''){alert('Choose a file to upload');return;}
      $('#add-image').attr("disabled", true);
      $('#add-image').attr("value", "Adding... please wait.");
google.script.run.withSuccessHandler(refreshIt).withFailureHandler(show_error).uploadImage(this.parentNode);
    });

But when I submit the form, the response from the server is this:

{theFile=null}

I've tried to set up this modal dialog as a standalone web-app and it's working normally... The response from the server from the standalone webapp is as follows:

{theFile=FileUpload}

And the file is being uploaded without any problems!

Why is it working normally as a standalone webapp but sending the null as a modal dialog?

1 Answers

Issue and workaround:

Why is it working normally as a standalone webapp but sending the null as a modal dialog?

I thought that the reason for this issue is due to the current specification. After V8 runtime was released, there was a bug that when the file is sent from HTML form to Google Apps Script side using google.script.run, the file blob was the invalid data. But, on Nov 26, 2021, this bug could be removed. Ref But, when I tested this, it was found that this bug could be removed for Web Apps, and this bug cannot be removed for the dialog and sidebar. Ref This has already been reported to the issue tracker. I believe that this bug will be resolved in the future updated.

In the current stage, in order to upload a file with the dialog and sidebar, it is required to use a workaround. In this answer, I would like to propose a workaround. When your script is modified, it becomes as follows.

Modified script:

From:

$("#add-image").click(function(){
      var val = $('#file-check').val();
      if (val == ''){alert('Choose a file to upload');return;}
      $('#add-image').attr("disabled", true);
      $('#add-image').attr("value", "Adding... please wait.");
google.script.run.withSuccessHandler(refreshIt).withFailureHandler(show_error).uploadImage(this.parentNode);
    });

To:

$("#add-image").click(function(){
  var val = $('#file-check').val();
  if (val == ''){alert('Choose a file to upload');return;}
  $('#add-image').attr("disabled", true);
  $('#add-image').attr("value", "Adding... please wait.");

  const file = this.parentNode.theFile.files[0];
  const fr = new FileReader();
  fr.onload = function(e) {
    google.script.run.withSuccessHandler(refreshIt).withFailureHandler(show_error).uploadImage([[...new Int8Array(e.target.result)], file.type, file.name]);
  };
  fr.readAsArrayBuffer(file);
});
  • In this case, the function uploadImage of Google Apps Script can be modified as follows. Unfortunately, I cannot see your current script of uploadImage. So please modify your script using the following sample.

      function uploadImage(obj) {
        const blob = Utilities.newBlob(...obj);
        DriveApp.createFile(blob);
    
        return "done"; // Please set your expected return value.
      }
    

References:

Related