Home > front end >  Pass a parameter from GAS to HTML
Pass a parameter from GAS to HTML

Time:12-12

I have been researching how to do this and have come across examples of using a Template or coding inline. In either case, i must not be understanding something fundamental.

In a script being called from a Google Spreadsheet, I determine how many lines are current selected. I want to place this as the default value on a Modal Dialog. I just cannot figure out how to do this.

Any help would be appreciated!

This is the script code:

function AddOn_More(){
  var data,idData,numlines,sht,ss,strAppend,widget;

  // need to pass the number of selected rows as a default for numlines
  ss = SpreadsheetApp.getActiveSpreadsheet();
  sht = ss.getActiveSheet();
  numlines = sht.getActiveRange().getValues().length; // the number of rows selected

  widget = HtmlService.createHtmlOutputFromFile("EnhancementsLocation.html")
    .setSandboxMode(HtmlService.SandboxMode.IFRAME)
    .setTitle('sample')
    .setHeight(450)
    .setWidth(550);
  // data can be any (serializable) javascript object.
  // if your data is a native value (like a single number) pass an object like {num:myNumber}
  data = {num:numlines};
  idData = "NumLines";

  //now append to widget
  // data is encoded after stringifying to guarantee a safe string that will never conflict with the html.
  // downside: increases the storage size by about 30%. If that is a concern (when passing huge objects) you may use base94
  // or even base128 encoding but that requires more code and can have issues, see http://stackoverflow.com/questions/6008047/why-dont-people-use-base128
  strAppend="<div id='" idData "' style='display:none;'>"   Utilities.base64Encode(JSON.stringify(data))    "</div>";
  widget.append(strAppend);
  SpreadsheetApp.getUi().showModalDialog(widget,"dineDK");
}

And this is the HTML source:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <style>
      .button {
        background-color: blue;
        color: white;
        padding: 10px;
        border: none;
        border-radius: 5px;
      }
      p.Lato{font-size: 20px; font-family: Lato,Arial,serif;}
    </style>
    <script>
      function getDataFromHTML() { // returns the stored object
        var idData = "NumLines";
        var dataEncoded = document.getElementById(idData).innerHTML;
        var data = JSON.parse(atob(dataEncoded));
        return data;
      }
      function initialize() {
          var data = getDataFromHtml();
          document.getElementById("LineCount").innerText = data; <!-- '.first   " - "   data.last' -->
      }
    
      // use onl oad or use jquery to call your initialization after the document loads
      window.onload = initialize;
    </script>
    <h1 style="font-family: Arial">ADDITIONAL ENHANCEMENTS</h1>
    <form style="font-family: Arial">
        The number of lines to be added <input type=number id="LineCount" value="1" min="1" max="10"  step="1"><!-- value=1  -->
        <?= data.first ?><br><br>
        <p>Where in the ENHANCEMENTS Section should the new lines be placed?</p>
        <pre style="font-family: Arial">
              <input type="radio" name="location" value="START">START of Section<br>
              <input type="radio" name="location" value="ABOVE">ABOVE Current line<br>
              <input type="radio" name="location" value="BELOW">BELOW Current line<br>
              <input type="radio" name="location" value="END" checked>END of Section<br>
          <!-- create the SUBMIT and CANCEL buttons -->
          <br>                <input type="button"  value="SUBMIT" onclick="google.script.run.AddOn_More_Location(location,numlines);google.script.host.close();">
        </pre>
    </form>
  </body>
</html>

CodePudding user response:

The easiest way to push Apps Script variable values to an HTML file is to use templated HTML, like this:

function AddOn_More() {
  const range = SpreadsheetApp.getActiveRange();
  const template = HtmlService.createTemplateFromFile('EnhancementsLocation.html')
  // set the values of the <?= numLines ?> and <?= idData ?> printing scriptlets in EnhancementsLocation.html
  template.numLines = range.getHeight();
  template.idData = 'numLines';
  const dialogBox = template
    .evaluate()
    .setTitle('sample')
    .setHeight(450)
    .setWidth(550);
  SpreadsheetApp.getUi().showModalDialog(dialogBox, 'dineDK');
}

In EnhancementsLocation.html, use printing scriptlets, like this:

within <script> tags:

   const numLines = <?= numLines ?>;
   const idData = "<?= idData ?>";

within HTML code:

   <b><?= numLines ?></b>
   <b><?= idData ?></b>

Another way is to use google.script.run within HTML <script> tags to call a server-side function that returns the values within a JavaScript object. Note that the object gets serialized on the way, so you cannot pass a Date object as is. Use a text string representation for Date objects if they are needed.

CodePudding user response:

In case anyone is interested the final gs file looks like this:

function AddOn_More(){
  const range = SpreadsheetApp.getActiveRange();
  const widget = HtmlService.createTemplateFromFile('EnhancementsLocation.html');
  // set the values of the <?= numLines ?> and <?= idData ?> printing scriptlets in EnhancementsLocation.html
  widget.numLines = range.getHeight();
  widget.idData = 'numLines';
  SpreadsheetApp.getUi().showModalDialog(widget.evaluate().setHeight(450).setWidth(550), 'dineDK');
}
  • Related