1

I have a spreadsheet where I open a sidebar with the order details and then an alert asking if user is ready to send the mail. If the user chooses cancel I want to stop the whole script and close the sidebar. google.script.host.close is giving a Cannot read property "script" from undefined error. How would I simply close the sidebar without the use having to manually do so?

// Display a modal dialog box in sidebar with custom HtmlService content to preview the order.
   var htmlOutput = HtmlService.createHtmlOutput('<h1>'+ supplier + '</h1><br/>' +  previewOrder)
   .setTitle('Order Details');
   SpreadsheetApp.getUi().showSidebar(htmlOutput);

// now also show an alert asking if you want to send the mail
   var ui = SpreadsheetApp.getUi();
   var response = ui.alert('Confirm Sending','You are about to send this order to '+  supplier + ' (' + emailAddress + ') - are you sure?', ui.ButtonSet.YES_NO_CANCEL);

        // Process the user's response.
        if (response == ui.Button.YES) {
          var subject = "Order for Tomorrow ";
          MailApp.sendEmail(emailAddress,subject + dayname + " - " + Utilities.formatDate(tomorrow, "GMT+2", "d MMM") + "" ,emailBody, {to: emailAddress,cc: ccEmailAddress, htmlBody: emailBody});          

          }
        else  if (response == ui.Button.NO) {
          //if user chooses NO then ignore and continue the loop
        } else {
      //close the sidebar
          SpreadsheetApp.getUi().google.script.host.close();
          //cancel the script
          return;
        }
TheMaster
  • 45,448
  • 6
  • 62
  • 85
southafricanrob
  • 331
  • 3
  • 15
  • Why not put a button on the sidebar to preview the order and use a dialog box client side to preview the order then when they cancel the dialog you can close the side bar and the dialog at the same time. I use JQuery UI - Dialog a lot and they're fairly easy to use. If you need data from the server you can use google.script. run with the success handler to get the data. – Cooper Jan 07 '19 at 07:39
  • Does this answer your question? [How to show/hide loading spinner in addon sidebar while Google Picker dialog is opened/closed?](https://stackoverflow.com/questions/58179202/how-to-show-hide-loading-spinner-in-addon-sidebar-while-google-picker-dialog-is) – TheMaster Feb 28 '20 at 22:22

3 Answers3

2
  • You want to close the sidebar which has already been opened.
  • You want to achieve above by other function which is not the script of sidebar.

If my understanding is correct, how about this workaround? In this workaround, the sidebar is closed by overwritten with a temporal sidebar. I think that there are several workarounds for your situation. So please think of this as one of them.

Modified script:

When this is reflected to your script, the modified script becomes as follows.

var ui = SpreadsheetApp.getUi();
var response = ui.alert('Confirm Sending','You are about to send this order to '+  supplier + ' (' + emailAddress + ') - are you sure?', ui.ButtonSet.YES_NO_CANCEL);

// Process the user's response.
if (response == ui.Button.YES) {
  var subject = "Order for Tomorrow ";
  MailApp.sendEmail(emailAddress,subject + dayname + " - " + Utilities.formatDate(tomorrow, "GMT+2", "d MMM") + "" ,emailBody, {to: emailAddress,cc: ccEmailAddress, htmlBody: emailBody});
}
else  if (response == ui.Button.NO) {
  //if user chooses NO then ignore and continue the loop
} else {
  //close the sidebar

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

  //cancel the script
  return;
}

Note:

  • When this modified script is run while the main sidebar is not opened, the temporal sidebar is opened a moment. If you don't want to do this, for example, please set the existence of main sidebar with PropertiesService when the main sidebar is opened. Using this, when the main sidebar is not opened, the temporal sidebar can be prevented to be opened.

References:

If this workaround was not what you want, I'm sorry.

Tanaike
  • 181,128
  • 11
  • 97
  • 165
1

There's no direct way to close the Sidebar from the alert window. You can, however, use a workaround.

  1. When the user hits Cancel, set a property on the server side.

     PropertiesService.getDocumentProperties().setProperty("CLOSED", "CLOSED");
    
  2. In the Sidebar, set a timer that polls for this property value every second. If the returned value is CLOSED, close the sidebar.

    // Server side
    function checkClosedStatus() {
       var props = PropertiesService.getDocumentProperties();
       var value = props.getProperty("CLOSED");
       if (value === "CLOSED") {
         props.deleteProperty("CLOSED");
       }
       return value;
    }
    
    // Inside the sidebar html
    
    google.script
      .run
      .withSuccessHandler(function(e) {
             if (e === "CLOSED") 
                google.script.host.close();
     })
     .checkClosedStatus()
    
Amit Agarwal
  • 10,910
  • 1
  • 32
  • 43
  • Thanks. I am currently running the whole thing from a single script and don't have a separate Sidebar.html...could I include the last bit of your code in my script? – southafricanrob Jan 07 '19 at 07:06
1

I figured out that this solution works.

function example(formObject) {
  function onSucces(e) {
      google.script.host.close();
  }

  // Inside the sidebar html  
  var runner = google.script.run.withSuccessHandler(onSucces)
    .formHandlerFunction(formObject);

  return;
}  

Using a withSuccessHandler made the trick for me. I had issues where the google.script.host.close(); was executing before the rest of my script was done.