How to call google script function from a HTML file? - google-apps-script

I have created a web page through the Html Services api in google apps script. In the script, I have one google script(.gs) file and two html files(.html). This script is published on web. To display html file on web I used following function in .gs file:
function doGet() { //Published on web
return HtmlService.createTemplateFromFile('<htmlFile_1>').evaluate();
}
function doProcess() {
return HtmlService.createTemplateFromFile('<htmlFile_2>').evaluate();
}
doGet() is returning this Html file on the web. Now I want to display another Html File by replacing this file. So, I used following in htmlFile_1:
//htmlFile_1.html
<html>
<head>
<script>
function loadMainHtmlPage(){
google.script.run.doProcess(); //calling another function in .gs file
setTimeout(function(){hello()},4000);
}
function hello(){
alert("hiii");
document.getElementById("loading").style.display="none";}
</script>
</head>
<body onload="loadMainHtmlPage();">
<div id="loading" style="display:block;">
<img src="http://commondatastorage.googleapis.com/kickoff/loading.gif"/>
</div>
</body>
</html>
This htmlFile_1 is not calling the doProcess(), that would return the htmlFile_2.'
Any suggestion to implement this?

You need to include an onSuccess (and optionally an onFailure) handler on this line of code
google.script.run.doProcess();
See below
Server code
function getSuperHero() {
return {name: "SuperGeek", catch_phrase: "Don't worry ma'am, I come from the Internet" };
}
Client code
<script>
function onSuccess(hero) {
alert (hero.catch_phrase);
}
google.script.run.withSuccessHandler(onSuccess).getSuperHero();
</script>

Related

How to have a html input correlate to a JavaScript variable?

I am new to Google Apps Scripts and am trying to begin running a JavaScript function in HTML and have input values set to js variables. I would use the variable to set the time for a trigger. I do not know how to do so and can't find anything helpful. I was trying to have it all in HTML because it seems even more complicated to have the function in a javascript file.
<script>
function setrange() {
ScriptApp.newTrigger('Start')
.timeBased()
.at(startdate)
.create();
}
</script>
<input type="datetime-local" id="startdate"/>
<input type="button" value="Submit?" onclick="setrange()">
I wrote the script in js and then copied it into the HTML file. The Start function is on the js file. The script does work with sample data on the js file. In theory, it should create the trigger on the date gathered from the input but I have yet to figure out how to do so in google apps script.
You are mixing server and client code. You can not run ScriptApp from the html client. You need to use google.script.run to run the server code getrange(). Here is an example. Note that startdate is passed as a string and needs to be converted to a Date object.
HTML_Test.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<input type="datetime-local" id="startdate">
<input type="button" value="Submit?" onclick="setrange()">
<script>
function setrange() {
try {
let startdate = document.getElementById("startdate").value;
google.script.run.setrange(startdate);
}
catch(err) {
alert(err);
}
}
</script>
</body>
</html>
Code.gs
function setrange(startdate) {
try {
let start = new Date(startdate);
ScriptApp.newTrigger('Start')
.timeBased()
.at(start)
.create();
}
catch(err) {
Logger.log(err);
}
}
Reference
HTML Service
google.script.run

Download a created Google Doc from a deployed web app

I've created a script that, when deployed as a web app, asks the user for some input, and creates and writes to a Google document.
Apparently, downloading the Google document from the script is not possible, and the next best thing seems to convert the doc and save it in My Drive.
I have tried this very simple approach, inspired by Convert Google Doc to PDF using Google Script Editior
Project is deployed as a web app
Code.gs:
function doGet() {
return HtmlService.createHtmlOutputFromFile('Index');
}
function editDoc(data) {
let doc = DocumentApp.create("Title");
let body = doc.getBody();
body.setText(data);
docblob = doc.getAs('application/pdf');
docblob.setName(doc.getName() + ".pdf");
let file = DriveApp.createFile(docblob);
}
Index.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form onsubmit="edit()">
<input type="text" id="input">
<input type="submit" id="sub" value="Submit">
</form>
<script>
function edit() {
google.script.run.editDoc(document.getElementById("input").value);
}
</script>
</body>
</html>
As a result, this adds a pdf to my google drive, which should be the pdf form of the created google doc, however it is blank.
I believe your goal as follows.
You want to create new Google Document including the value from the input tag.
And, you want to export the Google Document as a PDF file.
You want to achieve this using Google Apps Script.
Modification points:
I think that the reason of however it is blank is that the Document is not saved.
In order to download the PDF file, I would like to propose to convert the PDF data to the base64 data and set it as the data URL, and then, download it.
When above points are reflected to your script, it becomes as follows.
Modified script:
Google Apps Script side: Code.gs
function doGet() {
return HtmlService.createHtmlOutputFromFile('Index');
}
function editDoc(data) {
let doc = DocumentApp.create("Title");
let body = doc.getBody();
body.setText(data);
doc.saveAndClose();
return {
data: "data:application/pdf;base64," + Utilities.base64Encode(doc.getBlob().getBytes()),
filename: doc.getName() + ".pdf"
};
}
HTML & Javascript side: Index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form onsubmit="event.preventDefault(); edit();">
<input type="text" id="input">
<input type="submit" id="sub" value="Submit">
</form>
<script>
function edit() {
google.script.run.withSuccessHandler(({data, filename}) => {
const a = document.createElement("a");
document.body.appendChild(a);
a.download = filename;
a.href = data;
a.click();
}).editDoc(document.getElementById("input").value);
}
</script>
</body>
</html>
I thought that in this case, a simple button can be also used instead of the submit button.
In the case of Google Docs, when a blog is retrieved, in the current stage, the blob is the PDF format.
In this modified script, when a text is inputted and a button is clicked, a PDF file is downloaded to the local PC.
Note:
In your script, it seems that Web Apps is used. In this case, when the script of Web Apps is modified, please redeploy the Web Apps as new version. By this, the latest script is reflected to the Web Apps. Please be careful this.
References:
Class google.script.run
saveAndClose()
base64Encode(data)

"No functions have been run in this editor session" - Issue with Google App Script [duplicate]

This question already has answers here:
How can I test a trigger function in GAS?
(4 answers)
How to view the logging of Google Web App when other users are executing it?
(2 answers)
Closed 1 year ago.
I am trying to create a webapp using Google Apps Script.
However, when I deploy my project(in a new version) as webapp and then view Log, it shows "No functions have been run in this editor session" message.
The HTML Code is saved as "page.html" (as expected by the function). Please help me
function doGet(e)
{
return HtmlService.createHtmlOutputFromFile("page");
Logger.log(e);
}
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h1> Hello 3 </h1>
</body>
</html>
You have 2 small issues,
1.- Your doGet(e) is executing the return statement before you actually log the e event. and so Logger.log(e); is not executed.
2.- The Apps script Logger class only works in the apps script session. (You would have to execute the function from within the editor to see this log). Also keep in mind that doGet(e) when run from within the editor will have a null e, but when making a GET request to your deployed webapp it will not be null.
Solution:
function doGet(e){
// Log the event in StackDriver
console.log(e);
return HtmlService.createHtmlOutputFromFile("page");
}
Here's a quick dialog:
GS:
function showDialog() {
SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutputFromFile("page"), 'test');
}
function sayHowdy() {
return "Howdy";
}
HTML:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h1> Hello 3 </h1>
<input id="msg" type="text" readonly />
<input type="button" value="Say Hello" onClick="sayHello()" />
<script>
function sayHello() {
google.script.run
.withSuccessHandler(function(msg){
document.getElementById('msg').value=msg;
})
.sayHowdy()
}
</script>
</body>
</html>

Getting the "You do not have permission to call getFolderByID" error, when calling that method in HTML

I am going through the book Google Apps Scripts, 2nd Edition. The lesson I am on for creating a web app asked me to use the following code:
function doGet() {
var html = HtmlService.createTemplateFromFile('index').evaluate()
.setTitle('06 Automating Forms')
.setSandboxMode(HtmlService.SandboxMode.NATIVE);
return html;
}
However, when I run this code I get the "You do not have permission to call getFolderById" error message. I don't understand why I am getting this error message. Also, it says the error is on line 2.
I am calling the "getFolderByID" method in my index.html file. Here is that code:
<div class="body">
<div><h2>This App will allow you to create a form from a template
in Google Docs.</h2></div>
<hr>
<div id="options">
<?var files =
DriveApp.getFolderById('0B6YzuBeNxooXSWE3Vm9WMlVnWkk').getFiles();?>
<select id='template'>
<option value="notSel">Select a Template</option>
<?while (files.hasNext()){
var file = files.next();?>
<option value="<?=file.getId()?>"><?=file.getName()?></option>
<?}?>
</select>
</div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
</script>
<script>
</script>
<style>
.body{
padding: 10px;
}
</style>
Is there a way to get permission to call that method? I thought if I run the code a box pops up and allowing me access to that area of Drive.
Only script files have the ability to ask for authorization, html files don't.
The simplest thing to do is to add a dummy function in your code.gs file like this :
function myFunction() {
DriveApp.getFolderById('0B6YzuBeNxooXSWE3Vm9WMlVnWkk');
}
run it from the script editor and you will get the authorization request as expected.

chrome extension manifest v2 and onclick events in a div element

I'm in the process of converting a chrome extension from manifest v1 to manifest v2.
I've extracted most of the javascript code from the html files and put it in separate .js files.
I've a problem with a div element in a popup.
The current code in popup.html is:
<div onclick="PopupClick('SHOW')" id="blue">Show</div>
Apparently onclick="" is not allowed in html since v2, but how to replace it,
so that the user can click on the div and a function is executed?
popup.html:
<script src="popup.js" type="text/javascript"></script>
<div id="blue">Show</div>
popup.js:
document.addEventListener('DOMContentLoaded', function () {
document.getElementById("blue").addEventListener('click',
clickHandler); });
function clickHandler(e) { PopupClick('SHOW'); }
function PopupClick(str) {
//Do your thing here
}
Like Rob W said, it's clear in http://developer.chrome.com/extensions/contentSecurityPolicy.html#H3-1
I actually faced this problem and this code help me move from manifest v1 to v2.
Maybe events? Include something like <script src="js/my_script.js"> in head of your popup.html and then paste code in that js file.
var blueDiv = document.getElementById("blue");
blueDiv.addEventListener("click", function(){
PopupClick("SHOW");
}, false);
Or some specifics of your app doesn't allow you to do this? Or i don't understand the problem.