0

I am making a google site which shows a drop down based on data coming from a Google Sheet. It works.

As next step, I want that when the user select a drop down choice from the list, the value which is selected is written in Google Sheet cell (in the example below, the selected value will be written in Sheet: "Dashboard", cell: B92).

For example, assume that the drop down list has the following values coming from the Sheet: "Item 1", "Item 2", "Item 3".

When the user select "Item 1" from the web site, the script should write "Item 1" in Google sheet cell B92. Similarly, if the user select "Item 2", the script will set "Item 2" in cell B92.

I tried with the code below, but I think something is wrong with:

  • fetch in the HTML file
  • doPost(e) because I am not sure how to pass the parameter

(I removed the entire code to focus on the pieces which are incorrect. I can add it back if needed)

function doPost(e) {
          var ss=SpreadsheetApp.openById('XXXXXXXX');
          var sh=ss.getSheetByName('Dashboard');
          sh.getRange(92,2).setValues(e.parameter);

        }

HTML file:

<script type="text/javascript">
      var lastIndex = "";
      const url = "https://script.google.com/a/google.com/macros/s/AKfycbxHX7cthji076OrqfY9ZpGa7jNDxKHUMf_ib7Ekmoo0Ir5DQF1Y/exec";
    function listQ(){
        var e = document.getElementById("sel1");
        if(e.selectedIndex > 0){
                lastIndex = e.selectedIndex;
                console.log(lastIndex);
                fetch(url, {
                    method: "POST"
                    , body: lastIndex
                }).then(function (response) {
                    return response.json()
                }).then(function (data) {
                    console.log(data);            
            })
         }
    }

document.getElementById("sel1").addEventListener("click",listQ);

Filippo
  • 320
  • 2
  • 5
  • 22

2 Answers2

2

I believe your goal as follows.

  • You want to put the selected value at select tab in HTML to the cell "B92" in the sheet Dashboard.
  • You want to send the value to Web Apps with the POST method.

For this, how about this answer?

Modification points:

  • At Google Apps Script side,
    • When you want to use the POST method, the request body is included in e.postData.contents.
    • sh.getRange(92,2).setValues(e.parameter); is not correct. In this case, please use setValue/
    • In your doPost, no values are returned. In this case, an error occurs at Javascript side when the value is sent.
  • At Javascript side,
    • lastIndex is returned. In the case of When the user select "Item 1" from the web site, the script should write "Item 1" in Google sheet cell B92. Similarly, if the user select "Item 2", the script will set "Item 2" in cell B92., the selected value is required to be retrieved and returned.

When above modification is reflected to your script, it becomes as follows.

Modified script:

Google Apps Script side:

function doPost(e) {
  var value = JSON.parse(e.postData.contents).value;
  var ss = SpreadsheetApp.openById('XXXXXXXX');
  var sh = ss.getSheetByName('Dashboard');
  sh.getRange(92, 2).setValue(value);
  return ContentService.createTextOutput(JSON.stringify({message: "ok"})).setMimeType(ContentService.MimeType.JSON);
}

HTML and Javascript side:

From your question, I cannot understand about your options. So I used a sample options like below. Please replace this for your actual situation.

<select id="sel1">
  <option value="sample1">sample1</option>
  <option value="sample2">sample2</option>
  <option value="sample3">sample3</option>
</select>


<script>
  function listQ() {
    const index = this.selectedIndex;
    if (index > 0) {
      const e = document.getElementById("sel1");
      const value = e.options[index].value;
      const url = "https://script.google.com/macros/s/###/exec";  // Please replace this for your Web Apps.
      fetch(url, {
        method: "POST",
        body: JSON.stringify({index: index, value: value}),
      })
      .then(function (response) {
        return response.json();
      })
      .then(function (data) {
        console.log(data);
      })
    }
  } 

  document.getElementById("sel1").addEventListener("change", listQ);
</script>
  • In this modification, when the options of sample2 and sample3 are selected, the value is sent to Web Apps. And then, at the Web Apps, the retrieved value is put to the cell "B92".

Note:

  • When you modified the script of Web Apps, please redeploy it as new version. By this, the latest script is reflected to Web Apps. Please be careful this.

References:

Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • @Filippo Thank you for replying. I apologize for the inconvenience. About `I am getting similar error as I was before:`, I cannot replicate your situation. So in order to correctly replicate and understand about your situation, can you provide the sample Spreadsheet including my script? Because in my environment, when my script is used, no error occurs. I apologize for this. By this, I would like to confirm it. – Tanaike May 09 '20 at 23:13
  • @Tanike, I have some troubles to share due to restrictions in my company laptop. However, I read online that my error is due to the CORS policy. I will open a different question to address the CORS issue. I read this, but not sure how to apply to my code: https://serverpilot.io/docs/how-to-enable-cross-origin-resource-sharing-cors/ – Filippo May 11 '20 at 16:43
  • I asked my CORS question in https://stackoverflow.com/questions/61735101/cors-block-webapp-post-to-sheet – Filippo May 11 '20 at 16:58
  • @Filippo Thank you for replying. Can I ask you how do you want to do this question? – Tanaike May 11 '20 at 23:03
  • I am not sure how to verify this since I get that error. Also you probably cannot replicate it. However I think that doing this will solve it: https://stackoverflow.com/questions/29525860/google-apps-script-cross-domain-requests-stopped-working Do you know how to integrate that URL method into this code? When I tried myself it did not work – Filippo May 12 '20 at 00:21
  • @Filippo Thank you for replying. Do you want to return the value as JSONP? Although I'm not sure about your goal, in this case, the POST method cannot be used for JSONP. How about this? – Tanaike May 12 '20 at 00:32
  • I am not sure what to do. I will try again tomorrow to see if I can somehow fix the CORS issue. I was hoping that this link could be useful, but it did not work. https://stackoverflow.com/questions/29525860/google-apps-script-cross-domain-requests-stopped-working – Filippo May 12 '20 at 01:33
  • 1
    ok solved using the google.script.run. I am afraid that due to my (unknown) settings which cause a CORS error, I need to avoid the POST calls – Filippo May 12 '20 at 16:38
0

In addition to Tanaike answer, I am posting an alternative using google.script.run which avoid the CORS issue which some users may experience.

The complete explanation is here: CORS block: WebApp POST to Sheet

in gs file:

function yourServerSideFunc(body) {
  var value = body["value"];
  var ss = SpreadsheetApp.openById('1ROvDcIQ9JCGxzLvCvTKIqSor576Uj9ZJv-n6hQ762XB');
  var sh = ss.getSheetByName('Dashboard');
  sh.getRange(92, 2).setValue(value);
  return ContentService.createTextOutput(JSON.stringify({message: "ok"})).setMimeType(ContentService.MimeType.JSON);  
}

and in HTML:

function listQ() {
  const index = this.selectedIndex;
  if (index > 0) {
    const e = document.getElementById("sel1");
    const value = e.options[index].value;
    const body = { index: index, value: value };
    google.script.run.withSuccessHandler(yourCallBack).yourServerSideFunc(body);
  }
}
document.getElementById("sel1").addEventListener("change",listQ);

function yourCallBack(response) {
}
Filippo
  • 320
  • 2
  • 5
  • 22