southafricanrob
southafricanrob

Reputation: 351

Close a Sidebar from alert button in Google App Script

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

Upvotes: 1

Views: 1826

Answers (3)

Guillaume M-D
Guillaume M-D

Reputation: 35

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.

Upvotes: 1

Tanaike
Tanaike

Reputation: 201553

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

Upvotes: 2

Amit Agarwal
Amit Agarwal

Reputation: 11278

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

Upvotes: 1

Related Questions