Creating a very simple Dynamic Google Script Web App - javascript

OK I'm stuck at the beginning of setting up a dynamic stand-alone google script. I can't get the button to make any dynamic change to the html. I would figure that clicking the button will call the google script code function and would make a change to the resulting Index.html. What am I missing?
Code.gs:
function doGet() {
return HtmlService
.createHtmlOutputFromFile('Index')
.setTitle('DynamicTest');
}
function DoSomething() {
var obj = document.getElementById("status");
alert("kachow");
obj.innerText = "It's magic!";
}
Index.html
<!DOCTYPE html>
<html>
<body>
<button id="submitButton">Submit</button>
<br />
<div id="status">Static</div>
<br />
<script>
document.getElementById('submitButton').addEventListener('click', function() {
google.script.run.DoSomething();
});
</script>
</body>
</html>
Thanks!
Update Solution: Thanks #Tanaike for the solution! Here is the full code which also adds an pre-processing message as well as a post-processing message that is displayed after the google script app finishes the called function:
<!DOCTYPE html>
<html>
<body>
<button id="submitButton">Submit</button>
<br />
<div id="status">Static</div>
<br />
<script>
document.getElementById('submitButton').addEventListener('click', function() {
var obj = document.getElementById('status');
obj.innerText = 'Processing. Please wait...';
google.script.run.withSuccessHandler(value => {
var obj = document.getElementById("status");
obj.innerText = value;
}).DoSomething();
});
</script>
</body>
</html>
Code.gs
function doGet() {
return HtmlService
.createHtmlOutputFromFile('Index')
.setTitle('DynamicTest');
}
function DoSomething() {
return "It's magic!";
}

Modification points:
In your script, it seems that DoSomething() is not Google Apps Script. I think that it's Javascript. I think that this is the reason of your issue. So when the following modification is done, I think that the script works.
<!DOCTYPE html>
<html>
<body>
<button id="submitButton">Submit</button>
<br />
<div id="status">Static</div>
<br />
<script>
document.getElementById('submitButton').addEventListener('click', function() {
// google.script.run.DoSomething();
DoSomething();
});
function DoSomething() {
var obj = document.getElementById("status");
alert("kachow");
obj.innerText = "It's magic!";
}
</script>
</body>
</html>
But I thought that you might want to communicate between Javascript side and Google Apps Script. So in this case, please modify as follows.
Modified script:
Code.gs:
function doGet() {
return HtmlService
.createHtmlOutputFromFile('Index')
.setTitle('DynamicTest');
}
function DoSomething() {
return "It's magic!";
}
Index.html:
<!DOCTYPE html>
<html>
<body>
<button id="submitButton">Submit</button>
<br />
<div id="status">Static</div>
<br />
<script>
document.getElementById('submitButton').addEventListener('click', function() {
google.script.run.withSuccessHandler(value => {
var obj = document.getElementById("status");
alert("kachow");
obj.innerText = value;
}).DoSomething();
});
</script>
</body>
</html>
Reference:
Class google.script.run

Related

how to put a variable into GAS

Hi so i've been trying to code in Jquery javascript html and google apps script and i have gotten part of the app but i can't do the other half which is to take the jquery variable and print it in a google spread sheet. This is what it looks like right now.
GAS:
function doGet() {
return HtmlService.createTemplateFromFile('index')
.evaluate()
.setTitle('The Game')
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function codefunction() {
Logger.log("In codefunction in codegs");
}
HTML:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h1> The Game </h1>
<b><em>Output:</em></b>
<p id="output">
</p>
<input type="text" id="txt_box"/>
<button type="button" id="input_button" class="enjoy-css">Enter</button>
<?!= HtmlService.createHtmlOutputFromFile('javascript').getContent(); ?>
</body>
</html>
Jquery/javascript:
<script>
$(function() {
$('#input_button').bind('click',clickButton);
linkTocodegs();
});
function clickButton() {
var boxContents = $("#txt_box").val();
$("#txt_box").val("");
outputMessage(boxContents);
}
function outputMessage(message) {
var text = $('#output');
var item = $('<p>');
var title = $('<span>').text(message);
title.append(item);
text.append(title);
}
function linkTocodegs() {
console.log("in code gs function link");
google.script.run.withSuccessHandler(outputMessage)
.codefunction();
}
</script>
You need to get the value out of the text box and pass it to the server:
function linkTocodegs() {
var userInput;
userInput = document.getElementById('txt_box').value;
console.log("in code gs function link");
google.script.run.withSuccessHandler(outputMessage)
.codefunction(userInput);
}
Code.gs
function codefunction(receivedValue) {
Logger.log("In codefunction in codegs: " + receivedValue);
var ss,sh;
ss = SpreadsheetApp.getActiveSpreadsheet();
sh = ss.getSheetByName('sheet1');
sh.getRange(1,1,1,1).setValue(receivedValue);
}

Javascript immediate function call from external function

I am trying to call the immediate function defined in test1.js on click of the button defined under html file. It always throws error "test is undefined". I am little bit aware that being a immediate function, it calls immediately, and so it returns the "undefined error". But is there any way I can call the immediate function (access methods, properties, etc.) on click of the button?
Thank you in advance.
//test1.js
var test = (function(){
alert(window);
var tmp = 'hello';
}());
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script type="text/javascript" src="test1.js"></script>
<input type="button" id="btn1" value="ClickMe!" />
<script type="text/javascript">
var btn = document.getElementById("btn1");
btn.addEventListener("click",fun1,false);
function fun1(){
alert(test.tmp);
}
</script>
</body>
</html>
You have to modify your code so that the IIFE returns an object with a tmp property. Such as
var test = (function(){
alert(window);
var tmp = 'hello';
return {tmp:tmp};
}());
You need to explicitly return an object containing any data you want made available after you run the IIFE. (Just add the return as I did to the snippet below).
//test1.js
var test = (function(){
alert(window);
// you need to return any values you want accessible
return {
tmp: "hello"
}
}());
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script type="text/javascript" src="test1.js"></script>
<input type="button" id="btn1" value="ClickMe!" />
<script type="text/javascript">
var btn = document.getElementById("btn1");
btn.addEventListener("click",fun1,false);
function fun1(){
alert(test.tmp);
}
</script>
</body>
</html>

How to pass parameters to javascript function that are defined outside the form tag?

i am trying to pass a parameter to a javascript function thats been defined outside the tag.but when i try to use it in the javascript function it shows undefined.i am using alert to print the value both in the jsp page and in javascipt function...please help
<html>
<script type="text/javascript">
js_valueDate = '<%=valueDate%>';
alert(js_valueDate) **//displays correct value here**
</script>
<body>
<form>
....some html...
<td width=27%><input type=text name="ValDate"
onchange = "javascript:validateDate(document.f1.ValDate,js_valueDate);"></td>
......some html....
</form>
</body>
</html>
and this is my javascript function:
function validateDate(ValDate,origValDate) {
var valueDate=ValDate.value;
var OrigvalueDate=origValDate.value;
confirm(valueDate);
confirm(OrigvalueDate); **//displays undefined here**
var hh=replaceAll(valueDate,'-','');
confirm(hh);
if (replaceAll(valueDate,"-","")<=valueDate<=replaceAll(OrigvalueDate,"-","")) {
return true;
} else {
alertPopup("Please enter a valid value date");
document.f1.ValDate.focus();
return false;
}
}
Since you are passing the value itself there is no need of the statement var OrigvalueDate=origValDate.value;
Here is a small example which i have written which explains both the situation
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Check </title>
<script>
function display(v)
{
var d=v.value;
alert(v);
alert(d);
}
jval="qwerty";
</script>
</head>
<body>
<input type="button" value="check" onclick="javascript:display(jval)"/>
</body>
</html>
Try something like this. This 'll help you
<html>
<script type="text/javascript">
js_valueDate = '<%=valueDate%>';
alert(js_valueDate) **//displays correct value here**
var ValidationHandler = {
validateDate:function(ValDate,origValDate){
var valueDate=ValDate.value;
var OrigvalueDate=origValDate.value;
confirm(valueDate);
confirm(OrigvalueDate); **//displays undefined here**
var hh=replaceAll(valueDate,'-','');
confirm(hh);
if (replaceAll(valueDate,"-","")<=valueDate<=replaceAll(OrigvalueDate,"-",""))
{
return true;
}
else
{
alertPopup("Please enter a valid value date");
document.f1.ValDate.focus();
return false;
}
}
};
</script>
<body>
<form>
....some html...
<td width=27%><input type=text name="ValDate"
onchange = "javascript:ValidationHandler.validateDate(document.f1.ValDate,js_valueDate);"></td>
......some html....
</form>
</body>
</html>

Why can I call function which is in a shadow dom?

I created a custom element called "memory-box" like the below code.
Please pay attention to the function "logthis" which is in "memory-box-template".
memory-box.html
<template id="memory-box-template">
<input id="memory-box" type="form" />
<input type="button" id="testbutton" />
<script type="text/javascript">
function logthis(me){
console.log(me);
}
</script>
</template>
<script type="text/javascript">
(function() {
var thisDoc = document.currentScript.ownerDocument;
var storage = localStorage;
var proto = Object.create(HTMLElement.prototype, {
createdCallback: {
value: function() {
var temp = thisDoc.querySelector('#memory-box-template');
var con = document.importNode(temp.content, true);
this.createShadowRoot().appendChild(con);
var input = this.querySelector('::shadow #memory-box');
var data = storage.getItem(this.id);
input.value = data;
input.addEventListener('input', saveData.bind(input, this.id));
}
},
});
document.registerElement('memory-box', {
prototype: proto
});
function saveData(id, e) {
storage.setItem(id, this.value);
}
})();
</script>
Now, I uses the custom element "memory-box" like the below code.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="import" href="/html/memory-box.html">
</head>
<body>
<div><memory-box id="memory1"></memory-box></div>
<div><memory-box id="memory2"></memory-box></div>
<div><memory-box id="memory3"></memory-box></div>
<div><memory-box id="memory4"></memory-box></div>
</body>
<script type="text/javascript">
logthis(this);
</script>
</html>
As you can see, I putted a script in the index.html and called the function "logthis" just because I was curious. And no error occurred.
Why?
The function "logthis" is in each shadow doms. It's supposed not able to be called outside the shadow dom, I think.
As explained here, while the HTML within Shadow DOM is encapsulated, any JavaScript is NOT -- it is in the global scope, unless you utilize specific javascript techniques (namescaping, IIFE) to do so.
Hope this helps,
Jonathan Dodd

How do I assign the result of a function into a global variable?

I can't figure out how to assign this function's result into a global variable. I know this is a really basic thing, but can anyone help?
var pixel_code = null
function captureValue(){
pixel_code = document.getElementById("baseText").value;
return pixel_code;
}
pixel_code = captureValue();
Thanks for sharing the jsfiddle of what you were attempting. I see the concern. The captureValue() function is run asynchronously, so the console.log() shortly after defining it doesn't yet have a value. I've stripped and prodded the jsfiddle and come up with this working sample:
<html>
<head>
</head>
<body>
<h1>Welcome to the AdRoll SandBox</h1>
<textarea id="baseText" style="width:400px;height:200px"></textarea><br />
<input type="button" value="test" id="text_box_button" onclick="captureValue()"/>
<input type="button" value="get" id="text_box_button2" onclick="getValue()"/>
<script>
var pixel_code = null;
function captureValue(){
pixel_code = document.getElementById("baseText").value;
return false;
}
function getValue() {
alert(pixel_code);
return false;
}
</script>
</body>
</html>
I added a second button. Type in the textbox, push "test" (to set the value), then push "get" to get the value of the global variable.
Here's the same sample that uses jQuery and a closure to avoid the global variable:
<html>
<head>
</head>
<body>
<h1>Welcome to the AdRoll SandBox</h1>
<textarea id="baseText" style="width:400px;height:200px"></textarea><br />
<input type="button" value="test" id="text_box_button" />
<input type="button" value="get" id="text_box_button2" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script>
$(document).ready(function () {
var pixel_code = null;
$("#text_box_button").click(function (){
pixel_code = document.getElementById("baseText").value;
return false;
});
$("#text_box_button2").click(function () {
alert(pixel_code);
return false;
});
});
</script>
</body>
</html>
If the page reloads, your variable will be reset to it's initial state.
You're reusing pixel_code in and out of the function, which is not a great pattern, but the code you show should work as expected. What error are you seeing? What code surrounds this code that you're not showing? Could all this perhaps be nested inside another function? (Thanks #JosephSilver for the nod.)
Please try this,
var pixel_code='';
function captureValue(){
return document.getElementById("baseText").value;
}
function getValueBack()
{
pixel_code = captureValue();
//alert(pixel_code); /* <----- uncomment to test -----<< */
}

Categories