Transfering output from GAS(Google App Script) to html - html

I'll make the succeeding programs which transfers URL defined by GAS to html.
In this time, I set URL as fix letters for simplification, however,
in the actual situations, URL is generated uniquely in every trial.
function getUrl() {
var url = "https://www.google.co.jp/"
var html = HtmlService.createTemplateFromFile("dialog2").evaluate();
SpreadsheetApp.getUi().showModalDialog(html, "Download File");
}
// error ReferenceError: url is not defined # test.gs:3
html side (dialog2.html)
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
Click here
  <!--↑wanting to get url as a variable letters from the GAS program-->
</body>
</html>
I'm sure that the way of transfering the parameter (this time,url) is the crucial fautor to compile these codes.
If we cannnot get this plan into the practice, please tell me sub plans.
Thank you for checking this question.

I solved this problem by defining the paramerter url as property.
correct code (GAS)
function getUrl() {
var url = "https://www.google.co.jp/"
var html = HtmlService.createTemplateFromFile("dialog2");
html.url = url;
SpreadsheetApp.getUi().showModalDialog(html.evaluate(), "Download File");
}

Related

Updating automatically an HTML content when the imported *.json values are changed

I have an HTML code that imports a LOCAL but UPDATABLE *.json content, and it must be updated automatically when the *.json file is updated.
This is the *.HTML code:
<html>
<head>
<script type="text/javascript" src="sample.json"></script>
<script type="text/javascript" >
function load() {
setInterval(function () {
var mydata = JSON.parse(data);
var div = document.getElementById('data');
div.innerHTML = mydata[0].location.altitude;
}, 100);}
</script>
</head>
<body onload="load()">
<div id="data">
</div>
</body>
</html>
and the adapted sample.json file is:
data = '[{"location": {"altitude": 40}}]';
I just wanna see the altitude is changing in the browser(HTML) whenever the sample.json file is updated.
Now the HTML works but only ONCE, I wanna make it dynamic.
What should I do to make the function setInterval work correctly? or maybe this function works only for local changes, not external ones.
Thnks, Sadeq
If you want the browser to get data from a URL even interval, then you need to write code which gets data from a URL in the interval. e.g. with the Fetch API. (At which point you should make it JSON instead of JS).
However HTTP is not fast. You do not want to be polling over HTTP every 100ms. Consider using Websockets to push the data from the server when it changes instead of polling.

Why would this function generate an http: 500 error on one of my files?

I started getting this error in a lot more complicated script and after a while I tried this extremely simple case. When I click the button I get the error: NetworkError: Connection failure due to HTTP 500
and of course I get the same thing in the console. I've moved it to another file and the error goes away.
gs:
function runTwo() {
SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutputFromFile('test'),'Title');
}
function getMessage() {
return 'Hello World';
}
html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<div id='msg1'></div>
<input type="button" value="Click Me" onClick="iveBeenClick();" />
<script>
function iveBeenClick() {
google.script.run
.withFailureHandler(msg=>{document.getElementById("msg1").innerHTML=msg;})
.withSuccessHandler(msg=>{document.getElementById("msg1").innerHTML=msg;})
.getMessage();
}
</script>
</body>
</html>
Just in case it matters, this file has a webapp deployed that works with a Gmail Addon to delete unwanted emails. And here's that code:
function doGet(e) {
Logger.log('query params: ' + Utilities.jsonStringify(e));
if(e.queryString !=='')
{
switch(e.parameter.mode){
case 'dable':
deleteAllBlackListedEmails2();
return ContentService.createTextOutput("delete black list Done!!!!");
break;
case 'append':
const length=appendToBlackList({deletes:e.parameter.bls});
return ContentService.createTextOutput(length);
break;
case 'length':
return ContentService.createTextOutput(getBlackListLength());
break;
default:
return ContentService.createTextOutput("<h1>Unknown Command: " + e.parameter.mode);
}
}else{
return ContentService.createTextOutput("No Query String");
}
}
I'd like to know what the problem is. But I don't know where to go from here. I could certainly live without knowing and it doesn't seem to be affecting the performance of the other functions but it does impact my ability to built interactive tools for analyzing my data because I can't use google.script.run on any of my dialogs. Anyway I thought I'd ask and see if anyone else might be able to get it to fail.
New Information
Problem went away when I removed a library that I just installed. What should I looked for in that library?
The Fix
Because I was unfamiliar with the new dialog I chose to use the head deployment and I really wanted version 31. I don't know why this causes such an error but the script seems to be back to normal now. I was lucky this time.
I just wanted to share with everyone a simple way to avoid the HTTP 500 problem described above. It's fairly simple to reproduce and looking back upon it I can see now that it occurred because I was unfamiliar with the new editor and I made the simple error of not selecting a version. Instead I left it the head deployments which is a problem.
This is my minimum complete verifiable example.
I created a simple library with only one function and I called it the HTTP500Library
The Function:
function selectColumnsSkipHeader() {
var ss=SpreadsheetApp.getActiveSpreadsheet();
var sht=ss.getActiveSheet();
var rng=sht.getActiveRange();
var rngA= sht.getActiveRange().getA1Notation().split(':');
var ul=rngA[0].replace(/\d+/,'');
if(rng.getNumColumns()>1) {
var lr=rngA[1].replace(/\d+/,'');
}
else {
lr=ul;
}
var rngs=ul + rng.getRow() + ':' + lr;
var outrng=sht.getRange(rngs);
outrng.activate();
}
Then I deployed and actually due to a couple of stupid mistakes I have a couple of deployments
Then I created another spreadsheet called the HTTP500 Problem and I put this code into it:
Code.gs:
function onOpen() {
SpreadsheetApp.getUi().createMenu('My Tools')
.addItem('Simple Dialog', 'runTwo')
.addToUi();
}
function runTwo() {
SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutputFromFile('problem'),'Title');
}
function getMessage() {
return 'Hello World';
}
HTML:
function iveBeenClick() {
google.script.run
.withFailureHandler(msg=>{document.getElementById("msg1").innerHTML=msg;})
.withSuccessHandler(msg=>{document.getElementById("msg1").innerHTML=msg;})
.getMessage();
}
</html><!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<div id='msg1'></div>
<input type="button" value="Click Me" onClick="iveBeenClick();" />
<script>
function iveBeenClick() {
google.script.run
.withFailureHandler(msg=>{document.getElementById("msg1").innerHTML=msg;})
.withSuccessHandler(msg=>{document.getElementById("msg1").innerHTML=msg;})
.getMessage();
}
</script>
</body>
</html>
After setting up the problem I tested the dialog that I just created and it worked fine with no problems.
Then I added the library that I just created but because I was unfamiliar with the new editor I mistakenly chose the head deployment. In other words I didn't select a version.
I ran the dialog again and this time I recieved the Network Connection problem with the HTTP 500 error.
The next step should have been to realize that I didn't select the correct version and return to the dialog and do so and that would have fixed the problem.
So I guess the Network connection that cause the problem was the connection to the library. So don't forget to pick the appropriate deploy of your libraries when you install them.
Thank for all the help

exporting .txt files in html, and then importing it afterwards

So im making a website, and one of its core features I need to get working is getting the web page to export a mundane .txt file containing all the content from the forms I have.
Once that works, I also need to figure out how to import that same file back into the website and have it automatically fill in the text boxes.
How can I go about doing this?
Your question is kind of broad and doesn't show much research effort on your part. It's good form to have a go and then come here when you run into a problem, rather than just ask us to solve your problem for you. Despite that, I'll try to give you some pointers. :)
I recently had a requirement to make a button to download the contents of a div. I made a gist for future reference. You can probably adapt it to your purpose.
Basically what I did was assign a click handler to a HTML button marked 'Download'. When the button is clicked, I create a temporary anchor element on the page and set its href to the contents of the div and then programmatically click on the anchor to fire the download and finally removing the temporary anchor from the page. There's a fallback for Internet Explorer with a different method. I adapted this code from an SO answer some time ago.
var downloadButton = document.getElementById('downloadButton');
downloadButton.addEventListener('click', function () {
//get the contents of the div
var contents = document.getElementById('someDiv').innerHTML;
if (contents.length = 0) {
return;
}
var filename = 'some-filename.txt';
if (navigator.msSaveBlob) { // IE
navigator.msSaveBlob(new Blob([contents], { type: 'text/plain;charset=utf-8;' }), filename);
} else {
var link = document.createElement('a');
link.setAttribute('download', filename);
link.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(contents));
document.body.append(link);
link.click();
document.body.removeChild(link);
}
});
As for your next requirement, upload the file and importing the data, I'll direct you to the HTML5 Rocks - file handling tutorial.
I just had a crack at a quick file uploader and I have it dumping the file contents to the console. You could, instead, parse the file contents and add the data back to your form elements as required. Here's my test code:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>Test Page</title>
<script>
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
// Loop through the FileList
for (var i = 0; i < files.length; i++) {
var reader = new FileReader();
// when the file has been read, print the contents to the console
reader.onloadend = function (evt) {
if (evt.target.readyState == FileReader.DONE) {
console.log(evt.target.result);
}
};
var text = reader.readAsText(files[i]);
}
}
document.addEventListener('DOMContentLoaded', function () {
document.getElementById('files').addEventListener('change', handleFileSelect, false);
});
</script>
</head>
<body>
<input type="file" id="files" name="files[]" multiple />
</body>
</html>

use an include to include an html file that contains a script

I am working on a Google Apps Script. My situation is that I have an index.html file and a few others which should all share a menu on the side.
I therefore have a function as follows
function include(File) {
return HtmlService.createHtmlOutputFromFile(File).getContent();
};
and use
<?!= include('leftMenu'); ?>
to include that in my html files.
The problem I have is that in the included file there is a function called that is defined in my Code.gs
<div class="leftmenu">
Main menu<br>
<?var url = getScriptUrl();?><a href='<?=url?>?page=newInvoice'>New invoice</a><br>
<?var url = getScriptUrl();?><a href='<?=url?>?page=index'>Home</a>
</div>
This function works as I would expect as long as these lines are in the "main" html file but they produce text if they are in the "included" html file.
I hope that makes sense and some one is kind enough to explain what the problem is and hopefully how I can get round it.
Thank you
Neill
14 Dec. 2016 edited to try and explain exactly what my problem is
I have a html file named “newinvoice.html”.
This has javascript functions in it as follows
<script type="text/javascript">
function formSubmit() {
google.script.run.withSuccessHandler(updateUrl).onSubmitButton(document.forms[0]);
}
function updateUrl(url) {
var successMsg = document.getElementById('output');
successMsg.innerHTML = 'New invoice created, saved and sent per Email';
}
</script>
I can move these functions into a separate html file as you suggested. This is called menu_JS.html and is included in my main file with
This works perfectly.
I have a call to one of these these functions - also in the main html “newinvoice.html” This is as follows
<div class="leftmenu">
Main menu<br>
<?var url = getScriptUrl();?><a href='<?=url?>?page=newInvoice'>New invoice</a><br>
<?var url = getScriptUrl();?><a href='<?=url?>?page=index'>Home</a>
</div>
If I move this into a separate file “leftMenu.html” and include that in “newinvoce.html” with
Then the output no longer works.
It appears that the scripts are trying to run before the files are included instead of the include and then the execution as I am used to from PHP.
As always, I appreciate anyone willing to take the time to help me. This is frustrating. Thank you!
Create another HTML file and put the script you want to run client side in that file. Then use the same include statement to include that file.
So make menu_JS.html and place your functions in that, between script tags:
<script>
firstFunction(){
alert("In the first function");
}
secondFunction(){
alert("In the second function");
}
</script>
And in your main HTML template file, preferable after the body loads, place:
<?!= include('menu_JS'); ?>
NOTE that the script is in an HTML file and NOT a Script file.
EDIT: Nov 15 2016
Below is the variation of the function which I have that is working for my needs. Note that I am evaluating the included html file. I had previously used code more similar to your (commented out) and changed it to this some time ago:
function include(filename) {
// return HtmlService.createHtmlOutputFromFile(filename)
return HtmlService.createTemplateFromFile(filename).evaluate()
.getContent();
}
//function includeRaw(filename) {
// return HtmlService.createTemplateFromFile(filename).getRawContent();
//}
And this is how I load the initial html file. This is often in the doGet() function, but may be elsewhere
var result=HtmlService.createTemplateFromFile('GridView').evaluate()
.setTitle('Boxwood Registrations')
.setWidth(1285)
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
return result;

JSON and passing a URL value as a parameter - Chrome Extension

Ok, this is my final tango with this. Below I've listed the code. I'm able to get the value of the url and display it on screen for the current (active tab) in Google Chrome. Now all I have to do is pass that value as a parameter in the URL via JSON. My processing file resides on a our remote server - in php. Everything I've done with respect to this has worked to perfection. However, any attempts to pass the current url or any url as one of the parameters - e.g. ?format=json&url=http://something.com&callback=? - results in nothing. I'm not sure if what I'm doing is wrong or if it is even possible. The important thing to note is that all we are looking to do is pass the url to a remote server for storage, processing etc and send back results. I have everything working but I just can't seem to get the url to pass as a parameter.
<html>
<head>
<title>API JSON Test</title>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.0/jquery.min.js"></script>
<script>
window.addEventListener("load", windowLoaded, false);
function windowLoaded() {
chrome.tabs.getSelected(null, function(tab) {
document.getElementById('currentLink').innerHTML = tab.url;
});
}
</script>
<script type="text/javascript">
$(document).ready(function(){
var timeService =
"http://api.ulore.com/api2.php?key=abce&url="+tab.url+"&format=json&callback=?";
$.getJSON(timeService, function(data) {
$('#showdata').html("<p>url_results="+data.post.url+"</p>");
});
});
</script>
<div id="showdata"></div>
</head>
<body>
</body>
</html>
Again, all the JSON works fine when I'm testing other code. Even if I put in a NON-URL value as a parameter for url=..... it throws the appropriate error. However, it will not accept a URL for some reason.
Any feedback will be greatly appreciated.
Thanks,
Ethan-Anthony
Try encoding and decoding the url.
http://www.w3schools.com/tags/ref_urlencode.asp
http://php.net/manual/en/function.rawurlencode.php
http://phpjs.org/functions/rawurlencode:501