In below example I am sharing data between JavaScript and JSP files. I can successfully send data from File1.js to File2.jsp, But I am not getting value back from File2.jsp to File1.js. It was working fine with IE5 when I used ShowModalDialogue function, but it is not working with window.open() function.
I tried using localStorage, but it is not working out. I am always getting returnValue, data1 and data2 as undefined or empty. Is there any solution to get value from the file2.jsp? Thank you in advance.
file1.js
function framedialog() {
data1 = new Array();
data2 = new Array();
var pm = new Object();
pm.data1 = data1;
pm.data2 = data2;
var url = "http://locahost:8080/File2.jsp";
var returnValue = window.open(url, pm, '', '');
if (returnValue == '1') {
for (i in data1) {
alert(data1[i]);
alert(data2[i]);
}
}
}
File2.jsp
<html>
<head>
<script>
var count=5;
var tabco=new Array(count);
function ActionOK(){
tabco=['aa','bb','cc'];
for(j in tabco){
data1[j]=tabco[j];
}
tabcoTitle=['1','2','3'];
for(k in tabcoTitle){
data2[k]=tabcoTitle[k];
}
top.opener.returnValue="1";
}
</script>``
</head>
<body class="">
<input type="button" name="ok" value="ok" onClick="ActionOk()">
</body>
</html>
enter code here
I am trying to make a web app that will import excel file and pass it to google sheets. The idea is that different people will be uploading theirs table (format is the same) through web app to my spreadsheet where I will do the rest of the job.
For now I got this:
js code;
function doGet(e) {
Logger.log(e.parameter);
return HtmlService.createHtmlOutputFromFile("index");
}
function toroku(userInfo){
var url = "https://docs.google.com/spreadsheets/d/1gCMXhBTba-8PNeN5lk5wrumUGe_f4xNdip1DPCpaRSw/edit#gid=0";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("upload");
ws.appendRow([userInfo.table]);
}
And html;
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.8.0/jszip.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.8.0/xlsx.js"></script>
<script>
var ExcelToJSON = function() {
this.parseExcel = function(file) {
var reader = new FileReader();
reader.onload = function(e) {
var data = e.target.result;
var workbook = XLSX.read(data, {
type: 'binary'
});
workbook.SheetNames.forEach(function(sheetName) {
// Here is your object
var XL_row_object = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
var json_object = JSON.stringify(XL_row_object);
console.log(JSON.parse(json_object));
jQuery( '#xlx_json' ).val( json_object );
})
};
reader.onerror = function(ex) {
console.log(ex);
};
reader.readAsBinaryString(file);
};
};
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
var xl2json = new ExcelToJSON();
xl2json.parseExcel(files[0]);
}
</script>
<form enctype="multipart/form-data">
<input id="upload" type=file name="files[]">
</form>
<textarea class="form-control" rows=35 cols=120 id="xlx_json"></textarea>
<script>
document.getElementById('upload').addEventListener('change', handleFileSelect, false);
document.getElementById('upload').addEventListener('click', handleFileSelect).value
google.script.run.toroku(handleFileSelect);
document.getElementById("upload").value = "";
</script>
<div class="form-row">
<button id="btn">登録!</button>
</div>
<script>
document.getElementById("btn").addEventListener("click",doStuff);
function doStuff(){
var userInfo = {};
userInfo.table = document.getElementById("xlx_json").value;
google.script.run.toroku(userInfo);
document.getElementById("xlx_json").value = "";
}
</script>
</body>
</html>
It reads the data from the excel and imports it to google sheets, but I'm getting an array not a table.
This is what I am getting imported to google sheets:
[{"Product":"2132030501430 ","Customer":"A","Units":"1","Deliver":"1"},{"Product":"2188130546030 ","Customer":"B","Units":"2","Deliver":"3"},{"Product":"2132650259800 ","Customer":"A","Units":"1","Deliver":"5"},{"Product":"2138512138000 ","Customer":"B","Units":"0","Deliver":"6"},{"Product":"2132032500270 ","Customer":"A","Units":"-10","Deliver":"7"},{"Product":"2116104013159 ","Customer":"B","Units":"200","Deliver":"8"},{"Product":"2116102039910 ","Customer":"A","Deliver":"9"},{"Product":"2145710030310 ","Customer":"B","Deliver":"10"},{"Product":"2132630164760 ","Customer":"A","Deliver":"9"},{"Product":"2116105051990 ","Customer":"B","Units":"0","Deliver":"5"},{"Product":"2145721006510 ","Customer":"A","Units":"0","Deliver":"4"},{"Product":"2132030900430 ","Customer":"B","Units":"7","Deliver":"3"},{"Product":"2132031500270 ","Customer":"A","Units":"5","Deliver":"2"},{"Product":"2138506049100 ","Customer":"B","Units":"6","Deliver":"1"},{"Product":"2132042501730 ","Customer":"C","Units":"31","Deliver":"9"},{"Product":"2132030901470 ","Customer":"D","Units":"20","Deliver":"8"},{"Product":"2116101050089 ","Customer":"F","Units":"126","Deliver":"7"},{"Product":"2116104051870 ","Customer":"C","Units":"3","Deliver":"6"},{"Product":"2188131528030 ","Customer":"D","Units":"82","Deliver":"4"},{"Product":"2145718013050 ","Customer":"F","Deliver":"4"},{"Product":"2188140578030 ","Customer":"C","Units":"20","Deliver":"4"},{"Product":"2132640087170 ","Customer":"D","Deliver":"4"},{"Product":"2138506026000 ","Customer":"F","Units":"0","Deliver":"4"},{"Product":"2132042501770 ","Customer":"C","Units":"15","Deliver":"4"},{"Product":"2187106025940 ","Customer":"D","Units":"90","Deliver":"4"}]
My question is how can I convert it into a table?
should it be done on html side?
Also I would like to say that I am newbie in programing world so please tell me in the simplest way what should I do with this.
Best Regards!
I believe your goal as follows.
When a XLSX file on the local PC is selected, you want to retrieve the XLSX data and put to textarea using Javascript and xlsx.js.
When a bottom button is clicked, you want to send the values in textarea to Google Apps Script side, and want to put the values to the Google Spreadsheet.
From Excel file has only one sheet with one simple table, I understood that the XLSX data has only one sheet.
Modification points:
In your script, when there are multiple sheets in the XLSX data, the values of only the last sheet are sent to Google Apps Script. Because the values of other sheets are overwritten in workbook.SheetNames.forEach().
But from your replying, I could understand that you suppose that the XLSX data has only one sheet. So in this case, your script becomes more simple.
In your script, an error occurs at document.getElementById('upload').addEventListener('click', handleFileSelect).value.
In order to put the values to the Spreadsheet, I would like to propose to use setValues instead of appendRow. When setValues is used, the values of the multiple rows and columns can be put with one call.
In this case, the values are required to be 2 dimensional array.
When above points are reflected to your script, it becomes as follows.
Modified script:
Google Apps Script side:
function doGet(e) {
Logger.log(e.parameter);
return HtmlService.createHtmlOutputFromFile("index");
}
function toroku(userInfo){
var values = JSON.parse(userInfo.table);
var url = "https://docs.google.com/spreadsheets/d/1gCMXhBTba-8PNeN5lk5wrumUGe_f4xNdip1DPCpaRSw/edit#gid=0";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("upload");
ws.getRange(ws.getLastRow() + 1, 1, values.length, values[0].length).setValues(values);
}
HTML & Javascript side:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.8.0/jszip.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.8.0/xlsx.js"></script>
<form enctype="multipart/form-data">
<input id="upload" type=file name="files[]">
</form>
<textarea class="form-control" rows=35 cols=120 id="xlx_json"></textarea>
<div class="form-row">
<button id="btn">登録!</button>
</div>
<script>
document.getElementById('upload').addEventListener('change', handleFileSelect, false);
document.getElementById("btn").addEventListener("click", doStuff);
var ExcelToJSON = function() {
this.parseExcel = function(file) {
var reader = new FileReader();
reader.onload = function(e) {
var data = e.target.result;
var workbook = XLSX.read(data, {type: 'binary'});
jQuery('#xlx_json').val(JSON.stringify(XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]], {header: 1})));
};
reader.onerror = function(ex) {
console.log(ex);
};
reader.readAsBinaryString(file);
};
};
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
var xl2json = new ExcelToJSON();
xl2json.parseExcel(files[0]);
}
function doStuff() {
var userInfo = {};
userInfo.table = document.getElementById("xlx_json").value;
google.script.run.toroku(userInfo);
document.getElementById("xlx_json").value = "";
}
</script>
</body>
</html>
Note:
When you modified the script of Web Apps, please redeploy the Web Apps as new version. By this, the latest script is reflected to the Web Apps. Please be careful this.
References:
appendRow(rowContents)
setValues(values)
Re-worded objective:
I'm creating a web page using google apps script. I want to have multiple drop downs listed on the page. I know if I use <select><option>, I can create a list of hard coded options. What I would rather do is grab the options from a google sheet to display in the drop down, this way I can update it at anytime without modifying the HTML code.
The issue: While I was successful in creating a drop down selection containing Column A values from my sheet, I'm running into an issue where Apps Script will not let me create another drop down containing the values of Column B.
This is my sheet that contains names and dietary types. Each column contains the options for each drop down.
This is what it looks like on the front end. I'd like to have another drop down beside it that contains values from Column B (as seen above).
Here is my script:
var url = "google sheets URL";
function doGet(e){
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Staff");
var list = ws.getRange(1,1,ws.getRange("A1").getDataRegion().getLastRow(),1).getValues();
var tmp = HtmlService.createTemplateFromFile("index");
tmp.list = list.map(function(r){ return r[0]; });
return tmp.evaluate();
}
This is the HTML for my selection list:
<select id="app" class="browser-default">
<option disabled selected>Select a teammate!</option>
<? for(var i=0;i<list.length;i++){ ?>
<option><?= list[i]; ?></option>
<? } ?>
</select>
It functions correctly at this point but when trying to replicate it so I can grab another column in Google Sheets and use that as another selection list,
I get: Referenceerror: "list" is not defined.
This is the script that's causing me to get the error.
var url = "google sheets URL";
function doGet(e){
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Staff");
var list = ws.getRange(1,1,ws.getRange("A1").getDataRegion().getLastRow(),1).getValues();
var tmp = HtmlService.createTemplateFromFile("index");
tmp.list = list.map(function(r){ return r[0]; });
return tmp.evaluate();
}
function doGet(f){
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Variables");
var list2 = ws.getRange(1,1,ws.getRange("A1").getDataRegion().getLastRow(),1).getValues();
var tmp2 = HtmlService.createTemplateFromFile("index");
tmp2.list2 = list2.map(function(r){ return r[0]; });
return tmp2.evaluate();
}
Here's a simple example of getting multiple list from a dialog.
Load the code and run launchDialog(). You could also add a doGet() and use return HtmlService.createHtmlOutputFromFile('aq4');
Code.gs:
function getList(n) {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Sheet1');
var rg=sh.getRange(2,n,sh.getLastRow()-1,1);
return rg.getValues().map(function(r){return r[0]});
}
function launchDialog() {
var userInterface=HtmlService.createHtmlOutputFromFile('aq4');
SpreadsheetApp.getUi().showModelessDialog(userInterface, 'My List');
}
aq4.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<style>
input{margin:5px;}
td,th{border:1px solid black;}
</style>
<script>
$(function(){
google.script.run
.withSuccessHandler(function(vA){
var select=document.getElementById('sel1');
select.options.length=0;
for(var i=0;i<vA.length;i++) {
select.options[i] = new Option(vA[i],vA[i]);
}
})
.getList(1);
});
function getAnotherList() {
google.script.run
.withSuccessHandler(function(vA){
var select=document.getElementById('sel1');
select.options.length=0;
for(var i=0;i<vA.length;i++) {
select.options[i] = new Option(vA[i],vA[i]);
}
})
.getList(Math.floor(Math.random()*23));
}
console.log("My Code");
</script>
</head>
<body>
<select id="sel1"></select>
<input type="button" value="Get Another List" onClick="getAnotherList();" />
</body>
</html>
Here's my List Spreadsheet:
I need to load the text file data into a javascript array and define a dynamic form using html.
I tried below code for extracting data from text file and to store in a javascript array and it works as long as it is in .js file
var fs = require('fs');
var textByLine = fs.readFileSync('123.txt').toString().split("\n");
console.log(textByLine);
but when I embed it inside my html file this doesn't work.
below is my html code. for now I am just forming an array with months but i need to replace it with array taken from the text file.
<html>
<head>
<title></title>
<META NAME="DESCRIPTION" CONTENT="">
<META NAME="KEYWORDS" CONTENT="">
<script language="javascript">
var dt=new Date();
var dt_month=dt.getMonth() +1;
//alert(dt_month);
function addOption(selectbox,text,value )
{
var optn = document.createElement("OPTION");
optn.text = text;
optn.value = value;
selectbox.options.add(optn);
}
function addOption_list(){
var month = new Array("January","February","March","April","May","June","July","August",
"September","October","November","December");
for (var i=0; i < month.length;++i){
addOption(document.drop_list.Month_list, month[i], month[i]);
document.drop_list.Month_list.options[i].selected=true;
}
}
</script>
</head>
<body onLoad="addOption_list()";>
You can see the view-> Source of this page.
<br><br>
<FORM name="drop_list" action="yourpage.php" method="POST" >
<SELECT NAME="Month_list">
<Option value="" >Month list</option>
</SELECT>
</form>
</body>
</html>
I gave the 3 line code which is working independently as a .js file inside addOption_list function in above code and it doesn't work. Appreciate help on this.
Thanks in advance
The FileSytem (fs) module is for NodeJS applications so needs to be in .js file. If you want to load the file into your html you can use Ajax instead. This may work:
<script>
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myFunction(this.responseText);
}
};
xhttp.open("GET", "123.txt", true);
xhttp.send();
}
function myFunction(data) {
var textByLine = data.split("\n");
console.log(textByLine);
}
loadDoc();
</script>
How can I parse the value of status = 'logged-out' to the 3 tags below it, updating the value of login_status = 'logged-out'?
<script type="text/javascript">
window.ndm = window.ndm || {};
window.ndm.cam = {'status':'logged-out'};
</script>
<script src="http://foo.com/adserver/ndm/js.php?position=header-ad§ion_id=NEWS&login_status=SUBSCRIBER"></script>
<script src="http://foo.com/adserver/ndm/js.php?position=middle-ad§ion_id=NEWS&login_status=SUBSCRIBER"></script>
<script src="http://foo.com/adserver/ndm/js.php?position=footer-ad§ion_id=NEWS&login_status=SUBSCRIBER"></script>
Keep in mind, there also heaps of other script tags on the page, so to identify the relevant ones. I got this function.
function getScriptSourceName(name){
var scripts = document.getElementsByTagName('script');
for (i=0;i<scripts.length;i++){
if (scripts[i].src.indexOf(name) > -1)
return scripts[i].src;
}}
Therefore to find the relevant script tags I want, i call the function - getScriptSourceName('foo.com');
How can I then update the login_status parameter's value to use the one declare at the very top?
I think this should work (below the HTML file for testing).
Look at changeStatus method (I triggered it by button click for testing).
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<script type="text/javascript">
window.ndm = window.ndm || {};
window.ndm.cam = {'status':'logged-out'};
</script>
<script src="http://foo.com/some.php?login_status=SUBSCRIBER"></script>
<script src="http://foo.com/some.php?login_status=SUBSCRIBER"></script>
<script src="http://foofoo01.com/some.php?login_status=SUBSCRIBER"></script>
<script>
function changeStatus(name)
{
var scripts = document.getElementsByTagName('script');
var scriptsToChange = [];
for (var i = 0; i < scripts.length; i++)
{
if (scripts[i].src.indexOf(name) > -1)
{
var oldSrc = scripts[i].src;
var newSrc = oldSrc.replace(/(login_status=).*/,'$1' + 'logged-out');
scripts[i].setAttribute("src", newSrc);
scriptsToChange.push(scripts[i]);
}
}
for (var k = 0; k < scriptsToChange.length; k++)
{
document.getElementsByTagName("head")[0].appendChild(scriptsToChange[k]);
}
}
</script>
</head>
<body>
<button type="button" onclick="changeStatus('foo.com')">Change status</button>
</body>
</html>