1

I want to combine a few related HTMLService interface in to a tabbed page. I can get the tabs working using the code here. But I want to put the page for each Tab into a different html file in the project. How would I show Billets.html inside the div below? Basically replacing "Put the Billet Locations here" with the contents of the html file. My goal is to have a Main.html file that is loaded and shows Tabs for various tasks, using different files for the contents of each Tab to better organize the Project. Iam also looking to have each item load in the most efficient manor, meaning either loaded when the tab is selected (it may never be selected by a given user) or loading it all at the onset.

<div id="tabs-2">
  <p>Put the Billet Locations App here</p>
</div>
Community
  • 1
  • 1
Karl_S
  • 3,364
  • 2
  • 19
  • 33

1 Answers1

2

Two basic strategy's would be:

  • Inject all the HTML when your page first loads
  • Inject HTML after the page loads, (like when the user clicks a tab)

The first strategy can be accomplished with scriptlets:

HTML Service: Templating

index.html

//include is the name of a function
<div id="tabs-2">
  <?!= include("HTML_Tab2"); ?> //HTML_Tab2 is name of HTML file
</div>

code.gs

doGet() {
  var template = HtmlService.createTemplateFromFile("index");

  return template
    .evaluate() // evaluate MUST come before setting the sandbox mode
    .setTitle("nameOfApp")
    .setSandboxMode(HtmlService.SandboxMode.IFRAME); //Also NATIVE
};

function include(filename) {
  return HtmlService.createHtmlOutputFromFile(filename).getContent();
};

In order for the scriptlet to run correctly, the HtmlService method createTemplateFromFile() must be used. Because the index.html file has a scriptlet in it, it's a template.

The other option would involve making a separate google.script.run call to the server, getting the HTML, returning it, then using client side javascript to inject the HTML into that P tag.

Reference Guide- Google Documentation - Client side API

For that option, you would need to use something like a DOM property innerHTML or textContent to inject the HTML.

Documentation innerHTML - Mozilla

Alan Wells
  • 30,746
  • 15
  • 104
  • 152
  • Thank you! Using the Template method: Setting the SandboxMode to IFRAME breaks the tabs. If I keep it NATIVE the tabs work and the second file is Included. So I either need to figure out the tabs or see if NATIVE breaks anything. I also need to work on the layout of the Included page. It was created for a different output size so I need to better define the layout. – Karl_S Jun 18 '15 at 17:42
  • Method one is proving to be a less than ideal solution as the injected HTML will vary too much based on some settings. Is there a way to include runable script in the injected HTML if using method 2? – Karl_S Mar 09 '16 at 20:03
  • Good question. If you inject client side script in a `` tag ***after*** the page is loaded, I don't think that you can get that code to run directly. But, you can take JavaScript code, and then use `new Function()` to create a function, and then run it. The code that creates the new function, would need to be loaded at the very beginning. See Function() Constructor [Link to some information](http://www.w3schools.com/js/js_function_definition.asp) – Alan Wells Mar 09 '16 at 20:12
  • "The code that creates the new function, would need to be loaded at the very beginning." - Beginning of what? the 'new Function' appears nameless so my limited knowledge doesn't tell me how to access multiple functions from the injected HTML. Right now it may be easier to have client side functions named unique to each injected HTML Article and load them all at the beginning. I was hoping to load/unload it with the changing DOM Property. (Prior to my last comment I confirmed that script in a '' tag in the injected HTML does not work. My apologies for not mentioning this.) – Karl_S Mar 09 '16 at 20:31
  • very beginning = when the HTML is first loaded. That only happens once unless the sidebar or dialog is reopened, or HTML is served to a browser tab, with a web app. – Alan Wells Mar 10 '16 at 18:24
  • I can get an HTML file with only script to load as per the above `include()` func. If I have an `alert();` line outside of any functions in this included file, the line runs. I cannot seem to call my custom functions loaded this way, though. I have used both `HtmlService.createHtmlOutputFromFile(filename).getContent();` and `HtmlService.createHtmlOutputFromFile(filename).getRawContent();` I initially load the page via: `var template = HtmlService.createTemplateFromFile("template").evaluate().setTitle('My Title').setHeight(700).setWidth(1000).setSandboxMode(HtmlService.SandboxMode.NATIVE);` – Karl_S Mar 11 '16 at 16:06
  • You are asking a different question than the one posted here. It's better to post a new question. – Alan Wells Mar 11 '16 at 16:39