HtmlService: google.script.run not recognizing gs function - javascript

I'm currently trying to pass an array of values from a Google Sheet to the HtmlService where I will have the user choose an option and eventually pass it back to the .gs script. I have been using these two links as references:
1. Google Documentation
2. Stack Overflow example
When running the code, I looked at my console and noticed this error:
VM3051:4 Uncaught TypeError: google.script.run.withSuccessHandler(...).getVersionArray is not a function
It appears that getVersionArray() is not being passed correctly. When removing this function from the rest of that google.script.run call, the error goes away.
Also, per link two, I tried that code with the template and never even got a window to pop up, so I have been using the HtmlOutput example from the Google documentation link as a starting point. I have also tried the code with and without the SandboxMode declaration.
gs code:
function bugPieChart() {
getVersionArray();
openDialog();
function getVersionArray() {
var ss = SpreadsheetApp.getActive();
var valuesR = ss.getSheetByName("report").getRange('R1:R').getValues();
var valuesS = ss.getSheetByName("report").getRange('S1:S').getValues();
var versionRSArray = [];
for (var i = 0; i < valuesR.length; i++) {
versionRSArray.push(valuesR[i][0]);
}
for (var i = 0; i < valuesS.length; i++) {
versionRSArray.push(valuesS[i][0]);
}
versionRSArray.sort();
var uniqueArray = [];
uniqueArray.push(versionRSArray[0]);
for (var i in versionRSArray ) {
if((uniqueArray[uniqueArray.length-1]!=versionRSArray[i]) && (versionRSArray[i] !== "")) {
uniqueArray.push(versionRSArray[i]);
}
}
return uniqueArray;
}
function openDialog() {
var html = HtmlService.createHtmlOutputFromFile('index');
SpreadsheetApp.getUi().showModalDialog(html, 'Dialog title');
var htmlOutput = html.setSandboxMode(HtmlService.SandboxMode.NATIVE);
return htmlOutput;
}
}
index.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script>
$(function() {
google.script.run.withSuccessHandler(buildOptionsList)
.getVersionArray();
});
function buildOptionsList(uniqueArray) {
var list = $('#optionList');
list.empty();
for (var i = 0; i < uniqueArray.length; i++) {
list.append('<option value="' + uniqueArray[i].toLowerCase() + '">' + uniqueArray[i] + '</option>');
}
}
</script>
</head>
<body>
<select id="optionList">
<option>Loading...</option>
</select>
<input type="button" value="Close" onclick="google.script.host.close()" />
</body>
</html>

I think your just missing a closing bracket on the function above it.
function bugPieChart() {
getVersionArray();
openDialog();
}
function getVersionArray() {
var ss = SpreadsheetApp.getActive();
var valuesR = ss.getSheetByName("report").getRange('R1:R').getValues();
var valuesS = ss.getSheetByName("report").getRange('S1:S').getValues();
var versionRSArray = [];
for (var i = 0; i < valuesR.length; i++) {
versionRSArray.push(valuesR[i][0]);
}
for (var i = 0; i < valuesS.length; i++) {
versionRSArray.push(valuesS[i][0]);
}
versionRSArray.sort();
var uniqueArray = [];
uniqueArray.push(versionRSArray[0]);
for (var i in versionRSArray ) {
if((uniqueArray[uniqueArray.length-1]!=versionRSArray[i]) && (versionRSArray[i] !== "")) {
uniqueArray.push(versionRSArray[i]);
}
}
return uniqueArray;
}
function openDialog() {
var html = HtmlService.createHtmlOutputFromFile('index');
SpreadsheetApp.getUi().showModalDialog(html, 'Dialog title');
var htmlOutput = html.setSandboxMode(HtmlService.SandboxMode.NATIVE);
return htmlOutput;
}

Related

Convert excel to json but with only one header

I am trying to write an html with JS program that will convert an excel file into json which is does bit it does not format it the way I need to. So basically it spits out when finished
[
{
"imei": "357271093291264"
},
{
"imei": "353094106032150"
},
{
"imei": "353112106434588"
}
]
but what I need is.
[
{
"imei": "357271093291264", "353094106032150", "353112106434588"
}
]
So it is taking imei from cell A1 and using it over and over. I just need it
to keep adding on as I go down the rows.
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://unpkg.com/read-excel-file#4.x/bundle/read-excel-file.min.js"></script>
</head>
<body>
<div style="margin: auto;width: 50;margin-top: 80px;padding: 30px;background-color: #dedede;">
<h2>Excel to JSON Converter</h2>
<input type="file" id="input" />
<br> <br>
<textarea name="json-data" id="json-data" rows="25" style="width: 100%;"></textarea>
<br><br>
<button id="dl-json">Download JSON File</button>
</div>
<script>
var input = document.getElementById('input');
input.addEventListener('change', function(){
readXlsxFile(input.files[0]).then(function(data){
var i = 0;
var headers = [];
var json_object = [];
data.map((row, index)=> {
if (i == 0){
headers = row;
}
if (i > 0){
var temp = {};
for (var x = 0; x < row.length; x++){
temp[headers[x]] = row[x];
}
json_object.push(temp);
}
i++;
});
document.getElementById('json-data').value = JSON.stringify(json_object, null, 2)
});
document.getElementById('dl-json').onclick = function() {
var json_str = document.getElementById('json-data').value;
downloadObjectAsJson(json_str, '');
}
function downloadObjectAsJson(str, filename){
var data_str = "data:text/json;charset=utf-8," + encodeURIComponent(str);
var anchor = document.createElement('a');
anchor.setAttribute("href", data_str);
anchor.setAttribute("download", filename + ".json");
}
});
</script>
</body>
</html>
I have tried playing around with it and pulling out certain parts and setting different variables to certain values.
The shape of your output doesn't seem to make sense. Do you want the first element in your output array to be a key:value pair such as "headerText":"row2Value", and then the rest just strings?
If so, this should work for you:
var input = document.getElementById("input");
input.addEventListener("change", function () {
readXlsxFile(input.files[0]).then(function (data) {
let exportData = [];
for (i = 1; i < data.length; i++) {
i === 1
? exportData.push({ imei: data[i].toString() })
: exportData.push(data[i].toString());
}
document.getElementById("json-data").value = JSON.stringify(exportData);
});
document.getElementById("dl-json").onclick = function () {
var json_str = document.getElementById("json-data").value;
downloadObjectAsJson(json_str, "");
};
function downloadObjectAsJson(str, filename) {
var data_str =
"data:text/json;charset=utf-8," + encodeURIComponent(str);
var anchor = document.createElement("a");
anchor.setAttribute("href", data_str);
anchor.setAttribute("download", filename + ".json");
}
});
If you only need the key, then an array of values, this will work better for you:
readXlsxFile(input.files[0]).then(function (data) {
let exportData = [];
for (i = 1; i < data.length; i++) {
exportData.push(data[i].toString());
}
document.getElementById("json-data").value = JSON.stringify({
imei: exportData,
});
});

Push data to different elements, depending on column in google spreadsheet with GAS?

I am working in Google Spreadsheet with GAS, and I am trying to push some data from a spreadsheet to an HTML page, and right now that is working. But I am managing to do is grabbing all the values, and each time it hits a new row, it grabs all the values in that row pushes them into a newly created <div>. But I would like to do is have some column functionality also so that the different columns gets pushed to a different element like an <input> or a <select> element.
I tried out some things where I declared some variables for the desired columns, and trying to pushing them to the HTML one by one, but it didn't work out.
Here is my data:
This is what it looks like in the HTML:
This is what I am going for:
Would it be better to publish this into tables? Because I simply thought of creating divs with classes and set their width and line breaks?
Below is the code I described in the beginning:
Code.gs
var ss = SpreadsheetApp.openById("1c7IwmyBrbNq5xwzo-7EyFewCx31WpfP4EzLpkHawffI");
function doGet(request) {
return HtmlService.createTemplateFromFile('stuff')
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename).getContent();
}
function getStitchOrders(){
var ordersName = [];
var sheet = ss.getSheetByName("Cat1");
var subRange = sheet.getRange(2, 1, sheet.getLastRow(), sheet.getLastColumn());
var orders = subRange.getValues();
for (var i = 0; i < orders.length; i++) {
ordersName.push( orders[i] )
}
return ordersName;
}
stuff.html
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="orders">
//Data is listed here.
</div>
<script>
$(function() {
google.script.run.withSuccessHandler(buildOrderList).getStitchOrders();
});
function buildOrderList(ordersName) {
var rows = $('#orders');
for (var i = 0; i < ordersName.length; i++) {
rows.append('<div name="' + ordersName[i] + '">' + ordersName[i] + '</div>');
}
}
</script>
Any suggestions?
Edit
Code2.gs
var ss = SpreadsheetApp.openById("1c7IwmyBrbNq5xwzo-7EyFewCx31WpfP4EzLpkHawffI");
function doGet(request) {
return HtmlService.createTemplateFromFile('stuff2')
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename).getContent();
}
function getStitchOrders(){
var ordersName = [];
var sheet = ss.getSheetByName("Sheet");
var subRange = sheet.getRange(2, 1, sheet.getLastRow(), sheet.getLastColumn());
var orders = subRange.getValues();
for (var i = 0; i < orders.length; i++) {
ordersName.push( {
name: orders[i][0],
status: orders[i][1],
comment: orders[i][2]
} );
}
return JSON.stringify(ordersName);
}
stuff2.html
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="orders">
</div>
<script>
$(function() {
google.script.run.withSuccessHandler(buildOrderList).getStitchOrders();
});
function buildOrderList(ordersName) {
var arr = JSON.Parse(ordersName);
var rows = $('#orders');
for (var i = 0; i < arr.length; i++) {
rows.append('<div name="' + arr[i].name + '">' + arr[i].name + '</div>');
}
}
</script>
consider returning the data with this type of pattern:
for (var i = 0; i < orders.length; i++) {
ordersName.push( {
name: orders[i][0],
status: orders[i][1],
comment: orders[i][2]
} );
}
return JSON.stringify(ordersName);
then back in the client-side JS we can turn it back into an Array to loop through:
function buildOrderList(ordersName) {
var arr = JSON.parse(ordersName);
var rows = $('#orders');
for (var i = 0; i < arr.length; i++) {
// values can now be referenced via...
// arr[i].name
// arr[i].status;
// arr[i].comment;
rows.append(...);
}
}
how to then style the divs and the elements inside them to align up like a table is more a CSS question.

onkeyup event on dynamic array

Good Evening,
I am having trouble setting up the onkeyup event. I am trying to get it to fire an objects method when a user enters text into the text field. It does not seem to find the object.
I have cut down on the code and have made the following sample:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<script>
var ReportModule = new function () {
function ReportObj(id, title) {
this.id = id;
this.title = title;
this.result = "";
this.empno = "";
this.UpdateEmpno = function (empNo, resultBoxID) {
this.empno = empNo;
$(resultBoxID).update("Result: " + empNo);
};
};
var ReportObjArray = new Array();
var test1 = new ReportObj("box1", "First object");
var test2 = new ReportObj("box2", "Second object");
ReportObjArray.push(test1);
ReportObjArray.push(test2);
this.Initialize = function () {
for (i = 0; i < ReportObjArray.length; i++) {
var container = document.createElement("div");
container.id = ReportObjArray[i].id;
container.textContent = ReportObjArray[i].title;
$('#Container').append(container);
var empnoInput = document.createElement("input");
empnoInput.type = "text";
empnoInput.id = ReportObjArray[i].id + "_Empno";
empnoInput.onkeyup = function (event) {
// Update Report Objects empno field
ReportObjArray[i].UpdateEmpno(empnoInput.value,empnoInput.id); // <-------- Undefined here
};
$('#' + ReportObjArray[i].id).append(empnoInput);
var container2 = document.createElement("div");
container2.id = ReportObjArray[i].id + "_result";
container2.style.border = "1px solid black";
container2.style.width = "100px";
container2.textContent = "Result:";
$('#' + container.id).append(container2);
};
};
}
</script>
</head>
<body onload="ReportModule.Initialize()">
<div id="Container"></div>
</body>
</html>
Update: It works when searching for the object in the ReportObjArray and matching the correct object. However, I was wondering if there was a more efficient way instead of having to look through the array each time.
empnoInput.onkeyup = function (event) {
// Update Report Objects empno field
var target_id = document.getElementById(event.target.id).id;
for (j = 0; j < ReportObjArray.length; j++) {
if (target_id = ReportObjArray[j].id) {
ReportObjArray[j].UpdateEmpno(document.getElementById(event.target.id).value,empnoInput.id);
break;
}
}
};
Wrap your for loop code in a closure:
for (i = 0; i < ReportObjArray.length; i++) {
(function(i) {
// code
})(i);
}
Working JS Fiddle:
http://jsfiddle.net/23vkS/

Javascript/HTML button click error

I am using JavaScript with my html page to try an get a button to show a message to the user, but when I click the button, nothing happens. Is there something I am doing wrong?
<input type="button" name="get" id="getmsg" value="Get Message"/>
<script type="text/javascript">
document.getElementById("getmsg").onclick = msgtouser;
function (msgtouser)
{
var msg = "";
var topick = "012345";
for(var i = 0; i < 8; ++i)
{
msg += topick[Math.floor((Math.random()*topick.length)+1)];
}
alert(msg);
}
</script>
That is not how you define a function
function (msgtouser)
should be
function msgtouser ()
Try on this way:
document.getElementById("getmsg").onclick = msgtouser;
function msgtouser()
{
var msg = "";
var topick = "012345";
for(var i = 0; i << 8; ++i)
{
msg += topick[Math.floor((Math.random()*topick.length)+1)];
}
alert(msg);
}
Note function msgtouser() instead function (msgtouser).
Here are some of the points which you need to correct:
function (msgtouser) should be function msgtouser ()
Use window.load or .ready() function.
My guess is you are trying to generate random number between 1 and 012345 i.e topick.length,if so then remove that outer array topick[].
Here is a working code:
window.onload=function(){
document.getElementById("getmsg").onclick = msgtouser;
function msgtouser()
{
var msg = "";
var topick = "012345";
for(var i = 0; i < 8; ++i)
{
msg += Math.floor((Math.random()*topick.length)+1);
}
alert(msg);
}
}

Creating Navigation from text file

i have following peice of code...
but showing error *Uncaught type reference Cannot call method 'split' of undefined *
<script src="jquery-1.7.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
var textFile = "nav.txt";
jQuery.get(textFile, function (textFileData) {
var EachLineInTextFile = textFileData.responseText.split("\n");
for (var i = 0, len = EachLineInTextFile.length; i < len; i++) {
STORE_TO_REPLACE = EachLineInTextFile[i];
//STORE_TO_REPLACE: I would have to the entire format of your file to do this.
console.log(STORE_TO_REPLACE);
}
})
});
</script>
nav.txt file is below
a a.aspx
b b.aspx
c c.aspx
Remove the .responseText part.
$(document).ready(function () {
var textFile = "nav.txt";
jQuery.get(textFile, function (textFileData) {
var EachLineInTextFile = textFileData.split("\n");
for (var i = 0, len = EachLineInTextFile.length; i < len; i++) {
STORE_TO_REPLACE = EachLineInTextFile[i];
//STORE_TO_REPLACE: I would have to the entire format of your file to do this.
console.log(STORE_TO_REPLACE);
}
})
});

Categories

Resources