How to connect css to html in Google Apps Scripts - html

I'm trying to make my first Google App. I have my HTML doc which has the include statement as outlined on HTML Service: Best Practices.
<html>
<head>
<base target="_top">
<?!= include('stylesheet') ?>
</head>
<body>
...
</body>
My code.gs file is as follows:
function doGet() {
return HtmlService.createTemplateFromFile('BooksTS2.html')
.evaluate();
}
My style sheet is named stylesheet.html, and for testing purposes is really simple:
<style>
p {color: green;}
</style>
But when I run it I get this error message: ReferenceError: "include" is not defined.

In the example they created the reusable function include(), you need to add it in your code.gs file:
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename)
.getContent();
}
You can always use the printing scriptlet directly in your html file like this:
<html>
<head>
<base target="_top">
<?!= HtmlService.createHtmlOutputFromFile('stylesheet').getContent(); ?>
</head>
<body>
...
</body>
</html>

Related

Trouble passing a variable to HTML from Google Apps Script and then back to GS again

Having trouble getting a parameter from the URL of a Web App deployed from Google App Script, passing it through a HTML template, and then getting it again as a parameter for a JS function when a user clicks on a button in the Web App.
Specifically, in the code below, I am having trouble passing the variable "username" from the html back to a JS function defined in my original Google App Script when the user clicks on the button "approveTC"...
Here is the Google Apps Script
function doGet(e) {
if(e.parameters.name === undefined){
var tmp = HtmlService.createTemplateFromFile('entername')
return tmp.evaluate();
} else {
var tmp = HtmlService.createTemplateFromFile('timecard')
tmp.username = e.parameters.name
return tmp.evaluate();
}
}
function timecardApproved(name){
return signAndSendTc(name)
}
And here is the HTML:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<?!= include("timecard-css"); ?>
</head>
<body>
<div>
<h1>Hello <?!= username?></h1>
</div>
<div>
<iframe src=<?!= getTcJpg(username); ?> width="80%" height="800px" frameborder="0"></iframe>
</div>
<div>
<br>
<button id="approveTC">Approve Timecard</button>
</div>
<script>
document.getElementById("approveTC").addEventListener("click",approveTC);
function approveTC(username){
google.script.run.timecardApproved(username);
}
</script>
</body>
</html>
When you assign the templated value to a variable in your script, make sure that you pass it stringified
This works for me:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<div>
<h1>Hello <?!= username?></h1>
</div>
<div>
</div>
<div>
<br>
<button id="approveTC">Approve Timecard</button>
</div>
<script>
var uname = "<?!= username ?>"
document.getElementById("approveTC").addEventListener("click",approveTC);
function approveTC() {
console.log(uname)
}
</script>
</body>
</html>
After a lot of experimenting, this was the solution that ended up working for me... very close to what #ziganotschka suggested. Except, when I tried #ziganotschka's method earlier, the variable didn't pass through correctly to my Google Apps Script. This code does work for me, though...
<script>
var username = <?= username ?>
document.getElementById("approveTC").addEventListener("click",approveTC);
function approveTC(){
google.script.run.timecardApproved(username);
}
</script>

GoogleSheets google.script.run always going to FailureHandler

I am using GoogleSheets HTMLService. I am calling google.script.run from my Html page's script. But it is always going to FailureHandler. What is wrong in it? Please see the code below. When I run it, it always shows the alert Failed. Also, the logger does not show any error. It is also not showing the console log "Inside Hello" in the hello() function. Do we also need to do some browser settings (I am using chrome - javascript allowed).
[UPDATED]
After replacing Logger.log with console.log, I am seeing it as Transport Error.
modeDialog.gs
function openDialog() {
var html = HtmlService.createHtmlOutputFromFile("test");
html.setWidth(90).setHeight(1);
var ui = SpreadsheetApp.getUi().showModalDialog(html, "Opening ..." );
}
function hello() {
console.log("Inside Hello");
return "hello";
}
test.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function onSuccess(str) {
window.alert("executed");
}
function onFailure(error) {
window.alert("failed");
Logger.log(error);
}
google.script.run.withSuccessHandler(onSuccess).withFailureHandler(onFailure).hello();
</script>
</head>
<body>
<div id="failureContent"></div>
Hello world
</body>
</html>
As I mentioned that it was working earlier in Chrome and is currently working in FireFox, I tested it again after changing my chrome settings to default by going to Chrome > Settings > Advanced > Reset and clean up > Restore settings to their original defaults.
It is working fine after that. So setting this as the answer.
I ran it this way:
GS:
function openDialog() {
SpreadsheetApp.getUi().showModalDialog(HtmlService.createHtmlOutputFromFile("ah3"), "Opening ..." );
}
function hello() {
return "hello";
}
HTML:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
Hello world
<script>
window.onload=function(){
google.script.run
.withSuccessHandler(function(str){window.alert("executed");})
.withFailureHandler(function(error){window.alert("failed");})
.hello();
}
console.log('MyCode');
</script>
</body>
</html>
I just like to use onReadyState function or onload to run most javascript so that html is already loaded. Not that it makes much difference in this trivial example. Also I tend to put the scripts in the body rather than in the head.

Function given with google.script.run not getting invoked

I have followed code snippets and directions given at https://developers.google.com/apps-script/guides/html/communication#index.html
And added following codes in my scripts project:
Code.gs
function doGet() {
return HtmlService.createHtmlOutputFromFile('Index');
}
function doSomething() {
Logger.log('I was called!');
}
Index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
google.script.run.doSomething();
</script>
</head>
</html>
But my function doSomething is not getting called. This is a fresh google scripts project that I have started and published it as web app.
I have seen similar issue reported in this thread and this thread. I have tried the measures mentioned there, but still facing the issue. Also, I see that there is no accepted answer there, so posting this question again. I don't know how to bring those questions back to life.
Thanks,
Mukesh
You can test it a lot easier in a dialog.
GS:
function doSomething() {
SpreadsheetApp.getActive().toast('I was called!');
return 'I called';
}
function openDialog() {
SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutputFromFile('ah3'), "Testing")
}
HTML:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
</script>
</head>
<body>
<script>
window.onload=function(){
google.script.run
.withSuccessHandler(function(msg){
window.alert(msg);//display returned message
google.script.host.close();//close the dialog
})
.doSomething();//The call to the server
}
</script>
</body>
</html>

Is there a way to reference sweet alert from google apps script?

I'm linking the library with the src attribute and using a function to call it and its not working
GS:
function doGet(e) {
var params = JSON.stringify(e.parameters)
var params2 =JSON.parse(params)
cache.put("name", params2.name)
cache.put("DBID", params2.DBID)
return HtmlService.createTemplateFromFile("test").evaluate()
}
function include(f1){
return HtmlService.createHtmlOutputFromFile(f1).getContent();
}
Html:
<head>
<title>Email form test</title>
<?!= include("CSS") ?>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2#8.17.6/dist/sweetalert2.all.js"></script>
<?!= include('Javascript') ?>
<button type="button" name="Submit" onclick="javascript:t1();"id="sub1"class="btn btn-white btn-animation-1">Submit</button>
Calling library (after its been initialized above):
<script>
function t1(){
Swal.fire('Any fool can use a computer');
}
</script>
the expected result should be I click the button and "any fool can use a computer" should pop up in a sweet alert 2 box
You don't need to import and evaluate the Sweetalert library within Apps Script - you can include it in your HTML file as you would normally and return the HTML Output from file on doGet():
code.gs:
function doGet(e) {
// your code here
return HtmlService.createHtmlOutputFromFile("index");
}
and index.html:
<!DOCTYPE html>
<html>
<head>
<title>Email form test</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2#8.17.6/dist/sweetalert2.all.js"></script>
<button type="button" name="Submit" onclick="t1();"id="sub1"class="btn btn-white btn-animation-1">Submit</button>
<script>
function t1(){
Swal.fire('Any fool can use a computer');
}
</script>
</body>
</html>

how to reference a file inside an app script

is it possible to reference / import a file that is inside the script.
test.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css">
<script src="/testsrc.html"></script>
</head>
<body onLoad="onLoad()">
<div>
<p id='result'>....</p>
</div>
</body>
</html>
testsrc.html
function onLoad(){
document.getElementById("result").innerHTML = "ran";
}
You could do:
<?!= HtmlService.createHtmlOutputFromFile('testsrc').getContent() ?>
instead of
<script src="/testsrc.html"></script>
Don't forget to wrap all your js code in testsrc.html file in <script></script>
PS: better yet in your code.gs file create an include() function like this
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename).getContent();
}
then you can call it any time you need to include any file:
<?!= include('testsrc') ?>