How to show/hide loading spinner in addon sidebar while Google Picker dialog is opened/closed?

后端 未结 1 967
-上瘾入骨i
-上瘾入骨i 2020-12-01 23:21

I followed this tutorial: https://developers.google.com/apps-script/guides/dialogs#file-open_dialogs and I can open a Google Picker after clicking a button inside my addon s

相关标签:
1条回答
  • 2020-12-01 23:50

    Issue:

    Sidebar and modal dialog are not able to communicate despite having same origin.

    Solution:

    It is possible to get a reference to the sidebar html from modal dialog through window.top. From there, it is possible to

    • directly communicate with each other
    • use window.postMessage() to communicate with each other
    • use cookies/localstorage to communicate with each other

    Without a reference to each other, it is still possible to communicate with each other through

    • the server and script properties service. However, Here, one of them needs to poll the server at set intervals to get any updates from the other.

    Sample script(using direct access):

    addOn.html

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width" />
        <title>Addon</title>
        <style>
          #spinner {
            display: none;
            background-color: tomato;
            position: absolute;
            top: 1%;
            width: 100%;
            justify-items: center;
          }
        </style>
      </head>
      <body>
        <div id="spinner"><p>Loading modal dialog...</p></div>
        <div id="output"></div>
        <script charset="utf-8">
          google.script.run.withSuccessHandler(spinner).testModal();
          function spinner(e) {
            document.getElementById('spinner').style.display = e || 'flex';
          }
          (async () => {
            //After modal dialog has finished, receiver will be resolved
            let receiver = new Promise((res, rej) => {
              window.modalDone = res;
            });
            var message = await receiver;
            document.querySelector('#output').innerHTML = message;
            //Do what you want here
          })();
        </script>
      </body>
    </html>
    

    modalAddOn.html

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <title></title>
      </head>
      <body>
        Modal Dialog
        <script>
          (function findSideBar(limit) {
            let f = window.top.frames;
            for (let i = 0; i < limit; ++i) {
              try {
                if (
                  f[i] /*/iframedAppPanel*/ &&
                  f[i].length &&
                  f[i][0] && //#sandboxFrame
                  f[i][0][0] && //#userHtmlFrame
                  window !== f[i][0][0] //!== self
                ) {
                  console.info('Sidebar found ');
                  alert('Removing loadbar and closing self');
                  var sidebar = f[i][0][0];
                  sidebar.spinner('none'); //Remove sidebar spinner
                  sidebar.modalDone('Modal says Hi'); //Modal has finished
                  google.script.host.close();
                }
              } catch (e) {
                console.error(e);
                continue;
              }
            }
          })(10);
        </script>
      </body>
    </html>
    

    code.gs

    function testModal() {
      SpreadsheetApp.getUi().showModelessDialog(
        HtmlService.createHtmlOutputFromFile('modalAddOn')
          .setHeight(500)
          .setWidth(300),
        ' '
      );
    }
    
    function onOpen(e) {
      SpreadsheetApp.getUi()
        .createMenu('Sidebar')
        .addItem('Show Add-On', 'showSidebar')
        .addToUi();
    }
    
    function showSidebar() {
      SpreadsheetApp.getUi().showSidebar(
        HtmlService.createTemplateFromFile('addOn.html').evaluate()
      );
    }
    

    To Read:

    • Window#frames
    • Window#postMessage
    • Same origin policy
    • Document#cookie
    • Window#storage
    • Promises
    • PropertiesService

    Related questions:

    • Where is my iframe in the published web application/sidebar?

    • Window#postMessage

    • Window#storage

    • Origin

    0 讨论(0)
提交回复
热议问题