Embedding a Google Doc in Google Sheets - google-apps-script

I've developed a rather complex Google Sheets and hoping to embed user documentation directly into the Google Sheets. While I can certainly write the documentation directly in Google Sheets, I'd prefer to do it in a Google Document (The Word-like clone, just to be clear) and embed in the Google Sheet.
Some kind of onOpen script would be great if there is no native solution. Thank you!

This will add a menu to your spreadsheet where a user can choose Show instructions.
First, add the code below into the appropriate files in the code editor from your spreadsheet.
Tools > Script editor
Code.gs
function onOpen() {
SpreadsheetApp
.getUi()
.createMenu('My Menu')
.addItem('Show instructions', 'showInstructions')
.addToUi();
}
function showInstructions() {
var html = HtmlService
.createHtmlOutputFromFile('instructions')
.setWidth(1500)
.setHeight(800);
SpreadsheetApp.getUi().showModalDialog(html, ' ');
}
You'll have Code.gs to start with. Here's how to add instructions.html.
instructions.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<div style="text-align:center;">
<iframe width="1050" height="550" style="border: 0" src="COPIED_LINK_HERE?embedded=true&widget=false&chrome=false&headers=false"></iframe>
</div>
</body>
</html>
Follow the steps in the image below to obtain your URL.
Then paste that URL in instructions.html where the text COPIED_LINK_HERE is.
You may have to play with the height and width values in both to make it fit your needs.

Related

Bring up html file from sheets using apps script

I would like to have a google sheet that when you pick something on a google sheet it brings up an html file on a new google tab that has info from the google sheet. I am using the code below as a quick test to see if this is possible.
Right now I have a menu item that calls myFunction(), then I would like that to bring up the new html page. This doesn't come close to working, as it just enters and exits myFunction and no html page. So was wondering if anyone knows if this is possible. If so can you give me some hints on how to do it.
code.gs
function myFunction(){
HtmlService.createTemplate('page');
};
page.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<title>Hello<\title>
</body>
</html>
Change myFunction() to doGet(), and you need to return the HtmlService from the doGet function. Also, the statement inside the doGet() function is different than what you currently have.
Your myFunction() function should look like this
function doGet() {
return HtmlService.createTemplateFromFile('page').evaluate();
}
doGet() is a special function that Google Apps Script web app scripts should handle any GET requests.
For more information, please refer to one of these guides:
https://developers.google.com/apps-script/guides/html/templates
https://developers.google.com/apps-script/guides/html
This is absolutely possible.
What you want to implement is a web app.
Simple Example
function doGet() {
textOutput = ContentService.createTextOutput("Hello World! Welcome to the web app.")
return textOutput
}
Put this in a script file and then deploy the script as a web app - instructions. The deploy process will give you a link with which you can visit the web app and see your text output.
What apps script does is that every time someone visits the URL, the doGet function is run.
HTML Example
function doGet(){
let HTMLString = "<style> h1,p {font-family: 'Helvitica', 'Arial'}</style>"
+ "<h1>Hello World!</h1>"
+ "<p>Welcome to the Web App";
HTMLOutput = HtmlService.createHtmlOutput(HTMLString);
return HTMLOutput
}
As you have already seen, HtmlService is what to use to serve up HTML.
Linking to Spreadsheet
The best way IMO to approach this is:
Create a spreadsheet.
Create the script from the spreadsheet menu - this ensures that the script and sheet are linked.
Decide how you want to present the information from the Spreadsheet and get it with something like:
let file = SpreadsheetApp.getActive(); // getActive only possible if script and sheet are linked
let sheet = file.getSheetByName("Sheet1");
let range = sheet.getDataRange();
let values = range.getValues();
Figure out how to translate that into HTML.
Write your doGet function.
Deploy
Profit!
Docs
Google Apps Script Web Apps
HTML Service
Spreadsheet Service

Run Apps Script Client Side on Google Form Submit

I'm currently trying to make a paperwork wizard using google forms and apps script. At the end of the form, I'm trying to run an Apps Script once the form submits and display a HTML window. I tried using FormApp.getUI()along with the apps event trigger, but I keep getting the error Exception: Cannot call FormApp.getUi() from this context. From other posts it seems like this error is because the trigger runs the script server side. Is there a way to run this script client-side so the HTML window can be displayed?
EDIT: Conditional Sections Google forms this question is different from the one I'm asking now.
EDIT2: Code
Code.gs
function myFunction() {
var lock = LockService.getScriptLock();
var html = HtmlService.createHtmlOutputFromFile('display');
FormApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.showModalDialog(html, " Let's check if you need to present!");
SpreadsheetApp.flush();
lock.releaseLock();
}
display.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<p>Test</p>
</body>
</html>
From the question:
At the end of the form, I'm trying to run an Apps Script once the form submits and display a HTML window.
This is not possible.
If you collected the respondent email address you could send them an email

google.script.run.function not working with Chrome V8

Here is my code for show a sidebar. When click at OK button, I will insert a new record to my sheet.
It works well when I disable V8 by Run->Disable new App Script .. V8.
When I enable V8, onClicked in Code.gs not fired anymore.
I have checked the V8 Runtime Overview but I didn't find anything.
Index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<button onclick="okClicked()"> OK </button>
<button onclick="close()">Close </button>
<script>
function okClicked(){
window.alert("A");
google.script.run.okClicked();
}
function close(){
google.script.host.close();
}
</script>
</body>
</html>
Code.gs
function showSidebar() {
var html = HtmlService.createHtmlOutputFromFile('Index')
.setTitle('My custom sidebar')
.setWidth(300);
SpreadsheetApp.getUi().showSidebar(html);
}
function okClicked(){
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Data");
sheet.appendRow(["A", "B"]);
}
Any help or suggestion would be great appreciated.
Someone posted an issue similar to createHtmlOutputFromFile and V8 on Google's Issue Tracker. You can check if this issue is adequate for your case and hit the Star to let them know you have the same issue.
If you believe that this issue does not correspond with yours, you can also create a new issue with your case there.
2021 Answer
FWIW, I found that Google Apps Script was erroring out like this when my partner and I were both logged into the same Google account.
We also found that this can happen when new features have been built into your Google Apps Script / Sheets backend code that require updated permissions that haven't been granted yet. It's a bit hacky, but I fixed this by:
Sharing the sheet with another account I own
Logging into that account, then trying to run the function
Agreeing to grant the permissions asked by Google Auth / Scopes in the dialog that follows

Google Spreadsheet Apps Script: Dialog box from HTML Service not loading when embedded

I am having an issue where I created a custom dialog that displays some very basic HTML output using the HTML Service. This works well in Google Sheets, but when I embed the editable google sheet into another website, the content will not load.
Using the inspector/console, I have learned that the issue may be related to "Refused to display {link} in a frame because it set 'X-Frame-Options' to 'sameorigin'." I have referenced https://developers.google.com/apps-script/guides/html/restrictions and believe I have followed all relevant instructions, but I have been unable to resolve this issue for a few weeks now
I am not a developer, just dabbling, so even just resources to learn more about how to approach this issue would be very welcome.
Below is my code. Thank you for your time!
HTML:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
Hello, world! <input type="button" value="Close" onclick="google.script.host.close()" />
</body>
</html>
GS:
function showDialog() {
var html = HtmlService.createHtmlOutputFromFile('showDialogPage')
.setWidth(400)
.setHeight(300)
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
.showModalDialog(html, 'My custom dialog');
}

Google Script Cannot call FormApp.getUi() from this context

I can't get the simple example copied from the google dev site to work.
The error is: Cannot call FormApp.getUi() from this context
I am NOT attempting to deploy this a web form/app but I am simple trying to run this via the editor!!!
Not sure what I'm doing wrong?!?!?!
The following has been pasted into index.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
Hello, World!
</body>
</html>
The following is pasted into Code.gs:
// Use this code for Google Docs, Forms, or new Sheets.
function onOpen() {
FormApp.getUi()
.createMenu('Dialog')
.addItem('Open', 'openDialog')
.addToUi();
}
function openDialog() {
var html = HtmlService.createHtmlOutputFromFile('Index');
FormApp.getUi()
.showModalDialog(html, 'Dialog title');
}
Answered my own question.
The script must be bound to a Form (which mine wasn't!)
So now I need to figure out how to create a Dialog for an Unbound script.
I don't think this is possible!
If I deploy it as a Web App then obviously I have no access to the user UI.
So how would I take the output from ContentService.createTextOutput() and cause a download of a file to occur?