How do I convert a 'undefined' or 'zero' value to string? - javascript

When I retrieve cell value from google sheet with google app script then it returns 'undefined' when the value in that cell is 'zero'. I need it to be remain zero when I send the values to a email.Image Result of the cell value where value is zero in google sheet
function sendEmails() {
var app = SpreadsheetApp;
var targetSheet = app.getActiveSpreadsheet().getSheetByName("Template");
var i,j; var k=4;
for(i=2; i<=2; i++){
var infoData = [];
for(j=2; j<=5; j++){
var cellValues = targetSheet.getRange(i, j).getValue();
infoData.push(cellValues);
}
var emailSheet = app.getActiveSpreadsheet().getSheetByName("Emails");
var currentEmail = app.getActiveSheet().activate().getRange(i, 1).getValue();
var subject = app.getActiveSheet().activate().getRange(i, 2).getValue();
var block = app.getActiveSheet().activate().getRange(i, 3).getValue();
//var emailQuotaRemaining = MailApp.getRemainingDailyQuota();
//Logger.log("Remaining email quota: " + emailQuotaRemaining);
var body = "<h3>Dear Sir/Ma'am,</h3>" +
"<h3>Daily MGNREGA progress Report on different parameters.</h3>" +
"<table border = '1'>" +
"<tr><td>BLOCK: </td><td>" + block + "</td><tr>" +
"</table>" +
"<table border = '1'>" +
"<tr font-style = 'bold'><td>#S.NO</td> <td align = 'center'> PARAMETERS </td><td align = 'center'> VALUES </td></tr>" +
"<tr><td align = 'center'>1.</td> <td align = 'left'> Percentage of NRM Expenditure for the financial year 2019-20 (So far) </td><td align = 'right'>" + infoData[0] + "</td></tr>" +
"<tr><td align = 'center'>2.</td> <td align = 'left'> Percentage of Timely MGNREGA wage payment (T+8 days) FY 2019-20 </td><td align = 'right'>" + infoData[1] + "</td></tr>" +
"<tr><td align = 'center'>3.</td> <td align = 'left'> Work completion rate FY 2017-18 and Earlier in percentage</td><td align = 'right'>" + infoData[2] + "</td></tr>" +
"<tr><td align = 'center'>4.</td> <td align = 'left'> No. of Rejected transactions pending Reconcilation of FY 2018-19 </td><td align = 'right'>" + infoData[3] + "</td></tr>" +
"<tr><td align = 'center'>5.</td> <td align = 'left'> Pending Geotagging Stage- 3 of Phase-II (Completed Works) </td><td align = 'right'>" + infoData[4] + "</td></tr>" +
"<tr><td align = 'center'>6.</td> <td align = 'left'> FTOs Pending for First signatory FY 2019-20 </td><td align = 'right'>" + infoData[5] + "</td></tr>" +
"<tr><td align = 'center'>7.</td> <td align = 'left'> FTOs Pending for Second signatory FY 2019-20 </td><td align = 'right'>" + infoData[6] + "</td></tr>" +
"<tr><td align = 'center'>8.</td> <td align = 'left'> No. of Rejected transactions pending Reconcilation FY 2019-20 </td><td align = 'right'>" + infoData[7] + "</td></tr>" +
"</td></tr>" +
"</table>" +
"<h4>NOTE: This Alert message is valid for Today only. Thanks</h4>" +
"<h3>Regards,</h3>" +
"<h3>DRDA Barpeta</h3>";
var options = {
htmlBody : body
}
MailApp.sendEmail(currentEmail, subject, "", options);
}
}

You can set a default value to cellValue by adding a || 0 so that the cellValue gets set as 0 if targetSheet.getRange(i, j).getValue() returns undefined
Try this
var cellValues = targetSheet.getRange(i, j).getValue() || 0;

It'd be really helpful if we could tell what the raw data of infoData was (I'm not all too familiar with Google App Scripts), but I'll do my best. Now, this isn't code golf, but we can detect and replace all undefined values with 0 with a for loop.
var i;
for (i = 0; i < infoData.length; i++) {
if (infoData[i] == undefined) {
infoData[i] = 0;
}
}
Hope this helps!

Related

Google sheets script - Unable to get background color from cells that are part of pivot table

I have written the following code which replicates a Google Sheets pivot table in HTML along with the formatting to send out in an email.
issue: getBackgrounds() does not return the colours of the cells of the pivot table (it always returns #FFFFF). I verified the range to be correct, because the table is rendered with the correct amount of rows and columns along with the data values. However without styling. Further, if the colour of a cell is changed manually in the Sheets UI before running the script, then getBackgrounds() will fetch that colour. How can I retrieve the formatting of the pivot table?
code:
function getData(){
let ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("TCD").getRange(5,1).getDataRegion();
let background = ss.getBackgrounds();
let val = ss.getDisplayValues();
let fontColor = ss.getFontColors();
let fontStyles = ss.getFontStyles();
let fontWeight = ss.getFontWeights();
let fontSize = ss.getFontSizes();
return [val,background,fontColor,fontStyles,fontWeight,fontSize];
}
function setupEmail(attachment, sendBool) {
let ss_data = getData();
let data = ss_data[0];
let background = ss_data[1];
let fontColor = ss_data[2];
let fontStyles = ss_data[3];
let fontWeight = ss_data[4];
let fontSize = ss_data[5];
html += "<table border='1' style=\"background-color:#000000;\">";
for (let i = 0; i < data.length; i++) {
html += "<tr>"
for (let j = 0; j < data[i].length; j++) {
html += "<td style=\"height:20px;background-color:" + background[i][j] + "; color: " + fontColor[i][j] + "; font-style: " + fontStyles[i][j] + "; font-weight: " + fontWeight[i][j] + "; font-size: " + (fontSize[i][j] + 6) + "px; text-align: center;\">" + data[i][j] + "</td>";
Logger.log(background[i][j]);
}
html += "</tr>";
}
html + "</table>"
EDIT: I have worked around this by hardcoding the background-color. If anyone knows why the background colors of a pivot table cannot be returned, please do contribute.

Make entire table editable and saving the changes on click

I'm trying to make an editable table such that when the user clicks on the 'edit' button, every table data cell get placed inside an input form that the user can type in and change the information. Once the user is done, they may click the edit button again so that all of the input fields go away and the changes made are saved and displayed on the table.
I have made it so that every single data in every table data cell gets placed inside an input field when the user clicks the single 'edit' button. However, I'm having a really rough time trying to figure out how to remove the input boxes and display all the updated table cells. I was thinking of placing "contenteditable" withing every td and changing it to true/false would work, but I couldn't figure it out.
I'm using local storage for this, but I just need help on this one thing. Any help would be greatly appreciated.
var retrieveContacts = localStorage.getItem("contacts");
var newVariable = JSON.parse(retrieveContacts);
var isEdit = 0; // is the table in edit mode? 0- false 1- true
// set to 0 (false) by default
$.each(newVariable, function(){
$('#tableStyles').append('<tr>' +
'<td id="tableCells" contenteditable="false">' + newVariable[i].email + '</td>' +
'<td id="tableCells" contenteditable="false">' + newVariable[i].firstname + '</td>' +
'<td id="tableCells" contenteditable="false">' + newVariable[i].lastname + '</td>' +
'<td id="tableCells" contenteditable="false">' + newVariable[i].prefix + '</td>' +
'<td id="tableCells" contenteditable="false">' + newVariable[i].title + '</td>' +
'<td id="tableCells" contenteditable="false">' + newVariable[i].company + '</td>' +
'<td id="tableCells" contenteditable="false">' + newVariable[i].phone + '</td>' +
'<td id="tableCells" contenteditable="false">' + newVariable[i].fax + '</td>' +
'</tr>');
i++;
});
$('#createCont').click(function(){
var newRow = "<tr style='height: 35px;'><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>";
$('#tableStyles').append(newRow);
newVariable.push({"email": "",
"firstname": "",
"lastname": "",
"prefix": "",
"title": "",
"company": "",
"phone": "",
"fax": ""});
localStorage.setItem("contacts", JSON.stringify(newVariable));
});
$('#editCont').click(function(){
if(isEdit == 0){
var j = 0;
var trCount = 2; // up to newVariable.length+1
var tdCount = 1; // up to 8
for(trCount; trCount < newVariable.length+2; trCount++){
for(tdCount; tdCount < 9; tdCount++){
var testing1 = $("tr:nth-child(" + trCount + ")").children("td:nth-child(" + tdCount + ")");
var testing2 = testing1.html("<input type='text' value='" + testing1.html() + "'/>");
}
tdCount = 1;
}
trCount = 2;
tdCount = 1;
isEdit = 1;
//console.log("isEdit set to 1");
} else if(isEdit == 1) { // if the edit button is clicked and we are already editing the form,
// then we have take out the input boxes and save all changes.
for(trCount; trCount < newVariable.length+2; trCount++){
for(tdCount; tdCount < 9; tdCount++){
var testing1 = $("tr:nth-child(" + trCount + ")").children("td:nth-child(" + tdCount + ")");
}
tdCount = 1;
}
isEdit = 0;
//console.log("isEdit set to " + isEdit);
}
});
I would like to offer you a better solution. You can place the input field directly into the table cells and use the readonly attribute to set it editable.
Here is the code:
document.getElementById("edit").addEventListener("click", function() {
var fields = document.querySelectorAll("table input[type='text']");
for (var i = 0; i < fields.length; i++) {
fields[i].readOnly = false;
}
document.getElementById("save").style.display = "inline-block";
});
document.getElementById("save").addEventListener("click", function() {
var data = {};
data.name = document.getElementById("name").value;
data.email = document.getElementById("email").value;
// window.localStorage.formData = JSON.stringify(data);
// localStorage will not work in this snippet editor
// uncomment it in your code
var fields = document.querySelectorAll("table input[type='text']");
for (var i = 0; i < fields.length; i++) {
fields[i].readOnly = true;
}
document.getElementById("save").style.display = "none";
});
table input[type="text"] {
/* place any styling here */
}
table input[type="text"]:read-only {
border: none;
}
#save {
display: none;
}
<form>
<table>
<tr>
<td>Name:</td>
<td><input type="text" id="name" value="Some Name" readonly /></td>
</tr>
<tr>
<td>Email:</td>
<td><input type="text" id="email" value="Email address" readonly /></td>
</tr>
</table>
<input type="button" id="edit" value="Edit" />
<input type="button" id="save" value="Save" />
</form>
Please, tell me if it works for you!

Javascript page-break

I need help
I have a problem with making reports invoices with pre-printed paper. when an item of the invoice exceeds the capacity, automatically the rest of the items will be printed onto a second page.
I use a javascript programming language. No one can give a solution?
for (var x = 1; x <= lineCount; x++){
var strItem = '';
var strUnit ='';
var strJumlah ='';
var strHargaSatuan ='';
var strHargaTotal ='';
if(recIV.getLineItemValue('item','item', x)){
strItem = recIV.getLineItemText('item','item', x);
}
if(recIV.getLineItemValue('item','units', x)){
strUnit = recIV.getLineItemText('item','units', x);
}
if(recIV.getLineItemValue('item','quantity', x)){
strJumlah = recIV.getLineItemValue('item','quantity', x);
}
if(recIV.getLineItemValue('item','rate', x)){
strHargaSatuan = recIV.getLineItemValue('item','rate', x);
}
if(recIV.getLineItemValue('item','amount', x)){
strHargaTotal = recIV.getLineItemValue('item','amount', x);
}
strName += ' <tr style=\"font-size:13px\" line-height=\"11px\">';
strName += ' <td width=\"10%\" align=\"center\">'+ x +'</td>';
strName += ' <td width=\"35%\">'+strItem+'</td>';
strName += ' <td width=\"15%\">'+strUnit+'</td>';
strName += ' <td width=\"10%\">'+strJumlah+'</td>';
strName += ' <td width=\"20%\">Rp '+addCommas(strHargaSatuan)+'</td>';
strName += ' <td width=\"20%\">Rp '+addCommas(strHargaTotal)+'</td>';
strName += ' </tr>';
}
I have written a web app that does this for a friend's business. What I do is create the element, append it to the actual DOM, then measure the height in pixels using parseInt(getComputedStyle(item_list[i]).height)
As soon as the height exceeds the available space I remove the last item and start appending to the 2nd page.

How to arrange array values on a table for email?

Sorry for the vague title. I'm really new to programming and I have this code here:
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Confirm Order')
.addItem('Send Email', 'email')
.addToUi();
}
function email() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var currentRow = sheet.getActiveRange().getRow();
var product = sheet.getRange(2,5,1,11).getValues(); //header names
var order1 = sheet.getRange(currentRow, 5, 1,11).getValues();
var order2 = sheet.getRange(currentRow, 17, 1,11).getValues();
var order3 = sheet.getRange(currentRow, 29, 1,11).getValues();
var email = sheet.getRange(currentRow,2).getValues();
var tab = ""
var z ="";
for(var i in product){
if(product[i]!="") z += "<tr><td style='padding:5px'>" + product[i] + "</td><td style='padding:5px'>" + order1[i] + "</td><td style='padding:5px'>" + order2[i] + "</td><td style='padding:5px'>" + order3[i] + "</td></tr>";
}
tab = "<table><tr><th>Product Name</th><th>Order 1</th> <th>Order 2</th> <th>Order 3</th></tr>" + z + "</table>";
// MailApp.sendEmail(Session.getActiveUser().getEmail(),"Your report", report, {htmlBody: report});
MailApp.sendEmail(email,"Order Confirmation", tab, {htmlBody: tab});
}
The following code sends out an email of a selected data in a spreadsheet, however the results in email are not one below another. For example, I want it to look like this:
Product Name order 1 order 2 order 3
prod A 2 2 1
prod B 3 1 4
Prod C 12 7 9
But it ends up looking like this:
Product Name order 1 order 2 order 3
prod A,prod B,prod C 2,3,12 2,1,7 1,4,9
Please tell me what I'm doing wrong. I really wanted to learn.
getValues returns a 2d array. This is why product[0] displays as "prod A,prod B,prod C". That's the arrays toString function at work. So you need to print product[0][0], product[0][1], product[0][2].
for(var i in product) {
for (var j in product[i]) {
z += "<tr><td style='padding:5px'>" + product[i][j] + "</td><td style='padding:5px'>" + order1[i][j] + "</td><td style='padding:5px'>" + order2[i][j] + "</td><td style='padding:5px'>" + order3[i][j] + "</td></tr>";
}
}
This assumes product, order1, order2, and order3 all have the same size.

JavaScript works in Chrome but not ie9 [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am facing an issue with JavaScript.I see that it works fine in chrome but not in IE9.This would not display what chrome is displaying on the web page as expected.
I am new to JavaScripting can I get help in fixing this issue.
<script type="text/javascript">
var tds = document.getElementById('course_table')
.getElementsByTagName('td');
var sum = 0;
for (var i = 0; i < tds.length; i++) {
if (tds[i].className == 'count-me') {
sum += isNaN(tds[i].innerHTML) ? 0
: parseInt(tds[i].innerHTML);
}
}
var lastrecord = tds[tds.length - 2].innerHTML;
var table = document.getElementById('course_table')
.getElementsByTagName('tr');
var max = table.length - 2;
document.getElementById('course_table').innerHTML += '<tr bgcolor=#FFCCFF><td></td><td>Total Courses</td><td>' + max + '</td><td>Total Credits Remaining</td><td>'+ sum + '</td><td> Expected Graduation Date</td><td></td><td>' + lastrecord + '</td><td></td></tr> ';
</script>
Thanks
Niveditha
The problem is most likely in the last line:
document.getElementById('course_table').innerHTML += '<tr bgcolor=#FFCCFF><td></td><td>fsffd</td><td>' + max + '</td><td>abcdRemaining</td><td>'+ sum + '</td><td> abc</td><td></td><td>' + lastrecord + '</td><td></td></tr> ';
IE doesn't handle trs being added by strings; besides it is non-standard. Replace that line with this, it programmatically builds up the row and is faster. I added the corresponding <td> as comments.
var table = document.getElementById('course_table');
var row = table.insertRow(-1);
row.style.backgroundColor = '#FFCCFF'; // `bgcolor` attribute is deprecated
row.insertCell(-1); // <td></td>
row.insertCell(-1).textContent = "fsffd"; // <td>fsffd</td>
row.insertCell(-1).textContent = max; // <td>' + max + '</td>
row.insertCell(-1).textContent = "abcdRemaining"; // <td>abcdRemaining</td>
row.insertCell(-1).textContent = sum; // <td>' + sum + '</td>
row.insertCell(-1).textContent = "abc"; // <td> abc</td>
row.insertCell(-1); // <td></td>
row.insertCell(-1).textContent = lastRecord; // <td>' + lastRecord + '</td>
row.insertCell(-1); // <td></td>
The important methods here are insertRow and insertCell, they are guaranteed to work. textContent is faster and safer than innerHTML. Please use CSS instead of the deprecated bgcolor attribute
Internet Explorer doesn't like adding <tr> elements to the <table> in that manner. What you can do is append a new <tbody> element to the table:
// ... the first part of your function ...
var lastrecord = tds[tds.length - 2].innerHTML;
var table = document.getElementById('course_table');
var newbody = document.createElement('tbody');
newbody.innerHTML = '<tr bgcolor=#FFCCFF><td></td><td>Total Courses</td><td>' + max + '</td><td>Total Credits Remaining</td><td>'+ sum + '</td><td> Expected Graduation Date</td><td></td><td>' + lastrecord + '</td><td></td></tr> ';
table.appendChild(newbody);

Categories

Resources