Google Apps Script, Google Sheet - Template Scriplets don't work [duplicate] - google-apps-script

This question already has answers here:
Adding a property to an Html template gives error "Object does not allow properties to be added or changed"
(2 answers)
Updating content in a Google Apps Script sidebar without reloading the sidebar
(1 answer)
I am trying to pass a variable from my Google Script through to HtmlOutputFromFile
(1 answer)
Closed 8 months ago.
I've been reading these answers and trying out some of the code, but I could not get my code to work. These are the links I've been reading:
https://developers.google.com/apps-script/guides/dialogs#page.html_1
How to pass a parameter to html?
Adding a property to an Html template gives error "Object does not allow properties to be added or changed"
My Code.gs:
function onOpen() {
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.createMenu('Custom Menu')
.addItem('Show sidebar', 'showSidebar')
.addToUi();
}
function showSidebar() {
var html = HtmlService.createHtmlOutputFromFile('Page')
.setTitle('My custom sidebar');
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.showSidebar(html);
}
function testCSV2() {
const text = SpreadsheetApp.getActiveSheet().getDataRange().getDisplayValues();
const result = cellArraysToCsv(text);
Logger.log(result);
return result;
}
function cellArraysToCsv(data) {
const regex = /"/g;
let change = data.map(row => row.map(value => `"${value.replace(regex, '\"\"')}"`)).join('\n');
return change;
}
My Page.html:
<!DOCTYPE html>
<script>
function answers() {
var data = google.script.run.testCSV2();
document.getElementById("myTitle").innerText = data;
}
</script>
<html>
<head>
<base target="_top">
</head>
<body>
Hello, world! <input type="button" value="Answers" onclick="answers()" />
<H2 id="myTitle"></H2><br><br>
<?!= testCSV2() ?>
</body>
</html>
I'm getting very confused. Why is it that when I click on the button "Answers", I get no output? And why is <?!= testCSV2() ?> unchanged in the <body> of Page.html?

Description
There are two part to this. Using templated HTML in which testCSV2() is run on the server as well as passing data before the HTML is displayed and using google.script.run.testCSV3() to get data from the server.
Code.gs
function onOpen() {
var menu = SpreadsheetApp.getUi().createMenu("Test");
menu.addItem("Show Test", "showSidebar").addToUi();
}
function showSidebar() {
var html = HtmlService.createTemplateFromFile("HTML_Test");
html.data = "greetings";
html = html.evaluate();
SpreadsheetApp.getUi().showSidebar(html);
}
function testCSV2() {
return "hello";
}
function testCSV3() {
return "goodbye";
}
HTML_Test
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
Hello, world! <input type="button" value="Answers" onclick="answers()" />
<H2 id="myTitle"></H2><br><br>
<?!= data ?><br>
<?!= testCSV2() ?>
<script>
function answers() {
google.script.run.withSuccessHandler(
function (data) {
document.getElementById("myTitle").innerText = data;
}
).testCSV3();
}
</script>
</body>
</html>
References
Templated HTML
google.script.run

google.script.run.yourfunctionName();
Use this code in JavaScript to call your function that's defined in gs file.
Reference: Communicate with server function

Related

Google Workspace, SpreadsheetApp.getUi().showSidebar causes "TransportError", with Error code = 10, Path = /wardeninit and google.script.run will fail

I'm trying to make a Google App script with this simple code below
function onInstall(e) {
onOpen(e);
}
function onOpen(e) {
SpreadsheetApp.getUi()
.createMenu('Test Menu')
.addItem('Test', 'doTest')
.addToUi();
}
function doTest() {
var htmlOutput = HtmlService
.createHtmlOutput('<p>Some Text</p>')
.setTitle('My title');
SpreadsheetApp.getUi().showSidebar(htmlOutput);
}
The sidebar shows up correctly
[1]: https://i.stack.imgur.com/6QTR8.png
But i get this error in the chrome console:
message: "There was an error during the transport or processing of this request. Error code = 10, Path = /wardeninit"
name: "TransportError"
stack:"TransportError: There was an error during the transport or processing of this request. Error code = 10, Path = /wardeninit
at new Qo (https://docs.google.com/static/macros/client/js/3949079914-warden_bin_i18n_warden__vi.js:200:381)
at Vo.w.Xc (https://docs.google.com/static/macros/client/js/3949079914-warden_bin_i18n_warden__vi.js:208:372)
at Cf (https://docs.google.com/static/macros/client/js/3949079914-warden_bin_i18n_warden__vi.js:79:228)
at Bf (https://docs.google.com/static/macros/client/js/3949079914-warden_bin_i18n_warden__vi.js:76:472)
at xf.A (https://docs.google.com/static/macros/client/js/3949079914-warden_bin_i18n_warden__vi.js:76:419)
at Cf (https://docs.google.com/static/macros/client/js/3949079914-warden_bin_i18n_warden__vi.js:79:228)
at Bf (https://docs.google.com/static/macros/client/js/3949079914-warden_bin_i18n_warden__vi.js:76:472)
at Vo. (https://docs.google.com/static/macros/client/js/3949079914-warden_bin_i18n_warden__vi.js:207:159)
at An (https://docs.google.com/static/macros/client/js/3949079914-warden_bin_i18n_warden__vi.js:165:294)
at Do (https://docs.google.com/static/macros/client/js/3949079914-warden_bin_i18n_warden__vi.js:200:262)"
I have been make some Google App script before but just get this error recently.
What am I doing wrong?
Updated
Because of this "TransportError", any "google.script.run" script will fail.
If i update the code like this:
function doTest() {
var htmlOutput =
HtmlService.createHtmlOutputFromFile('Index');
SpreadsheetApp.getUi().showSidebar(htmlOutput);
}
function doSomething() {
Logger.log('I was called!');
}
And the Index.html is
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function onSuccess() {
console.log("onSuccess");
}
function onFailure(error) {
console.log("onFailure",error);
}
google.script.run.withSuccessHandler(onSuccess).withFailureHandler(onFailure).doSomething();
</script>
</head>
<body>
</body>
</html>
The onFailure will always be called and the error is empty.
Update 2
The problem with "google.script.run" script will fail.
only for google workspace account.
If I change to my personal gmail account and made the similar code, the problem does not happen.
I used your code like this:
html:(filename: ah3.html)
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function onSuccess() {
console.log("onSuccess");
}
function onFailure(error) {
console.log("onFailure",error);
}
google.script.run.withSuccessHandler(onSuccess).withFailureHandler(onFailure).doSomething();
</script>
</head>
<body>
<div>Hello World</div>
</body>
</html>
gs:
function doTest() {
var htmlOutput = HtmlService.createHtmlOutputFromFile('ah3').setTitle('My title');
SpreadsheetApp.getUi().showSidebar(htmlOutput);
}
function doSomething() {
Logger.log('I was called!');
}
It works for me.
If you look in the console you will see the onSuccess printed and if you look in executions you will see Sep 3, 2021, 10:16:03 PM Info I was called!

how to do to join the adress mail with "mailto", in javascript?

Using google app script, the adresse mail filled in the variable , from google sheet API and then, I want to join "mailto:" with the variable of adress mail . This allows to appear this variable in html .
How to do it ?
in google app script:
var Email_user = Session.getActiveUser().getEmail();
var hrefmail = "mailto:"+Email_user ;
var val_htm_mail_1 =hrefmail ;
:
:
:
theHTML.linkEmail = val_htm_mail_1; ( this is to fill the variable "val_htm_mail_1" to send it to HTML
in html :
<span id="linkEmail"><?=linkEmail?></span><br />
thank you in advance for this helpness
I recommend using HTML DOM Edit HTML content instead of a scriptlet. Here's the w3 reference so you can try to write it yourself, instead of just copying mine. Here is an example program:
code.gs
function doGet() {
return HtmlService.createTemplateFromFile('Index')
.evaluate();
}
function include(filename) {
var Email_user = Session.getActiveUser().getEmail();
var hrefmail = "mailto:"+Email_user ;
val_htm_mail_1 = hrefmail ;
return HtmlService.createHtmlOutputFromFile(filename)
.getContent();
}
Index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<span id="linkEmail">...</span><br/>
<script>
document.getElementById("linkEmail").innerHTML = this.val_htm_mail_1;
</script>
<?!= include ('javascript'); ?>
</body>
</html>
javascript.html
<script>
window.addEventListener('load', function() {
console.log('Page is loaded');
});
</script>
*Note you may need to adjust this depending on your browser settings

How to upload file from local to Drive using HTML service dialog in apps script?

Attempting to upload a file to google drive from Local using a custom HTML dialog.
On clicking upload in the dialog it waits a few seconds and then shows an error:
"failed UploadWe're sorry, a server error occurred. Please wait a bit and try again."
It is just not running the server side function. I have tried changing the server side function just to return anything and it is just not working so I don't think it's a problem with the server side function itself. Something about the communication between client and server.
Do you have any idea why this is not working?
// Use this code for Google Docs, Slides, Forms, or Sheets.
function onOpen() {
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.createMenu('Dialog')
.addItem('Upload', 'uploadDialog')
.addToUi();
}
function uploadDialog() {
var html = HtmlService.createHtmlOutputFromFile('Index');
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.showModalDialog(html, 'Upload File Here');
}
function uploadFile(frmdata) {
var fileBlob = frmdata.fileToUpload
if (fileBlob.getName() != "") {
var fldrSssn = DriveApp.getFolderById("1nFl9S3pgR9IXSKVuKh9sUGOKi5adEHR1");
var picFile = fldrSssn.createFile(fileBlob);
}
}
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form id="fileform" onsubmit="event.preventDefault()">
<input type="file" id="file" name="fileToUpload">
<input type="Button" value="Upload" onclick="uploadthis(this.parentNode)">
</form>
</body>
<script>
function uploadthis(frmData) {
google.script.run
.withSuccessHandler(closeDialog)
.withFailureHandler(alertFailure)
.uploadFile(frmData);
}
function closeDialog() {
google.script.host.close()
}
function alertFailure(error) {
google.script.host.close()
alert("failed Upload" + error.message)
}
</script>
</html>
This behavior is a known issue with V8 runtime. Here is the link: https://issuetracker.google.com/150675170. You can click on the star icon to indicate you are affected by it too.

"cannot read property 'fileName of undefined'" error while uploading file to Google Drive using a html form

The script started to throw an error:
TypeError: Cannot read property 'fileName' of undefined at uploadFile(Code:16:25)
It was working a couple of months back, but now it doesn't, also it sometimes works when used in some other sheet.
Also this is not my code, and i am not a tech guy, i just used this code of someone else. if you could help please tell me what changes do i make in this code.
/* this is the index.html used to get the file to upload*/
<!DOCTYPE html>
<html>
<head>
<base target="_center">
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
</head>
<body>
<form id="myForm" >
Select File:
<input type="file" name="myfile" accept="*" /><br>
File name: <input type="text" name="fileName" /><br><br>
<input type="button" value="Upload" onclick="upload(this.parentNode);" />
</form>
<script>
window.onload=func1;
function func1() {
document.getElementById('myForm').addEventListener('submit', function(event) {
event.preventDefault();
});
}
function upload(obj){
google.script.run.withSuccessHandler(close).withFailureHandler(close).uploadFile(obj);
}
function close(e) {
console.log(e);
google.script.host.close();
}
</script>
</body>
</html>
/* code.gs function called when file is uploaded*/
function onOpen() {
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.createMenu('File')
.addItem('Attach...', 'showForm')
.addToUi();
}
function showForm() {
var app = SpreadsheetApp;
var html = HtmlService.createHtmlOutputFromFile('index');
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.showModalDialog(html, 'Upload File');
}
function uploadFile(obj) {
var newFileName = obj.fileName; //this is where debug shows the above error
var blob = obj.myfile;
var upFile = DriveApp.getFolderById('1BWcs7RBPDyJQm_R0FLEUxCfRlKTB0uwX').createFile(blob).setName(newFileName);
var fileUrl = upFile.getUrl();
var urlCell = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getActiveCell();
urlCell.setValue(fileUrl);
}
There seems to be a bug related to the curent upgrade of the Apps Script runtime to v8
While this is being fixed, you cannot disable V8 by going from the Apps Script Editor on
Run -> Disable new Apps Script runtime powered by V8
You can alternatively use a different method to upload your file
Sample how to upload your file with fileReader:
index.html
<!DOCTYPE html>
<html>
<head>
<base target="_center">
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
</head>
<body>
<form id="myForm" >
Select File:
<input type="file" name="myfile" accept="*" /><br>
File name: <input type="text" name="fileName" /><br><br>
<input type="button" value="Upload" onclick="upload(this.parentNode);" />
</form>
<script>
window.onload=func1;
function func1() {
document.getElementById('myForm').addEventListener('submit', function(event) {
event.preventDefault();
});
}
function upload(obj){
var file = obj.myfile.files[0];
var reader = new FileReader();
reader.onload = function(e) {
var obj2 = {
fileName: obj.fileName.value,
mimeType: file.type,
bytes: [...new Int8Array(e.target.result)]
};
google.script.run.withSuccessHandler(close).withFailureHandler(close).uploadFile(obj2);
};
reader.readAsArrayBuffer(file);
}
function close(e) {
console.log(e);
google.script.host.close();
}
</script>
</body>
</html>
code.gs
function onOpen() {
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.createMenu('File')
.addItem('Attach...', 'showForm')
.addToUi();
}
function showForm() {
var app = SpreadsheetApp;
var html = HtmlService.createHtmlOutputFromFile('index');
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.showModalDialog(html, 'Upload File');
}
function uploadFile(obj) {
var newFileName = obj.fileName;
var blob = Utilities.newBlob(obj.bytes, obj.mimeType, newFileName);
var upFile = DriveApp.getFolderById('1BWcs7RBPDyJQm_R0FLEUxCfRlKTB0uwX').createFile(blob);
var fileUrl = upFile.getUrl();
var urlCell = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getActiveCell();
urlCell.setValue(fileUrl);
}
Note:
Your error message TypeError: Cannot read property 'fileName' of undefined at uploadFile implies that you tried to run the function uploadFile manually form the editor - without passing it a file as obj parameter - this will lead to the error since without a file there is no fileName (and no fiel data).
The way your code is designed, uploadFile needs to be called from the html form after you upload a file.

Active user's details in the HTML page

How can I print the active user's details in the HTML page? I am able to print in logs and as well as in sheet but not able to print in HTML
<script>
var email = Session.getActiveUser().getEmail();
Logger.log(email);
}
</script>
<p email="email"></p>
Not completely sure what your asking but here's a simple example of getting current user email on to an html dialog. You could deploy it as a web app if you wish.
Code.gs:
function onOpen(e)//for Menu
{
SpreadsheetApp.getUi().createMenu('My Tools')
.addItem('Display Email','displayEmail')
.addToUi();
}
function getCurrentUserEmail()
{
var email={'email':Session.getActiveUser().getEmail()};//returned as an object
return email;
}
function displayEmail()
{
SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutputFromFile('getemailinhtml'), 'User Email');//modeless dialog
}
getemailinhtml.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(function() {
google.script.run
.withSuccessHandler(dispEmail)
.getCurrentUserEmail();
});//runs after dom is loaded
function dispEmail(data)
{
$('#email').text(data.email);//put's email into h1 tag
}
console.log('My Code');
</script>
</head>
<body>
<h1 id="email"></h1>//Email show up here
</body>
</html>
To have your script display HTML pages, start with
HTML Service: Create and Serve HTML. A minimal example:
function doGet() {
var email = Session.getActiveUser().getEmail();
var html = '<html><body>Email: ' + email + '</body></html>';
return HtmlService.createHtmlOutput(html);
}
Go to "Publish > Deploy as web app" and set appropriate options, so that the app will run as the user accessing it (who will have to authorize it):
Note that the above example is only suitable as a demo; for larger pages you will want to use templated HTML and other web-oriented features of Google Apps script.