Open an Iframe in a modal popup in Google sheets - google-apps-script

I want to open a modal pop up in Google sheets
I have in code.gs:
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('Custom Menu')
.addItem('Open Dialog Box', 'openDialog')
.addToUi();
}
function openDialog() {
var html = HtmlService.createHtmlOutputFromFile('index');
SpreadsheetApp.getUi()
.showModalDialog(html, 'Correct Postcode Errors');
}
In index.html
<!DOCTYPE HTML>
<HTML>
<body>
<iframe src="https://www.w3schools.com" title="W3Schools Free Online Web Tutorials"></iframe>
</body>
</html>
I get the popup but the Iframe does not connect
How to get the Iframe to connect?
Here is a Google sheet with the above code
https://docs.google.com/spreadsheets/d/1LHiTZB225jFnOdzflUkm0ZSO6Wy_XQ_0OJ9WwAk46dA/edit?usp=sharing
Thanks

www.w3schools.com refused to connect.
It tells that they refused to connect because they don't want you to iframe their website.

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

Launch Google Form via Appscript as a Custom menu

I am trying to launch a Google Form that I created from a Google Sheet, via App Script. The script does not work and I am not sure what needs to be done to fix it. Here is the script:
function onOpen() {
var ui = SpreadsheetApp.getUi();
// Or DocumentApp or FormApp.
ui.createMenu('Custom Menu')
.addItem('Edit/Delete', 'menuItem1')
.addSeparator()
.addItem('New Entry', 'menuItem2')
.addToUi();
}
function menuItem1() {
SpreadsheetApp.getUi () // Or DocumentApp or FormApp.
.alert('You clicked the first menu item!');
}
function menuItem2() {
// Open a fom. var form = FormApp.openByUrl('https://docs.google.com/forms/d/e/1FAIpQLSfYrw3nwiYt6p8bPEqyV0GD8hpnaFOfa1i4LHYMo01GPPM6dQ/viewform');
}
This is how I would approach this task. My Code.gs would like like this. It opens a mini modal. Let me know what you think.
function onOpen() {
var ui = SpreadsheetApp.getUi();
// Or DocumentApp or FormApp.
ui.createMenu('Custom Menu')
.addItem('Edit/Delete', 'menuItem1')
.addSeparator()
.addItem('New Entry', 'menuItem2')
.addToUi();
}
function menuItem1() {
SpreadsheetApp.getUi () // Or DocumentApp or FormApp.
.alert('You clicked the first menu item!');
}
function menuItem2() {
// Here register an HTML template that will render a modal/popup.
// 'form' is the name of a new 'form.html' file
var htmlOutput = HtmlService.createHtmlOutputFromFile('form')
.setWidth(250)
.setHeight(50)
// Here call the modal/pop to open when the menu button 'MenuItem2' is
// clicked
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Form');
}
I would then have another html file call "form.html" which will render a modal when it is called.
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
Open Form
<!-- Below is an HTML trick to open a url in a new tab automatically -->
<!-- change the action url to any that is needed -->
<!-- foo can be any string -->
<form action='http://example.com' method='get' id='foo'></form>
<script>document.getElementById('foo').submit();</script>
</body>
</html>
The file structure in the Appscript should look like this:

Cannot find custom menu and sidebar in the published add-on

I am trying to publish a Google Sheet add-on with the unlisted option: Only people with the link can see it. Here is the code: Code.gs:
function myFun() {
return "myFunValue"
}
function onInstall() {
onOpen()
}
function onOpen() {
var html = HtmlService.createHtmlOutputFromFile('Index.html') //your html page name
.setTitle('My custom sidebar')
.setWidth(300);
SpreadsheetApp.getUi().createAddonMenu()
.addItem('Use in this spreadsheet', 'use')
.addToUi();
SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
.showSidebar(html);
}
function use() {
var title = 'Date Custom Functions';
var message = 'Message of use';
var ui = SpreadsheetApp.getUi();
ui.alert(title, message, ui.ButtonSet.OK);
}
Index.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
super add-on, with custom function "=myFun()" and custom menu
</body>
</html>
Here is the link:
https://chrome.google.com/webstore/detail/functionmenuside/bmojfiljhggogegocdkjdlaoohbkcmod?authuser=0
This add-on works on its own Google Sheet. However, after publishing, when I click on +Free, it opens a new Google Sheet, I can find FunctionMenuSide in the Add-ons. The custom function works, whereas there is no sidebar, and we cannot find the custom menu Use in this spreadsheet. It seems that onOpen is not executed.
Does anyone know how to fix this?
Edit 1:, in the console, there are messages:
1739997376-ritz_waffle_integrated_i18n_ritzmaestro.js:105 Google Apps Script: You do not have permission to call createHtmlOutputFromFile.
You are trying to open the sidebar in the onOpen() function. This won't work because of the way that simple triggers work with Google Apps Script.
Instead, create another function that opens the sidebar and adds that function as an item in your add-on menu. Then your user can open the sidebar themselves from the add-on menu.

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>