How to use parameters that go to a script in html content? - google-apps-script

I am new to using Google script, but not completely new to programming.
I have looked at some examples and they generate HTML output like this:
function doGet(e) {
return HtmlService.createHtmloutputFromFile('form.html')
}
I would like to pass a parameter to my script to use that in the output.
I have gotten as far as that I can use this in the function:
var room= e.parameter.room
So when I execute my script with url?room=test
I do get the value for that parameter.
But how can I use that variable room that I create in the HTML output and other code?
I have been looking at createTemplateFromFile but I am not getting anywhere.
Hope someone can point me in the right direction of what constructs and command to look at.

You can directly get query parameters client side1:
form.html
<script>
google.script.url.getLocation(function(location) {
alert(location.parameter.room); //alerts "test" on loading "url?room=test"
});
</script>
Alternatively, You can use scriplets to load html2:
code.gs
function doGet(e) {
var temp = HtmlService.createTemplateFromFile('form');
temp.room = e.parameter.room;
return temp.evaluate();
}
form.html:
<script>
alert('<?=room?>'); //Printing scriplets
</script>

Related

Apps Script - Use a Code.gs variable in HTML script

Here, the task is to use a variable from Code.gs to be used in the HTML side.
The best idea I've had is using google.script.run to get access to Code.gs where I have stored a variable that I wish to use in the HTML script. Eg: Suppose there is a variable in the Code.gs side that turned out to be 1+1. Then I would very much have liked the following to work:
Code.gs
function getMyGSValue() {
return 1+1
}
HTML
<script>
google.script.run.withSuccessHandler(myGsValue => {
myScriptVar = myGsValue
}).getMyGsValue()
// Here use MyScriptVar endlessly.
</script>
Which unfortunately fails to work. If it's of any help, I'm more interested in using string variables from the Code.gs side as these will be more likely the link to the images I want to display if particular conditions are met.
A related question follows:
Passing variable from Code.gs to html in Google App Script
But to be honest, It seemed to have its focus elsewhere.
Doing it with google.script.run. I just used window.onload event to get the data from the server
html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<input type="text" id="txt1" />
<script>
window.onload = () =>{
//console.log("window.onload")
google.script.run.withSuccessHandler((v) => {
document.getElementById("txt1").value = v;
}).getMyGsValue()
//console.log("Code");
}
</script>
</body>
</html>
gs:
function getMyGsValue() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet0");
return sh.getRange("A1").getValue();
}
function launchmydialog() {
SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutputFromFile("ah2"),"Title");
}
If you need that the "variable" from the server side be ready when the web browser start parsing the web application, instead of using client-side code to retrieve the "variable", generate the client-side code with the "variable" that you need by generating first a HtmlTemplate, then assigns the variable to a HtmlTemplate property and finally evaluates it.
Below is an over simplistic example:
function doGet(e){
const myServerVariable = 1 + 1;
const template = `<body><script>const myClientVariable = <?!= tmpProp?> </script></body>`;
return (
HtmlService.createTemplate(template)
.tmpProp = myServerVariable
).evaluate();
}
The above example is so simple that you could do the same by using regular JavaScript string manipulation. Anyway, <?!= tmpProp?> is a force-printing scriptlet, also there are standard scriptlets and printing scriptlets that might be more frequently used on .html files in Google Apps Script.
Be careful when using scriptlets to built the client-side code to not make them to take too much time to generate the client-side code as this will impact how fast the web app responds to the initial request.
By the other hand, if you want to keep using google.script.run, just declare a global variable, and update it in the withSuccessHandler callback
<script>
var MyScriptVar;
google.script.run.withSuccessHandler(myGsValue => {
MyScriptVar = myGsValue
}).getMyGsValue()
// Here use MyScriptVar endlessly.
</script>
Just consider the case that MyScriptVar will be undefined while the google.script.run finish it's execution.
Related
How to pass a parameter to html?
Passing variable from google script to html dialog
References
https://developers.google.com/apps-script/guides/html/templates

Call a function from external URL

I want to call a function I wrote within my Google Apps Script. When I execute a getJSON I suppose it'll automatically run my doGet(e).
My Javascript:
$.getJSON(https://script.google.com/macros/s/[ID]/exec, function(data){
//code here
});
Is there a possible way to call one of my custom functions for example
My Google Apps Script:
function getNumberOfFans(e){
//code here
}
Do I have to add some kind of extra function parameter to my URL?
In either a "stand alone" or bound Apps Script file add a doGet(e) function.
Publish the Apps Script file as a Web App.
Get the published URL of the Web App.
Add a search string parameter to the end of the URL.
You can add search string parameters to the URL of the published Wep App.
Here is an example:
https://script.google.com/macros/s/[ID]/exec?searchStringName=functionOne
The search string is at the end of the URL, after exec. You must add a question mark after exec and then name=value
url/exec?name=value
Where name and value will be replaced with your choices.
Put the event argument (denoted by the letter "e") into the doGet(e) function, not the function you want used.
function doGet(e) {
var passedString,whatToReturn;
passedString = e.parameter.searchStringName;
if (passedString === 'functionOne') {
whatToReturn = functionOne(); //Run function One
};
return ContentService.createTextOutput(whatToReturn);
};
function functionOne() {
var something;
//. . . . Code;
something = code here;
return something;
};
The above code is for a GET request. If you want to use a POST request, don't use a search string in the URL. For a POST request, you will send information in the payload. You'll still use e.parameter to access the data sent, but whatever is in e.parameter will be an object with key/value pairs. You'll need to know what the key (property) name is that was sent in the object.
For an explanation on URL Parameters, see this documentation:
URL Parameters

Display variable as html in Google App Script?

Let's say we have a variable. This variable was created in google app script. On that app script project, you have two files. First, the .gs file, where the variable came from. Next, you have the html file. How do you transfer the variable to html?
GAS:
function doGet() {
return HtmlService.createHtmlOutputFromFile('index');
}
function items() {
var exmp = 45;
document.getElementById("test").innerHTML = "You have " + exmp + " items";
HTML:
<script>
google.script.run.items();
</script>
<div id="test"></div>
However, this doesn't work. How can I make this work?
If you read over the Private Functions section of the HTML service documentation, you'll find an example that does almost exactly what you're trying. The code below adapts that example to yours.
You need to keep the GAS server stuff separate from the HTML client stuff. For example, document.getElementById("test").innerHTML = ... means nothing in the context of the server / GAS code. Instead, the modification of the document will be done by Javascript on the client side - in this case, by a success handler.
A success handler is a client-side Javascript callback function that will receive the asynchronous response from your server function items().
Client-side calls to server-side functions are asynchronous: after the
browser requests that the server run the function doSomething(), the
browser continues immediately to the next line of code without waiting
for a response.
This means that there is no waiting for the return code from the call to your server function... the browser just keeps going. You'll see this in this example, as the "More loading..." text gets displayed after the google.script.run call, but before the response is received.
What if items() needs to do something more advanced... like read info from a spreadsheet? Go ahead and change it... just make sure that you return the text you want displayed, and that what you're returning is going to be valid HTML (so the innerHTML operation is OK).
Code.gs
function doGet() {
return HtmlService.createHtmlOutputFromFile('index');
}
function items() {
Utilities.sleep(5000); // Added to allow time to see the div content change
var exmp = 45;
return( "You have " + exmp + " items" );
}
index.html
<div id="test">Loading...</div>
<script type="text/javascript">
function onSuccess(items) {
document.getElementById('test').innerHTML = items;
}
google.script.run.withSuccessHandler(onSuccess).items();
document.getElementById('test').innerHTML = "More loading...";
</script>
You need first to create the HTML using the createHTMLOutput function
In order for you to append strings youo have to use the var.append method
function items(){
var email = Session.getActiveUser().getEmail();
var output = HtmlService.createHtmlOutput(email);
var string1 = HtmlService.createHtmlOutput('<p>You have </p>')
string1.append(output);
string2= HtmlService.createHtmlOutput('<p> items</p>')
string1.append(string2);
Logger.log(string1.getContent());
}
Reference

Displaying a GoogleScript UiApp with the htmlService / html template

I have a UiApp that creates some form elements that write data to a specific spreadsheet. Now I want to load the UiApp widgets into an htmlService template, and I'm not sure how to go about this.
My doGet function loads the base template, and the doGetApp builds the UiApp:
function doGet() {
return HtmlService.createTemplateFromFile('base_template').evaluate();
}
function doGetApp() {
// creates input forms for a spreadsheet (the following is just an example
var app = UiApp.createApplication();
var tabPanel = app.createDecoratedTabPanel();
var flowPanel1 = app.createFlowPanel();
var flowPanel2 = app.createFlowPanel();
tabPanel.add(flowPanel1, "Create New Projects");
tabPanel.add(flowPanel2, "Edit Projects");
app.add(tabPanel);
// return app; // <<<< original doGet function returned the app
// testing different ways of returning the UiApp
return HtmlService.createHtmlOutput(app); // this displays the text "HtmlOutput"
}
My base_html template is very simple right now:
<html >
<?!= getCSS("css_js"); ?>
<body>
<h1>Template Test</h1>
<?!= doGetApp(); ?>
</body>
</html>
I've tried a few variations on this, but the results are generally the same: Text output that appears to describe the object, as opposed to displaying the UiApp. (the getCSS function works fine)
The goal is to be able to easily load some of my own css / js as well as the UiApp in order to easily style the forms / resulting content. I'm pretty new to this, so it is entirely possible that I'm approaching this the wrong way. Appreciate any pointers. Thanks!
-greg
For now, you either use html service or uiapp - you cannot combine the two

Google Apps Script HTMLservices append HTML

Hi GAS StackOverflow guides,
How do you append another HTML code/file after the initial doGet mentioned here? https://developers.google.com/apps-script/html_service#HTMLFiles
It says it can append using HtmlOutput class but no success with:
function doSomething() {
//append another HTML file
return HtmlService.createHtmlOutputFromFile('headers');
}
function doSomething2() {
//append another HTML file
return HtmlService.createHtmlOutputFromFile.append('headers');
}
Thanks.
The append method on an HtmlOutput is for appending in the initial doGet function (if you are building up your HTML piece by piece). You can't use it to append more stuff later, but you can use the regular document.append() that you'd use in any other client-side JavaScript to do this. Something like this:
On the client
google.script.run.withSuccessHandler(function(x) { document.append(x); }).doSomething2()
On the server
function doSomething2() { return "the stuff I want to append"; }