Home > Blockchain >  How to refresh a card from modal HTML dialog boxes?
How to refresh a card from modal HTML dialog boxes?

Time:10-01

I am building a Workspace add-on (in contrast to an Editor add-on). I have successfully created a modal dialog box using the following code:

  var html = HtmlService.createHtmlOutputFromFile('dialog.html')
      .setWidth(600)
      .setHeight(425)
      .setSandboxMode(HtmlService.SandboxMode.IFRAME);
  SpreadsheetApp.getUi().showModalDialog(html, 'Some title here...');

I can successfully call an Apps Script (server side) function from the dialog.html JavaScript using this syntax:

google.script.run.withFailureHandler(showError).withSuccessHandler(closeThisWindow).onAppsScriptFunction(p1, p2);

On the Apps Script side, I have the function that receives the arguments (p1, p2) from the JavaScript function:

function onAppsScriptFunction(p1, p2) {
  console.log(p1   p2);

  // the following does not work
  // it simply does nothing
  return CardService.newCardBuilder()
      .addSection(
        CardService.newCardSection().addWidget(
          CardService.newTextParagraph().setText("This never appears")
          )
      )
      .build();
}

Everything works as expected, except -- the card is not updated/refreshed. I have digged through all the Apps Script documentation and I don't see how can I refresh the sidebar or card. Is there a way to initiate a refresh / redraw / restart / anything from the client-side JavaScript. I also tried various combinations with CardService.newActionResponseBuilder() and setStateChanged(true) and setNavigation but nothing works.

Or if that's not possible, at least somehow visually act after a user closes the Modal HTML dialog?

CodePudding user response:

You can only update the card from a context of an Addon trigger

In your case onAppsScriptFunction is not linked to the Addon and thus cannot update the content of the Addon sidebar.

A workaround would be to deploy your modal dialog as a WebApp.

Code.gs

function onAppsScriptFunction(p1, p2) {
  console.log(p1   p2);  
  var props = PropertiesService.getScriptProperties();
  props.setProperty("update", "yes");
  
}

function onHomepage() {  
  var props = PropertiesService.getScriptProperties();
  var update = props.getProperty("update");
  if(update == null || update == "no"){   

    var url =ScriptApp.getService().getUrl(); 
  
    var button = CardService.newTextButton()
    .setText("Open modal dialog as WebApp")
    .setOpenLink(CardService.newOpenLink()
                 .setUrl(url)
                 .setOnClose(CardService.OnClose.RELOAD_ADD_ON));   
    var buttonSet = CardService.newButtonSet().addButton(button)    
    return CardService.newCardBuilder()
            .addSection(CardService.newCardSection().addWidget(buttonSet))
    .build();
    
  }  
  else{
    props.setProperty("update", "no");
    return CardService.newCardBuilder()
            .addSection(CardService.newCardSection()
              .addWidget(CardService.newTextParagraph().setText("This now appears")))
    .build();
  }
}

function doGet(){
  var html = HtmlService.createHtmlOutputFromFile('dialog.html')
  .setWidth(600)
  .setHeight(425);
  
  return html; 
}

dialog.html:

<html>
  <script>
    google.script.run.withSuccessHandler(success).onAppsScriptFunction(100, 150);
    function success() {
      window.top.close();
    }
  </script>
</html>
  • After deploying your code as a WEbApp this sample snippet will update your Addon sidebar as desired after the opened window is closed again.
  • Please mind that depending on your use case you need to decide how to deploy the WebApp and which of the PropertiesServices is the most suitbale for you (script, user or document properties).
  • Related