0

I created a sidebar to have a basic UI for searching my Google sheet. I'm following this tutorial exactly to make sure the first step works, except that it doesn't! I even took out the userObject part to make it simpler (honestly, because I don't know what that part does).

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script>
      function updateButton(email, button) {
        button.value = 'Clicked by ' + email;
      }
    </script>
  </head>
  <body>
    <input type="button" value="Not Clicked"
      onclick="google.script.run
          .withSuccessHandler(updateButton)
          //.withUserObject(this)
          .testMe()" />
    <input type="button" value="Not Clicked"
      onclick="google.script.run
          .withSuccessHandler(updateButton)
          //.withUserObject(this)
          .testMe()" />
  </body>
</html>

It calls this function:

function testMe() {
  Logger.log("Test log.");
  return ContentService.createTextOutput("Jackpot!");
}

If it matters, the HTML runs in a sidebar via onOpen as follows:

function showGradingSidebar() {
  var html = HtmlService.createHtmlOutputFromFile('testSidebar')
      .setSandboxMode(HtmlService.SandboxMode.IFRAME)
      .setTitle('Testing Module')
      .setWidth(300);
  SpreadsheetApp.getUi()
      .showSidebar(html);
}

When I click the button, it does nothing (that I can see). By changing various aspects, I can get it to Logger.log() a simple message but even that doesn't work reliably if I change the HTML side.

I was reading about the security restrictions that require sanitizing what the function returns, but both HtmlService.createHtmlOutput() and ContentService.createTextOutput() were also unsuccessful. Please advise.

UPDATE: Thanks to @Bryan P, I got it to work. The testMe() is simply:

return "Jackpot";

...and the HTML page looks like this:

[html, head, etc.]<body>
    <input type="button" value="Ready"
      onclick="google.script.run
          .withSuccessHandler(updateButton)
          .withUserObject(this)
          .testMe()" --->
  <br><div id="output">Output goes here: </div>
  <br><div id="papa">Papa goes here: </div>
  <br><p></p>
  <script>
    function updateButton(result) {
      var div = document.getElementById('output')
      div.innerHTML = 'It finally works!' + result;
    }
  </script>  
</body>
</html>

I don't know how much it helped, but I did move the script tag down to the bottom of the body, fwiw, after reading this SO post.

Community
  • 1
  • 1
AimFireReady
  • 81
  • 2
  • 14

1 Answers1

0

In Chrome, if you right-click in the sidebar area >> Inspect >> in the Console it should show a message that there wasn't a valid return type after clicking on one of the buttons.

.createTextOutput(content) returns a TextOutput type (which isn't the same as just plain text type)

It's only used when you've deployed a the web app URL and some external service calls that URL. It only gets handled with doGet() too.

Did you try just return "Jackpot"; instead?

.withUserObject(this) - this refers to button element and the whole method passes it on to the successHandler(). So you can consider keeping it. Otherwise you'd have to reference the button from within the successHandler another way:

function updateButton(email) {
  document.getElementById('myButton').value = 'Clicked by ' + email;
}

...which requires you add an ID attribute into the button.

You can always do:

function updateButton(email, button) {
  console.log('Success hit');
  button.value = 'Clicked by ' + email;
}

...to check whether the successHandler was even called in that Chrome dev console too.

Bryan P
  • 5,031
  • 3
  • 30
  • 44
  • Thanks for the insight. I guess I was misusing the Content Service then. I did try plain `return "Jackpot"` first before I found out about the security restrictions, so then I didn't know what was a "dirty" return or not. I finally got it to work after an hour implementing Bryan's input. I updated my original post for posterity. – AimFireReady Feb 19 '16 at 19:55