Search code examples
javascripthtmlgoogle-apps-scriptgoogle-sheetsinclude

Why does the html output include <?!= include('foo.html') ?> instead of the file being included?


I'm similarly seeing

<?!= include('WebAppScript.html') ?> 

rather then the script actually being included. There's an include function in Code.gs and I've tried a few variations with doGet but cannot find the precise method to tie together webApp.html with WebAppScript.html as when it was a single file.

Why is this include statement from the header showing in the output?

include WebAppScript

The Code.gs file:

const id = "####";


function doGet(e) {
  Logger.log(id);
  Logger.log(e);

  //return HtmlService.createTemplateFromFile('WebApp').evaluate();
  return HtmlService.createHtmlOutputFromFile('WebApp');
}

function AddRecord(firstname, lastname) {
  Logger.log(firstname);
  Logger.log(lastname);
  var sheet = SpreadsheetApp.openById(id).getSheetByName("alpha");
  sheet.appendRow([firstname, lastname, new Date()]);
}

function include(filename) {
  Logger.log(filename);
  return HtmlService.createOutputFromFile(filename).getContent();
}

The WebApp.html file:

<!DOCTYPE html>
<html>

<head>
  <base target="_top">
  <?!= include('WebAppScript.html') ?>
</head>

<body>
  First Name:<input type="text" id="firstname" />
    Second Name:<input type="text" id="lastname" />
  <input type="button" value="Add" onclick="AddRow()" />
</body>

</html>

The WebAppScript.html file:

<script>
  function AddRow()
    {
      var firstname = document.getElementById("firstname").value;
      var lastname = document.getElementById("lastname").value;
      google.script.run.AddRecord(firstname, lastname);
      document.getElementById("firstname").value = '';
      document.getElementById("lastname").value = '';
    }
</script>

Which I've tried both with and without the script tag.

Is the doGet function calling the correct html generation functions? Are the file names being referenced correctly? WebAppScript or WebAppScript.html, for example? Should there be a script tag wrapping the AddRow function?

Perhaps I'm not using templates correctly.

Possibly there are some Google App Script peculiarities versus standard java Script.

Most notably, nothing is written to the spreadsheet when the "add" button is clicked. It seems likely that this is connected with the unnecessary output.


Solution

  • In your script, I think that there are 2 modification points.

    Modification points:

    • In doGet, please use return HtmlService.createTemplateFromFile('WebApp').evaluate(); instead of HtmlService.createHtmlOutputFromFile('WebApp');.

    • In include, please modify return HtmlService.createOutputFromFile(filename).getContent(); to return HtmlService.createHtmlOutputFromFile(filename).getContent();. Please modify createOutputFromFile to createHtmlOutputFromFile.

    When these points are reflected in your script, it becomes as follows.

    Modified script:

    Code.gs

    This was modified.

    const id = "####";
    
    function doGet(e) {
      Logger.log(id);
      Logger.log(e);
    
      return HtmlService.createTemplateFromFile('WebApp').evaluate();
      // return HtmlService.createHtmlOutputFromFile('WebApp');
    }
    
    function AddRecord(firstname, lastname) {
      Logger.log(firstname);
      Logger.log(lastname);
      var sheet = SpreadsheetApp.openById(id).getSheetByName("alpha");
      sheet.appendRow([firstname, lastname, new Date()]);
    }
    
    function include(filename) {
      Logger.log(filename);
      return HtmlService.createHtmlOutputFromFile(filename).getContent();
    }
    

    WebApp.html

    This is not modified.

    <!DOCTYPE html>
    <html>
    
    <head>
      <base target="_top">
      <?!= include('WebAppScript.html') ?>
    </head>
    
    <body>
      First Name:<input type="text" id="firstname" />
        Second Name:<input type="text" id="lastname" />
      <input type="button" value="Add" onclick="AddRow()" />
    </body>
    
    </html>
    
    • By the way, in this case, I think that both <?!= include('WebAppScript.html') ?> and <?!= include('WebAppScript') ?> can be used.

    WebAppScript.html

    This is not modified.

    <script>
      function AddRow()
        {
          var firstname = document.getElementById("firstname").value;
          var lastname = document.getElementById("lastname").value;
          google.script.run.AddRecord(firstname, lastname);
          document.getElementById("firstname").value = '';
          document.getElementById("lastname").value = '';
        }
    </script>
    

    or, how about using withSuccessHandler as follows?

    <script>
      function AddRow()
        {
          var firstname = document.getElementById("firstname").value;
          var lastname = document.getElementById("lastname").value;
          google.script.run.withSuccessHandler(_ => {
            document.getElementById("firstname").value = '';
            document.getElementById("lastname").value = '';
          }).AddRecord(firstname, lastname);
        }
    </script>
    

    References: