How to use scriptlets in HTMLOutput in Google Apps Script - html

I'm loading a modal dialog with:
var html = HtmlService.createHtmlOutputFromFile('File')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setWidth(1000)
.setHeight(700);
SpreadsheetApp.getUi()
.showModalDialog(html, 'My Page');
Now, in File.HTML, I want to load another HTML file with CSS settings, how do I do that?
I've tried including it as in HtmlTemplate using scriptlets but it doesn't work:
<?!= include('File'); ?>
EDIT:
I have defined the include function in code.gs:
function include (file) {
return HtmlService.createTemplateFromFile(file).evaluate().getContent();
}

The problem is that you are using:
createHtmlOutputFromFile
instead of:
createTemplateFromFile
You need to create a template:
This is what you are seeing:
The scriptlet is not running, but being interpreted as text.
This is what you want to see:
Here is how the code should be:
Code.gs
// Use this code for Google Docs, Forms, or new Sheets.
function onOpen() {
SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
.createMenu('Dialog')
.addItem('Open', 'openDialog')
.addToUi();
}
function openDialog() {
var html = HtmlService.createTemplateFromFile('index')
.evaluate();//This is necessary
SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
.showModalDialog(html, 'Dialog title');
}
function include(File) {
return HtmlService.createHtmlOutputFromFile(File).getContent();
};
index.html
<?!= include('File'); ?>
Hello, world!
<input type="button" value="Close"
onclick="google.script.host.close()" />
File.html
<div>
This is a test. it worked!
</div>
Basically, you need to change:
var html = HtmlService.createHtmlOutputFromFile('index')
to:
var html = HtmlService.createTemplateFromFile('index')
Create a TEMPLATE from file.
And I also changed the code to this:
function openDialog() {
var html = HtmlService.createTemplateFromFile('index')
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
Original answer:
include is not something like a keyword or a built in function. You need to create a function in a .gs script file named include.
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename).getContent();
};
Also, you can't mix the HTML Service and the UI Service. I don't know if that's what you are trying to do, but I thought I'd mention it.
What you want to accomplish is describe in the documentation here:
Documentation - Best Practices

Related

onOpen event does not not launch a dialog box

I have a sheet that I send out to staff (copies that are shared) but when I copy this the function onOpen does not launch the dialog box.
function onOpen() {
SpreadsheetApp.getUi()
}
function openDialog() {
var html = HtmlService.createHtmlOutputFromFile('Index');
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.showModalDialog(html, 'Math Sheet Directions');
}
Take a deep look on the next thread : onOpen not executing?
As you can see from the thread and Issue Tracker:
Google has restriction for onOpen functionality
Is there a different way to achieve your goal?
You can create a red button "Show URLs" and assign it a function.
For example:
function openDialogBox() {
// your html content here
var html = "<a href='https://google.com'>Google.com</a><br /><a href='https://stackoverflow.com'>Stackoverflow.com</a>" ;
var htmlOutput = HtmlService
.createHtmlOutput(html)
.setWidth(250)
.setHeight(300);
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'URL links');
}
This is how it looks like:
We don't have any restriction here.
I know this method doesn't help you, but probably this is the only way to achieve similar behavior of what you want to do :)
Reference
Google Apps Script - onOpen()
Google Apps Script - Class HtmlService
Google Apps Script Guide - HTML Service: Create and Serve HTML

Calling library function from html in that library

In order to share with my colleagues the AppsScript code I am developing, I created a standalone project used as a library in our Docs template.
This library contains:
a .gs file for the server side code
a .html file for the client side sidebar
In the sidebar, I have a button which triggers a call to a function from the library with a parameter.
The javascript call is the following:
google.script.run
.withFailureHandler(
function(msg, element) {
showError(msg, $('#button-bar'));
})
.test();
I read on other pages that the library code wasn't exposed so the test function is in fact in the AppsScript code of my Docs and calls the equivalent library function.
As it was suggested here: Can a Google Spreadsheet Apps Script library contain a user dialog?
Code in the Docs AppsScript:
function test()
{
myLibrary.test();
}
Code in myLibrary library:
function test()
{
DocumentApp.getUi().alert('test');
}
The problem is that the failure handler from the javascript returns a ScriptError stating that I need to have the authorization to perform this action.
Any ideas of what I am doing wrong?
PS: I know I could make an add-on but this is not something I can easily do inside my company :)
Yes, when you use the html code (sidebar) from your library it'll call the test() function inside the script bound to the document rather that the one in the library.
You need to request permission to the user to be able to prompt UI elements, you can do this with a custom menu [1].
Also, the users need to have at least read access on the library [2]. I add the withSuccessHandler function [3] to show the response from client-side in the sidebar. The following code worked for me:
Script bound to the document:
function onOpen() {
DocumentApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.createMenu('Custom Menu')
.addItem('Show sidebar', 'showSidebar')
.addToUi();
}
function showSidebar() {
myLibrary.showSidebarLibrary();
}
//
function test() {
myLibrary.test();
}
Library:
code.gs
function showSidebarLibrary() {
var html = HtmlService.createHtmlOutputFromFile('Page')
.setTitle('My custom sidebar')
.setWidth(300);
DocumentApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.showSidebar(html);
}
function test() {
DocumentApp.getUi().alert('test');
return "Success";
}
Page.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
Hello, world!<br>
<input type="button" value="Alert" onclick="alert()" /><br>
<input type="button" value="Close" onclick="google.script.host.close()" />
<p id="msg">Replace message with response<p>
</body>
<script>
function alert() {
google.script.run.withFailureHandler(handler).withSuccessHandler(handler).test();
}
function handler(msg) {
document.getElementById("msg").innerHTML = msg;
}
</script>
</html>
[1] https://developers.google.com/apps-script/guides/menus
[2] https://developers.google.com/apps-script/guides/libraries#gaining_access_to_a_library_and_including_it_in_your_project
[3] https://developers.google.com/apps-script/guides/html/communication#success_handlers

How to call Google Apps Script encapsulated function from html template

Hi I am using Google App Scripts on a Google Sheet and I wanted to organize my code, so I tried encapsulating some of the functions. However, I can't seem to figure out how to call the encapsulated functions from the html templates.
Does anyone know if it is possible to call an encapsulated function with google.script.run from an html template?
Example:
Code.gs
function onOpen(e){
var menu = SpreadsheetApp.getUi().createMenu('Document Routing')
.addItem('View/Edit My Routes', 'ViewMyRoutes')
.addToUi();
}
function ViewMyRoutes() {
var html = HtmlService.createHtmlOutputFromFile('MyRoutes')
.setTitle('My Routes')
.setWidth(300);
SpreadsheetApp.getUi()
.showSidebar(html);
}
User.gs
var User = function(){
return {
GetMyRoutes: function (){
var userProperties = PropertiesService.getUserProperties();
var routeData = userProperties.getProperty("SpreadsheetRoutes");
return routeData;
}
};
}();
Sample.html
<h1>Edit Route</h1>
<select id="EditRoute" onchange="LoadSelectedRoute()"></select>
<div id='divRoutes'></div>
<script>
function LoadEditDropDown(){
google.script.run
.withFailureHandler(onFailure)
.withSuccessHandler(OnGetRoutesSuccess)
.User.GetMyRoutes();
function OnGetRoutesSuccess(scriptProperties){
//do stuff with scriptProperties here
}
}
LoadEditDropDown();
</script>
How about this? In such case, I use this way. But I don't know whether this is the best way. I'm sorry. I worry about that this may be the opposite way for you want.
1. Please add this function to GAS
function UserGetMyRoutes() {
return User.GetMyRoutes();
}
2. Please modify google.script.run as follows
From :
google.script.run
.withFailureHandler(onFailure)
.withSuccessHandler(OnGetRoutesSuccess)
.User.GetMyRoutes();
To :
google.script.run
.withFailureHandler(onFailure)
.withSuccessHandler(OnGetRoutesSuccess)
.UserGetMyRoutes();

Google scripts, change text in Form.html from Code.gs

In my Google Script I have 2 files: Form.html and Code.gs
When user click button in Form.html, the script start code in Code.gs, but I need inform user about process.
How I can change text in Form.html from Code.gs?
Form.html crate in Code.gs by this function:
function showSidebar() {
var ui = HtmlService.createHtmlOutputFromFile('Form')
.setTitle('Report');
SpreadsheetApp.getUi().showSidebar(ui);
}
And Form.html have
<div id="report"></div>
For status report.
What you need to do is use templated HTML, see: https://developers.google.com/apps-script/guides/html/templates
Example:
function showSidebar() {
var ui = HtmlService.createTemplateFromFile('Form');
ui.message = "Hello!";
ui = ui.evaluate().setTitle('Report');
SpreadsheetApp.getUi().showSidebar(ui);
}
And in Form.html:
<div id="report"><?=message?></div>

In Google Shreadsheet I have a created a new menu which opens a dialog and a sidebar. I want to be able to open the dialog from the sidebar

Sidebar is html.
Figured I could just link a button to the function that originally opens the dialog from the menu, but no luck...doesn't do anything. Wondering whether it could be because function call is now in an html file not in the actual spreadsheet? Maybe?
Here is code for sidebar:
<input type="button" value="New Booking" onclick="newContact()" ><p>
<script>
function newContact() {
var html = HtmlService.createHtmlOutputFromFile('Experimental')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setWidth(1050);
//.setHeight(800);
SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
.showModalDialog(html, 'New Contact');}
</script>
The HtmlService code needs to be run from a google script (.gs) file. It won't work in standard javascript as you have it set up in your question. From html and javascript, you can run .gs function with google.script.run.newContact(). Of course you can replace newContact with any .gs function you want to run.
.gs code
function sideBar(){
var html = HtmlService.createHtmlOutputFromFile('index')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setTitle('My custom sidebar')
.setWidth(300);
SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
.showSidebar(html);
}
function newContact() {
var html = HtmlService.createHtmlOutputFromFile('New Contact')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setWidth(1050);
//.setHeight(800);
SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
.showModalDialog(html, 'New Contact');
}
Index.html
<div>
<input type="button" value="New Booking" onclick="google.script.run.newContact()" ><p>
</div>
New Contact.html
<div style="width:50px; height:50px; color:red;">
</div>