1

tried to find some useful answer in existing threads but nothing is really matching my issue. I guess there is a quick fix to it, i just cannot see it.

I have a HTML form and want to upload the file to my google drive (works great) and save the text fields to my spreadsheet (does not work at all).

I just cannot find any major difference between the two functions, its frustrating!

Below my code, and here is also the [link to my public script][1].

Form:

<!DOCTYPE html>

<form id="myForm">
    <input type="text" name="myName" placeholder="Your name..">
    <input type="file" name="myFile">
<input type="submit" value="Upload File" 
       onclick="this.value='Uploading..';
                google.script.run.withSuccessHandler(fileUploaded)
                .uploadFiles(this.parentNode);
                return false;
                google.script.run.withSuccessHandler(fileUploaded)
                .doPost(this.parentNode);">
</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>



  [1]: https://script.google.com/d/1K9jGl7ALHCZ93rz8GoeV8t7PE_7vgbNZlLJed1h6ZWyuoon11gIbik24/edit?usp=sharing

server.gs:

function doGet(e) {
  var html = HtmlService.createTemplateFromFile("form");
  html = html.evaluate();
  html.setSandboxMode(HtmlService.SandboxMode.IFRAME);
  return html;  
}

function uploadFiles(form) {

  try {

    var dropbox = "Customer Shapes";
    var folder, folders = DriveApp.getFoldersByName(dropbox);

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

    var blob = form.myFile;    
    var file = folder.createFile(blob);    
    file.setDescription("Uploaded by " + form.myName);

    return "File uploaded successfully " + file.getUrl();

  } catch (error) {

    return error.toString();
  }
}

function doPost(form) { // change to doPost(e) if you are recieving POST data
  html.setSandboxMode(HtmlService.SandboxMode.EMULATED);
  var name = form.myName;
  var url="url...";
  var message = 'Ram';
  var submitSSKey = '...kHI';
  var sheet = SpreadsheetApp.openById(submitSSKey).getActiveSheet();
  var lastRow = sheet.getLastRow();
  var targetRange = sheet.getRange(lastRow+1, 1, 2, 2).setValues([[name,url]]);
}

Thank You for Your kind help!

Martin

Martin
  • 87
  • 7

1 Answers1

0

If you are going to use google.script.run, then it's pointless to have a function named doPost(). And it's also pointless to have a submit type input tag: type="submit"

If you want to run a withSuccessHandler(fileUploaded) to change the display, you can't have a button inside of the form. It will cause the display to go blank.

And you don't need two google.script.run calls. You need multiple changes and improvements:

form.html

<form id="myForm">
  <input type="text" name="myName" placeholder="Your name..">
  <input type="file" name="myFile">
</form>

  <input type="button" value="Upload File" 
       onclick="this.value='Uploading..';
                var theForm = document.getElementById('myForm');
                google.script.run.withSuccessHandler(fileUploaded)
                .processFormData(theForm);">

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

server.gs

function processFormData(form) {
  uploadFiles(form.myFile);//Call first function to process the file

  var innerArray = [];
  var outerArray = [];

  innerArray.push(form.myName);
  innerArray.push(form.myFile);

  outerArray.push(innerArray);//Call second function to write data to SS
  writeDataToSS(outerArray);
};

function uploadFiles(theFile) {

  try {

    var dropbox = "Customer Shapes";
    var folder, folders = DriveApp.getFoldersByName(dropbox);

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

    var blob = theFile;    
    var file = folder.createFile(blob);    
    file.setDescription("Uploaded by " + theFile);

    return "File uploaded successfully " + file.getUrl();

  } catch (error) {

    return error.toString();
  }
}

function writeDataToSS(values) {
  //html.setSandboxMode(HtmlService.SandboxMode.EMULATED);
  var url="url...";
  var message = 'Ram';
  var submitSSKey = '...kHI';
  var sheet = SpreadsheetApp.openById(submitSSKey).getActiveSheet();
  var lastRow = sheet.getLastRow();
  var targetRange = sheet.getRange(lastRow+1, 1, 1, 2).setValues(values);
}

The html file is not a template, it does not have a scriptlet in it. Just use createHtmlOutputFromFile():

function doGet(e) {
  var html = HtmlService.createHtmlOutputFromFile("form");
  html.setSandboxMode(HtmlService.SandboxMode.IFRAME);
  return html;  
}
Alan Wells
  • 30,746
  • 15
  • 104
  • 152
  • Hi, thanks Sandy to provide a complete solution! I openheartedly confirm that I am a GAS novice. Just tried out Your code but I got a failure message: InternalError: Cannot convert [object Object] to BlobSource. Any idea what went wrong? Link: https://docs.google.com/spreadsheets/d/1ajWtsLxjIwXk5CTctjWVFxPPAAtm6rehLbVleYv-kHI/edit?usp=sharing thanks! – Martin Mar 19 '16 at 18:31
  • I made a couple of errors. Change `.uploadFiles(theForm);` to: `.processFormData(theForm);`. Also change the number of rows in the range from 2 to 1. `var targetRange = sheet.getRange(lastRow+1, 1, 1, 2).setValues(values);` – Alan Wells Mar 19 '16 at 19:13
  • @Sandy Thanks. Can you please also show an example of the client code (XMLHttpRequest with the GET request) to trigger the whole thing? – Mor Sagmon Oct 03 '16 at 12:14
  • @MorSagmon Do some searches and research on AJAX request for the request itself. Look at these posts also: [Stack Overflow - pass a doGet parameter](http://stackoverflow.com/questions/27664518/how-to-pass-a-dogete-parameter-to-another-function/27668966#27668966) and [URL string parameter passed to doGet](http://stackoverflow.com/a/22292365/2946873) – Alan Wells Oct 03 '16 at 12:34
  • @Sandy doing a lot of research :) I tried to implement using JSONP but I still can't get a response to the browser, probably because of Google's redirect https://developers.google.com/apps-script/guides/content#serving_jsonp_in_web_pages – Mor Sagmon Oct 03 '16 at 14:26
  • It seems that you have some code, so you could post a question if you are stuck. – Alan Wells Oct 03 '16 at 16:11
  • @Sandy yes, here it is: http://stackoverflow.com/questions/39838459/serving-jsonp-in-web-pages-from-google-doget-not-returning-response-to-browser – Mor Sagmon Oct 03 '16 at 18:51