3

My spreadsheet has a sidebar, how can I hide it with a script?

  SpreadsheetApp.getUi().[method?]

Thanks for any help!

Mogsdad
  • 44,709
  • 21
  • 151
  • 275
  • 2
    Not sure this will work, but worth trying: The sidebar will need to monitor (poll, something like [this](http://stackoverflow.com/questions/24773177/how-to-poll-a-google-doc-from-an-add-on/24773178#24773178)) for the server-side condition that signals to close. Then, if you're using HtmlService for your sidebar, it might be able to close itself with `google.script.host.close()`. For UiApp the equivalent is `UiInstance.close()`. – Mogsdad Dec 04 '14 at 14:41
  • On client-side google.script.host.close() works, I just need to make sure the form in my sidebar is properly validated after submission. That's what I'm trying to achieve. –  Dec 04 '14 at 14:56
  • Ah, easy then. Call close from the google.script success handler. – Mogsdad Dec 04 '14 at 15:51
  • The google.script.run.withSuccessHandler is running no matter if the form is validated or not. It seems it is running just because the validation function on the server is executed. How do I return the validation status back to the client side? –  Dec 04 '14 at 16:55
  • You need to have an explicit `return` in the handler. You can't rely on the implicit behavior. To trigger the failure handler, you need to `throw` an error from your validation function. At any rate, we've narrowed in on the problem - you could post the code at both ends of the interaction. – Mogsdad Dec 04 '14 at 17:17
  • @Mogsdad UiInstance.close is deprecated. Check my answer below https://stackoverflow.com/a/45071715/1737158 – Lukas Liesis Jul 13 '17 at 04:59

2 Answers2

1

Here is the straight forward approach

function closeSidebar() {
    var html = HtmlService.createHtmlOutput("<script>google.script.host.close();</script>");
    SpreadsheetApp.getUi().showSidebar(html);
}

// anywhere on the server-side script (or code.gs)
closeSidebar()
leopragi
  • 441
  • 1
  • 6
  • 16
0

Ignore what I said in the question comments about an explicit return... the successHandler syntax is tricky. You need the NAME of a function, without the brackets. No idea why, but there you go.

Code.gs

Here's a quick example of a sidebar that automatically closes after validating the input form. You can test the error behavior by ignoring the input hint.

/**
 * Creates a menu entry in the Google Sheets UI when the document is opened.
 */
function onOpen(e) {
  SpreadsheetApp.getUi().createAddonMenu()
      .addItem('Start', 'showSidebar')
      .addToUi();
}

/**
 * Runs when the add-on is installed.
 */
function onInstall(e) {
  onOpen(e);
}

/**
 * Opens a sidebar in the document containing the add-on's user interface.
 */
function showSidebar() {
  var ui = HtmlService.createHtmlOutputFromFile('Sidebar')
      .setTitle('Simple');
  SpreadsheetApp.getUi().showSidebar(ui);
}


/**
 * Validates the new text, and inserts it into spreadsheet if it is acceptable.
 *
 * @param {string} newText The text with which to replace the current selection.
 */
function insertText(newText) {

  if (newText.indexOf('Pizza') == -1) {
    SpreadsheetApp.getActiveSheet().getActiveCell().setValue(newText);
  }
  else {
    throw new Error( 'No Pizza allowed!' );
  }
  return;
}

Sidebar.html

<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css">

<div>
  <form>
    <div>
      <label for="new-text">Enter new text:</label>
      <input type="text" id="new-text" placeholder="Don't enter 'Pizza'!">
    </div>
    <br>
    <div class="block" id="button-bar">
      <button id="insert-text">Insert</button>
    </div>
  </form>
</div>


<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
</script>
<script>
  /**
   * On document load, assign click handler
   */
  $(function() {
    $('#insert-text').click(insertText);
  });

  /**
   * Runs a server-side function to validate and enter the entered text.
   */
  function insertText() {
    this.disabled = true;
    $('#error').remove();
    google.script.run
        .withSuccessHandler(google.script.host.close)  // <-- No brackets after function name
        .withFailureHandler(
          function(msg, element) {
            showError(msg, $('#button-bar'));
            element.disabled = false;
          })
        .withUserObject(this)
        .insertText($('#new-text').val());
  }

  /**
   * Inserts a div that contains an error message after a given element.
   *
   * @param msg The error message to display.
   * @param element The element after which to display the error.
   */
  function showError(msg, element) {
    var div = $('<div id="error" class="error">' + msg + '</div>');
    $(element).after(div);
  }
</script>
Mogsdad
  • 44,709
  • 21
  • 151
  • 275
  • That makes it, although my solution was a bit different: I validated the form on client side. If validated, then close the sidebar and run the script on the server. –  Dec 04 '14 at 22:48
  • I can't make it work... no matter what I do, the sidebar is always closed. I'll open another question, thank you for your effort. –  Dec 10 '14 at 14:39
  • 1
    Note this comment: `.withSuccessHandler(google.script.host.close) // <-- No brackets after function name`. I was having problems with a modal dialog that was closing even on failure - the problem turned out to be that I had `google.script.host.close()`. There were no console logs indicating any problem. But once the brackets were removed, it all worked right. – Mogsdad Dec 10 '14 at 14:49
  • Yes, I've removed the brackets. You may see the new question here: http://stackoverflow.com/questions/27403944/how-to-call-function-from-serve-in-google-apps-script –  Dec 10 '14 at 14:51