I need to pass a data value from the HTML to the Google Script on a GAS project. The parts with comments of the code is the value I need to pass.
gs file
function doGet(e) {
if (e.parameter.prefix){
var result = data; // <-- GET VALUE "data" FROM THE HTML "forms.html"
var content = e.parameters.prefix + '(' +JSON.stringify(result) + ')';
return ContentService.createTextOutput(content)
.setMimeType(ContentService.MimeType.JAVASCRIPT);
}
var html = HtmlService.createHtmlOutputFromFile('Index');
return html.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
Index.html in GAS project
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h1 id='title' style="color: #e31414">SCRIPT</h1>
<h1 id='done' style="display: none"> DATA PASSED</h1>
<button id="btn" onclick="passData()">Run "passData()"</button>
</body>
</html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script>
function passData() {
$('#done').show();
var data = 'value'; //<-- PASS THIS DATA TO GOOGLE SCRIPT (The .gs file)
}
</script>
Follow these steps:
in the gs file, create a variable without a value at the very top: var data;
Create a function below it like so:
function myfunction(x) {
data = x;
}
in the Index.html file especially in passData() function, insert this line in the bottom of the function: google.script.run.myfunction(data);
Finally, you will be able to use the result variable as the data in doGet() function.
-- your code should look like this --
gs file
var data;
function myfunction(x) {
data = x;
}
function doGet(e) {
if (e.parameter.prefix){
var result = data; // <-- GET VALUE "data" FROM THE HTML "forms.html"
var content = e.parameters.prefix + '(' +JSON.stringify(result) + ')';
return ContentService.createTextOutput(content)
.setMimeType(ContentService.MimeType.JAVASCRIPT);
}
var html = HtmlService.createHtmlOutputFromFile('Index');
return html.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
Index.html in GAS project
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h1 id='title' style="color: #e31414">SCRIPT</h1>
<h1 id='done' style="display: none"> DATA PASSED</h1>
<button id="btn" onclick="passData()">Run "passData()"</button>
</body>
</html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script>
function passData() {
$('#done').show();
var data = 'value'; //<-- PASS THIS DATA TO GOOGLE SCRIPT (The .gs file)
google.script.run.myfunction(data);
}
</script>
Related
I need to save the source code of any website in a java script variable. For example, saving Google source code in a variable "GoogleSourceCode".
I tried some ways but I don't have enough knowledge for that.
<html>
<head>
<script src="http://code.jquery.com/jquery-1.12.1.min.js"></script>
</head>
<body>
<div id="container">
<button id="acessaSite">Acessa Site</button>
<button id="pegarHTMLagora">pegar HTML agora</button>
</div>
<script>
$('#acessaSite').on('click', function () {
$.getJSON('http://www.whateverorigin.org/get?url=' + encodeURIComponent('https://google.com.br') + '&callback=?', function(data){
alert(dados.conteudo);
});
});
$('#pegarHTMLagora').on('click', function () {
var htmlAgora = document.documentElement.innerHTML; // Javascript vanilla (sem jquery)
alert(htmlAgora);
});
let htmlPego = document.documentElement.innerHTML;
</script>
</body>
</html>
The variable fieldName for testGetFieldName function is located at Code.gs
I want to insert it into the input value of the index.html file.
But if I open Sidebar using testSetValue, the value comes out as undefiend.
How can I get the variable 'Account' to come out with Value?
The code I wrote is as follows.
//code.gs
function testGetFieldName(){
var fieldName = 'Account';
return fieldName;
}
function testSetValue(){
var html = HtmlService.createTemplateFromFile('index');
var output = html.evaluate()
.setTitle('MySidebar')
.setWidth(400)
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
SpreadsheetApp.getUi().showSidebar(output);
}
index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<input type="text" id ='textValue' name='textValue' value=''/>
<script>
document.getElementById('textValue').setAttribute('value',google.script.run.testGetFieldName());
</script>
</body>
</html>
In your script, how about the following modification?
Google Apps Script side:
From:
var html = HtmlService.createTemplateFromFile('index');
var output = html.evaluate()
To:
var html = HtmlService.createTemplateFromFile('index');
html.value = testGetFieldName();
var output = html.evaluate()
HTML side:
From:
document.getElementById('textValue').setAttribute('value',google.script.run.testGetFieldName());
To:
document.getElementById('textValue').setAttribute('value', '<?= value ?>');
Note:
If you want to use google.script.run, how about the following modification?
From
document.getElementById('textValue').setAttribute('value',google.script.run.testGetFieldName());
To
google.script.run.withSuccessHandler(e => {
document.getElementById('textValue').setAttribute('value', e);
}).testGetFieldName();
Reference:
HTML Service: Templated HTML
In general, it's a best practice to separate your HTML,CSS,JavaScript files.
References
HtmlService Best Practices
Goal: The purpose is that a sheet will contain information, this information is placed inside a namedrange, the namedrange will be dynamic (the entire column is given a namedrange).
I created a html popup which contains a dropdown list. This dropdown list must contain the list of information from the namedrange.
I am unable to understand how this is to be done. Here is the code below:
function fncOpenMyDialog() {
var htmlDlg = HtmlService.createHtmlOutputFromFile('HTML_myHtml')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setWidth(200)
.setHeight(150);
SpreadsheetApp.getUi()
.showModalDialog(htmlDlg, 'New File');
};
function onInstall(e) {
onOpen(e);
}
function onOpen(e) {
var ui = SpreadsheetApp.getUi();
ui.createMenu('New')
.addItem('New Save File Extension','fncOpenMyDialog')
.addToUi();
}
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<select name="nameYouWant" placeholde="File Type">
<option value="something">Word</option>
<option value="anything">MS Excel</option>
<option value="anything">MS Powerpoint</option>
<option value="anything">MS Slides</option>
</select>
<hr/>
<p>Choose a file, which will then be saved into your Google Drive.</p>
<button onmouseup="closeDia()">Close</button>
<button onmouseup="onOpen()">Save</button>
<script>
window.closeDia = function() {
google.script.host.close();
};
window.saveDia = function() {
onOpen();
};
</script>
</body>
</html>
As you can see in my html file, that the extensions are currently hardcoded.
I am trying to make this dynamic, how do I achieve this?
I believe your goal as follows.
You want to put the values to the dropdown list by retrieving from the named range of the Spreadsheet.
In this case, is the named range the same with this thread?
For this, how about this answer?
Modification points:
From google.script.host.close(), I understood that the HTML file of HTML_myHtml is included in the Google Apps Script project. By this, I would like to propose to achieve your goal using google.script.run.
If the named range is the same with your previous question, you can use it by modifying a little.
When above points are reflected to your script, it becomes as follows.
Modified script:
HTML and JavaScript side: HTML_myHtml
Please modify HTML_myHtml as follows.
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<select id="select" name="nameYouWant" placeholde="File Type"></select>
<hr />
<p>Choose a file, which will then be saved into your Google Drive.</p>
<button onmouseup="closeDia()">Close</button>
<button onmouseup="onOpen()">Save</button>
<script>
google.script.run.withSuccessHandler(v => {
const obj = document.getElementById("select");
v.forEach(e => {
const option = document.createElement("option");
option.text = e;
option.value = e;
obj.appendChild(option);
});
}).readNamedRange();
window.closeDia = function() {
google.script.host.close();
};
window.saveDia = function() {
onOpen();
};
</script>
</body>
</html>
Google Apps Script side: Code.gs
At above HTML, readNamedRange() is used. So please put the following script. If you have the same function names, please modify them. In this script, the values are retrieved from the named range of listDown, and sent to HTML side using google.script.run.
function readNamedRange() {
var activeSheet = SpreadsheetApp.getActiveSheet();
var result = activeSheet.getRange("listDown").getValues();
var end = activeSheet.getLastRow();
var values = [];
for (var i = 0; i < end; i++) {
if (result[i][0] != "") {
values.push(result[i][0]);
}
}
return values;
}
Note:
About window.saveDia = function() {onOpen()};, unfortunately, I couldn't understand about what you want to do.
Reference:
Class google.script.run
Ok, so I am trying to make a function in google sheets that when the user selects a cell and then runs the function (currently trying to make), a sidebar getting all the synonyms of the word should appear. I am using https://words.bighugelabs.com/ to get the synonyms. So first I make the menu:
`function onOpen(e) {
var ui = SpreadsheetApp.getUi().createMenu("Sidebar")
.addItem("Get Synonym", 'showSidebar')
.addToUi();
}`
Then this is the showSidebar function:
function showSidebar() {
var html = HtmlService.createHtmlOutputFromFile("Test")
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setWidth(150)
.setTitle("My Sidebar");
SpreadsheetApp.getUi().showSidebar(html);
}
This is the html file:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function doSomething() {
var synonyms = google.script.run.getSynonym();
document.getElementById("synonyms").innerHTML = synonyms;
}
</script>
</head>
<body>
<div>
<span style="color:orange;">This is a test sidebar!</span>
<button onclick="doSomething()">Click Me!</button>
<div id="synonyms"></div>
</div>
</body>
</html>
And this is the getSynonym function:
function getSynonym() {
var word = SpreadsheetApp.getActiveRange().getValue();
var synonyms = [];
var response = UrlFetchApp.fetch("http://words.bighugelabs.com/api/2/{my_api_key}/" + word + "/json");
response = JSON.parse(response);
var synonyms = response.adjective.syn;
return synonyms;
}
But the variable synonyms which as an array of synonyms doesn't get returned to the doSomething function in the Html file.
What I want is that the sidebar should get a list of all the synonyms.
So basically I can't get the data from one function to another...and I want to know if this is the right way.
When calling server side functions using google.script.run you need to define a success handler, which will asynchronously receive your response.
See the examples on: https://developers.google.com/apps-script/guides/html/communication
function onSuccess(synonyms ) {
console.log(synonyms);
}
google.script.run.withSuccessHandler(onSuccess).doSomething();
Below is a fully functional and working code . When I copy paste it to a text file testFile.html and then open it with a browser it works fine.
But I want the selectCollege function to execute right after the initViz function
I tried this
<body onload="initViz();selectCollege('Engineering');"> . . .
But it didn't work. How can I make the selectCollege function to execute right after the initViz ?
<!DOCTYPE html>
<html>
<head>
<title>Select Marks</title>
<script type="text/javascript"
src="https://public.tableau.com/javascripts/api/tableau-2.min.js"></script>
<script type="text/javascript">
var viz, sheet;
function initViz() {
var containerDiv = document.getElementById("vizContainer"),
url = "http://public.tableau.com/views/RegionalSampleWorkbook/College",
options = {
"Academic Year": "",
hideTabs: true,
onFirstInteractive: function () {
sheet = viz.getWorkbook().getActiveSheet();
}
};
viz = new tableau.Viz(containerDiv, url, options);
}
function selectCollege(college_name) {
sheet.selectMarksAsync("College", college_name, tableau.SelectionUpdateType.REPLACE);
}
</script>
</head>
<body onload="initViz();">
<div id="vizContainer"></div>
<br />
<button onclick="selectCollege('Engineering');">Select a value</button>
</body>
</html>
In selectCollege() you are attempting to access sheet before it is defined in the callback function from the tableau.Viz options object, namely onFirstInteractive(). In order to solve this, you can call the function after defining sheet in that function:
options = {
...
onFirstInteractive: function () {
sheet = viz.getWorkbook().getActiveSheet();
selectCollege('Engineering');
}
};
And according to this forum, onFirstInteractive() will be called once when your instance of tableau.Viz is first rendered.
Create a new function
function init(){
initViz();
selectCollege('Engineering');
}
Then call the init function
window.onload = init;
function initViz(college_name) {
//your code
viz = new tableau.Viz(containerDiv, url, options);
//then
selectCollege('engineering');
}
function selectCollege(college_name) {
sheet.selectMarksAsync("College", college_name, tableau.SelectionUpdateType.REPLACE);
}
Use it like this
This works for me
function bar() {
alert("bar");
}
function foo() {
alert("foo");
}
<!DOCTYPE html>
<html>
<body onload="bar();foo();">
</body>
</html>
...
<body>
... All other tags..
<script>
//just before closing body
function(){
}()
</script>
</body>
....
Call your function just before closing body within a script tag.
HTML tree interpreted sequentially. So that's how I add loading message for SPAs.