javascript loop does not write to number input - javascript

I have made a loop to several fields in a dynamic table row to write and retrieve data from localstorage.
It first saves data on localstore, resets the table to 0 rows and for retrieval of data, the table rows will be recreated it and load data there. The problem is that when the textbox is of type "number", the field appears blank. It loads data on the respective fields as I tried it on the number field's placeholder values just to see data coming.
This only happens on the looped fields in the dynamic rows of the table. Number inputs from the fixed rows can load properly.
The ID's I used on the loop where correct and prints
document.getElementById('4-4-1').value = 2"
Where
4-4-1 = x-y-z
x = tableNumber
y = FieldNumber
z = RowNumber
But when I pasted document.getElementById('4-4-1').value again on the console, it returns nothing. (Though a placeholder of '2' appears on the field).
I also tried changing the value with the same line in the console and it works properly.
Why is it that it is not working on number fields during the loop?
Tried it on Chrome, Firefox. Aiming for Android 4.2 web view.
The Store Loop
function saveRecordNow() {
var rec = {};
rec[0] = document.getElementById('data0').value
rec[1] = document.getElementById('data1').value
rec[2] = document.getElementById('otherdata').value
rec[3] = document.getElementById('foo').value
...
...
var tblSpaceQtr = document.getElementById('tblSpaceQtr');
rowCnt = tblSpaceQtr.getElementsByTagName("tr").length - 11;
//there are 11 fixed rows on the table, and is not included on the count
//var page4Data = '';
for(x=1; x <= rowCnt; x++) {
page4Data += document.getElementById("4-1-"+x).value + ', '+
document.getElementById("4-2-"+x).value + ', '+
document.getElementById("4-3-"+x).value + ', '+
document.getElementById("4-4-"+x).value + ', '+
document.getElementById("4-5-"+x).value + ', '+
document.getElementById("4-6-"+x).value + ', '+
document.getElementById("4-7-"+x).value + ', '+
document.getElementById("4-8-"+x).value + ', '+
document.getElementById("4-9-"+x).value + ', '+
document.getElementById("4-10-"+x).value + ', '+
document.getElementById("4-11-"+x).value + ', '+
document.getElementById("4-12-"+x).value + ', '+
document.getElementById("4-13-"+x).value + ', '+
document.getElementById("4-14-"+x).value + ', '+
document.getElementById("4-15-"+x).value + ', '+
document.getElementById("4-16-"+x).value + ', '+
document.getElementById("4-17-"+x).value + ', '+
document.getElementById("4-18-"+x).value + ', '+
document.getElementById("4-19-"+x).value + ', '+
document.getElementById("4-20-"+x).value + ', '+
document.getElementById("4-21-"+x).value + ', '+
document.getElementById("4-22-"+x).value + ', '+
document.getElementById("4-23-"+x).value + '||| ';
//console.log("data from 4-1-"+x);
}
page4Data.substring(0, page4Data.length - 2); //remove end comma
//alert()
rec[681] = page4Data;
...
}
The retrieval loop
function loadRecord(n) {
var getVar = JSON.parse(localStorage.getItem(n));
document.getElementById('id').value = n;
numCells = document.getElementById('nbcells');
document.getElementById('data0').value = getVar[0];
document.getElementById('data1').value = getVar[1];
document.getElementById('otherdata').value = getVar[2];
document.getElementById('foo').value = getVar[3];
document.getElementById('foo2').value = getVar[4];
document.getElementById('foo3').value = getVar[5];
...
initTable(numCells, numCells.value)
var pg4Data = [],
pg4RowData = [],
pg4Data = getVar[681].split('|||');
page4Data = getVar[681]
//getVar[681] from JSON.parse(localStore['source']);
//having a csv separated by '|||' per row
for(x=1; x < pg4Data.length; x++) {
pg4RowData = pg4Data[x-1].split(',');
document.getElementById("4-1-"+x).value = pg4RowData[0];
document.getElementById("4-2-"+x).value = pg4RowData[1];
document.getElementById("4-3-"+x).value = pg4RowData[2];
document.getElementById("4-4-"+x).value = pg4RowData[3];
console.log("document.getElementById('4-4-"+x+"').value =" +pg4RowData[3]);
document.getElementById("4-4-"+x).placeholder = pg4RowData[3];
//document.getElementById("4-4-"+x).setAttribute('value', pg4RowData[3]);
//document.getElementById("4-5-"+x).value = pg4RowData[4];
document.getElementById("4-5-"+x).value = pg4RowData[4];
document.getElementById("4-5-"+x).placeholder = pg4RowData[4];
document.getElementById("4-6-"+x).value = pg4RowData[5];
document.getElementById("4-6-"+x).placeholder = pg4RowData[5];
document.getElementById("4-7-"+x).value = pg4RowData[6];
document.getElementById("4-7-"+x).placeholder = pg4RowData[6];
document.getElementById("4-8-"+x).value = pg4RowData[7];
document.getElementById("4-8-"+x).placeholder = pg4RowData[7];
document.getElementById("4-9-"+x).value = pg4RowData[8];
document.getElementById("4-9-"+x).placeholder = pg4RowData[8];
document.getElementById("4-10-"+x).value = pg4RowData[9];
document.getElementById("4-11-"+x).value = pg4RowData[10];
document.getElementById("4-12-"+x).value = pg4RowData[11];
document.getElementById("4-13-"+x).value = pg4RowData[12];
document.getElementById("4-14-"+x).value = pg4RowData[13];
document.getElementById("4-15-"+x).value = pg4RowData[14];
document.getElementById("4-16-"+x).value = pg4RowData[15];
document.getElementById("4-17-"+x).value = pg4RowData[16];
document.getElementById("4-18-"+x).value = pg4RowData[17];
document.getElementById("4-19-"+x).value = pg4RowData[18];
document.getElementById("4-20-"+x).value = pg4RowData[19];
document.getElementById("4-21-"+x).value = pg4RowData[20];
document.getElementById("4-22-"+x).value = pg4RowData[21];
document.getElementById("4-23-"+x).value = pg4RowData[22];
}
...
}

The element's IDs, class names, and variables in JavaScript cannot start with a number! Please prefix the values with a character and then try it again.
for(x=1; x < pg4Data.length; x++) {
pg4RowData = pg4Data[x-1].split(',');
document.getElementById("s-4-1-"+x).value = pg4RowData[0];
document.getElementById("s-4-2-"+x).value = pg4RowData[1];
document.getElementById("s-4-3-"+x).value = pg4RowData[2];
document.getElementById("s-4-4-"+x).value = pg4RowData[3];

Related

Google Scripts to draft replies to emails with keyword in subject and inputting data from Google Sheets

I'm new to Google Apps Script so I'm looking for some advice. There's multiple parts and I managed to do some of it but I'm stuck on others. Any help would be much appreciated.
I'm trying to make a script that:
drafts a reply to emails that contain specific keywords (found in the body or the subject line).
I also want it to include a template with data inputted from a Google Sheets file.
It would be preferable if the draft can be updated without making a duplicate whenever the Sheet is modified.
I plan on also including a row of values (the first one) that correspond to the Subject columns in the second row the but I haven't gotten to it yet.
Some details about the Google Sheet:
Each row corresponds to a different person and email address that regularly emails me.
The first three columns are details about the person which I include in the body of my draft.
Each column after that represents a different string or keyword I expect to find in the subject of the emails sent to me.
The rows underneath contain two patterned code-words separated by a space in one cell that I want to be able to choose from. Such as:
3 letters that can contain permutations of the letters m, g, r (for ex: mmg, rgm, rgg, gmg)
and 0-3 letters with just p's (for ex: p, pp, ppp, or blank)
I want to be able to detect the different codes and assign it to a variable I can input into my draft.
What I have so far:
I'm able to draft replies for emails within my specified filter. However, I only have it set up to reply to the person's most recent message. I want to be able for sort through the filter for specific emails that contain a keyword in the subject line when it loops through the columns.
I'm able to input static strings from the Sheet into the body of my email but I'm still having trouble with the patterned codewords.
I was able to loop through more than one row in earlier version but now it's not. I'll look over it again later.
Here's my code:
function draftEmail() {
var sheet = SpreadsheetApp.getActiveSheet(); // Use data from the active sheet
var startRow = 1; // First row of data to process
var numRows = sheet.getLastRow() - 1; // Number of rows to process
var lastColumn = sheet.getLastColumn(); // Last column
var dataRange = sheet.getRange(startRow, 1, numRows, lastColumn) // Fetch the data range of the active sheet
var data = dataRange.getValues(); // Fetch values for each row in the range
// Work through each row in the spreadsheet
for (var i = 2; i < data.length; ++i) {
var row = data[i];
// Assign each row a variable
var grader = row[0]; // Col A: Grader's name
var firstName = row[1]; // Col B: Student's first name
var studentEmail = row[2]; // Col C: Student's email
var grade = row[3].split(' '); // Col D: Grade
var pgrade = grade[1];
var hgrade = grade[0];
for (var n = 1; n < data.length; ++n) {
var srow = data[n];
var subjectCol = srow[3];
var threads = GmailApp.getUserLabelByName('testLabel').getThreads();
for (i=0; i < threads.length; i++)
{
var thread = threads[i];
var messages = thread.getMessages(); // get all messages in thread i
var lastmsg = messages.length - 1; // get last message in thread i
var emailTo = WebSafe(messages[lastmsg].getTo()); // get only email id from To field of last message
var emailFrom = WebSafe(messages[lastmsg].getFrom()); // get only email id from FROM field of last message
var emailCC = WebSafe(messages[lastmsg].getCc()); // get only email id from CC field of last message
// form a new CC header for draft email
if (emailTo == "")
{
var emailCcHdr = emailCC.toString();
} else
{
if (emailCC == "")
{
var emailCcHdr = emailTo.toString();
} else
{
var emailCcHdr = emailTo.toString() + "," + emailCC.toString();
}
}
var subject = messages[lastmsg].getSubject().replace(/([\[\(] *)?(RE|FWD?) *([-:;)\]][ :;\])-]*|$)|\]+ *$/igm,"");
// the above line remove REs and FWDs etc from subject line
var emailmsg = messages[lastmsg].getBody(); // get html content of last message
var emaildate = messages[lastmsg].getDate(); // get DATE field of last message
var attachments = messages[lastmsg].getAttachments(); // get all attachments of last message
var edate = Utilities.formatDate(emaildate, "IST", "EEE, MMM d, yyyy"); // get date component from emaildate
var etime = Utilities.formatDate(emaildate, "IST", "h:mm a"); // get time component from emaildate
if (emailFrom.length == 0)
{
// if emailFrom is empty, it probably means that you may have written the last message in the thread. Hence 'you'.
var emailheader = '<html><body>' +
'On' + ' ' +
edate + ' ' +
'at' + ' ' +
etime + ',' + ' ' + 'you' + ' ' + 'wrote:' + '</body></html>';
} else
{
var emailheader = '<html><body>' +
'On' + ' ' +
edate + ' ' +
'at' + ' ' +
etime + ',' + ' ' + emailFrom + ' ' + 'wrote:' + '</body></html>';
}
var emailsig = '<html>' +
'<div>your email signature,</div>' +
'</html>'; // your email signature i.e. common for all emails.
// Build the email message
var emailBody = '<p>Hi ' + firstName + ',<p>';
emailBody += '<p>For ' + subjectCol + ', you will be graded on #1, 2, and 3: <p>';
emailBody += '<p>Participation: ' + pgrade + '</p>';
emailBody += '<p>HW grade: ' + hgrade + '</p>';
emailBody += '<p>If you have any questions, you can email me at ' + grader + '#email.com.<p>';
emailBody += '<p>- ' + grader;
var draftmsg = emailBody + '<br>' + emailsig + '<br>' + emailheader + '<br>' + emailmsg + '\n'; // message content of draft
// Create the email draft
messages[lastmsg].createDraftReply(
" ", // Body (plain text)
{
htmlBody: emailBody // Options: Body (HTML)
}
);
}
}
}
function WebSafe(fullstring)
{
var splitString = fullstring.split(",");
var finalarray = [];
for (u=0; u < splitString.length; u++)
{
var start_pos = splitString[u].indexOf("<") + 1;
var end_pos = splitString[u].indexOf(">",start_pos);
if (!(splitString[u].indexOf("<") === -1 && splitString[u].indexOf(">",start_pos) === -1)) // if < and > do exist in string
{
finalarray.push(splitString[u].substring(start_pos, end_pos));
} else if (!(splitString[u].indexOf("#") === -1))
{
finalarray.push(splitString[u]);
}
}
var index = finalarray.indexOf(grader + "#email.com"); // use your email id. if the array contains your email id, it is removed.
if (index > -1) {finalarray.splice(index, 1);}
return finalarray
}
}
I've never coded in JavaScript before or used Google Scripts so I mostly looked at similar examples.
Thank you for any feedback.
I prefer reading code that isn't too nested. So I took the liberty to re-write your code and make it easier to read.
Your main function:
function mainFunction(){
// Use data from the active sheet
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
var threads = GmailApp.getUserLabelByName('<YOUR-LABEL-HERE>').getThreads();
var subject1 = data[1][3];
// Work through each row in the spreadsheet omit headers
for (var i = 2; i < data.length; ++i) {
// Get grader's data
var grader = getGrader(data[i]);
console.log(grader);
// Loop through threads
for (j=0; j < threads.length; j++){
var thread = threads[j];
// Get last message in thread
var messages = thread.getMessages();
var lastMsg = messages[messages.length - 1];
var email = new Email(grader, lastMsg, subject1);
// Create the draft reply.
var draftMessageBody = createDraftMessage(email);
lastMsg.createDraftReply(draftMessageBody);
}
}
}
Support functions:
Function getGrader:
function getGrader(array){
var row = array
var grader = {}
grader.grader = row[0];
grader.firstName = row[1];
grader.studentEmail = row[2];
var grade = row[3].split(' ');
grader.pgrade = grade[1];
grader.hgrade = grade[0];
return grader
}
Function webSafe:
function webSafe(fullstring, grader){
var splitString = fullstring.split(",");
var finalarray = [];
for (u=0; u < splitString.length; u++){
var start_pos = splitString[u].indexOf("<") + 1;
var end_pos = splitString[u].indexOf(">",start_pos);
// if < and > do exist in string
if (!(splitString[u].indexOf("<") === -1 && splitString[u].indexOf(">",start_pos) === -1)){
finalarray.push(splitString[u].substring(start_pos, end_pos));
} else if (!(splitString[u].indexOf("#") === -1)){
finalarray.push(splitString[u]);
}
}
// use your email id. if the array contains your email id, it is removed.
var index = finalarray.indexOf(grader.grader + "#mangoroot.com");
if (index > -1) {
finalarray.splice(index, 1);
}
return finalarray
}
Function Email: Behaves like a class
var Email = function(grader, lastMsg, subject){
this.signature = "your_email_signature,";
this.grader = grader;
this.to = webSafe(lastMsg.getTo(), this.grader);
this.from = webSafe(lastMsg.getFrom(), this.grader);
this.cc = webSafe(lastMsg.getCc(), this.grader);
this.subject = lastMsg.getSubject().replace(/([\[\(] *)?(RE|FWD?) *([-:;)\]][ :;\])-]*|$)|\]+ *$/igm,"");
this.message = lastMsg.getBody();
this.date = lastMsg.getDate();
this.attachments = lastMsg.getAttachments();
this.subject1 = subject;
this.ccHeader = function() {
var ccHeader = "";
if (this.to == "" || this.cc == ""){
ccHeader = this.cc.toString();
}
else {
ccHeader = this.to.toString() + "," + this.cc.toString();
}
return ccHeader
}
this.eDate = function() {
return Utilities.formatDate(this.date, "IST", "EEE, MMM d, yyyy");
}
this.eTime = function() {
return Utilities.formatDate(this.date, "IST", "h:mm a");
}
this.header = function() {
var header = ''.concat('On ');
if (this.from.length == 0){
header += this.eDate().concat(' at ',this.eTime(),', you wrote: ');
}
else {
header += this.eDate().concat(' at ',this.eTime(),', ',this.from,' wrote: ');
}
return header
}
this.body = function(){
var grader = this.grader;
var body = '<div>'.concat('<p>Hi ',grader.firstName,',</p>');
body += '<p>For '.concat(this.subject1,', you will be graded on #1, 2, and 3: </p>');
body += '<p>Participation: '.concat(grader.pgrade,'</p>');
body += '<p>HW grade: '.concat(grader.hgrade,'</p>');
body += '<p>If you have any questions, you can email me at '.concat(grader.grader,'#mangoroot.com.</p>');
body += '<p>- '.concat(grader.grader,'</p>','</div>');
return body;
}
}
Function createDraftMessage:
function createDraftMessage(email){
var draft = '<html><body>'.concat(email.body);
draft += '<br>'.concat(email.signature);
draft += '<br>'.concat(email.header);
draft += '<br>'.concat(email.message);
draft += '<br>'.concat('</body></html>');
return draft;
}
Now when you run mainFunction() you should get your expected drafts.
Notes:
It is good practice to keep functions flat, flat is better than nested. Makes the code more readable and maintainable.
Also be consistent in your variable naming style.
var emailMsg = ''; // Good.
var emailmsg = ''; // Hard to read.
Have a read about classes

Javascript not showing up total value in middle of Oracle APEX Donut chart

I am trying use below code (found from a forum) as JavaScript initialization code in Oracle APEX Donut chart to display total value in middle. But the result showing up only the Text "Total" in middle of the chart and does not show any numerical value. Can anyone help me out in spotting the error from the below code ? I am new to Javascript and have very less knowledge about the same.
function( options ){
var total;
this.pieSliceLabel = function(dataContext){
var series_name;
percent = Math.round(dataContext.value/dataContext.totalValue*100);
total = Math.round(dataContext.totalValue);
if ( dataContext.seriesData ) {
series_name = dataContext.seriesData.name;
} else {
series_name = 'Other';
}
document.getElementById("myDiv").innerHTML = Math.round(dataContext.totalValue);
return series_name + " " + percent + "% ( " + dataContext.value + " )";
}
// Set chart initialization options
options.dataLabel = pieSliceLabel;
this.centerCallback = function(dataContext){
var pieElem = document.createElement('div');
pieElem.innerHTML =
'<div id="myDiv" style="position:absolute;text-align:center;font-size:16px;">' +
'Total' +' '+ total +
'</div>';
var outerDiv = pieElem.children[0];
var innerBounds = dataContext.innerBounds;
// Outer bounds
outerDiv.style.top = innerBounds.y + "px";
outerDiv.style.left = innerBounds.x + "px";
outerDiv.style.height = innerBounds.height + "px";
outerDiv.style.width = innerBounds.width + "px";
outerDiv.style.lineHeight = innerBounds.height + "px";
return pieElem;
}
options.pieCenter = {
renderer : centerCallback
}
return options;
}
if I correct understood, try to fix it, add to centerCallback,
var value = dataContext.totalValue;
pieElem.innerHTML =
'<div id="myDiv" style="position:absolute;text-align:center;font-size:16px;">' +
'Total ' + value +
'</div>';
Could you try this
function( options ){
// will hold the total value, must be global variable
var total;
Add below statement in this.pieSliceLabel = function(dataContext){}
percent = Math.round(dataContext.value/dataContext.totalValue*100);
total = dataContext.totalValue; //assign to global variable
Update the below innerHTML code in this.centerCallback = function(dataContext){}
//updated element
pieElem.innerHTML =
'<div id="myDiv" style="position:absolute;text-align:center;font-size:16px;">' +
'Total' + total +
'</div>';

How to implement pagination in Firebase using JavaScript?

I am working on Firebase pagination using JavaScript. I have implemented a soft delete feature where the record is not deleted in Firebase but deleted in the web display.
So when a soft delete is being done, the visible flag in Firebase becomes false. I want to display on my web form, the contacts whose visible flag is true using JavaScript ( with the NEXT and PREV buttons ).
Since I am new to this, I would love to get suggestions and help!!
A Snapshot of Firebase is as follows:
My code of getting first three records initially is as follows :
function getData() {
var total="";
var firstRef = firebase.database().ref("Persons/").orderByChild("visible").endAt("true").limitToFirst(3);
firstRef.on("value", function (data) {
console.log(data.val());
a = data.val();
var keys = Object.keys(a);
key1 = keys[0];
key2 = keys[1];
console.log("Key 1" + keys[0]);
for (var i = 0; i < keys.length; i++)
{
var k = keys[i];
var fname = a[k].fname;
var lname = a[k].lname;
var mno = a[k].mno;
var email = a[k].email;
var image = a[k].image;
var visible = a[k].visible;
if (visible == true) {
total += "<div><br/></div<div><b>KEY ID: </b><h1>" + k + "</h1></div><div><br/></div><div><img src=" + image + " alt=NoProfilePic class=imgsrc></div><div><b>FIRST NAME : </b>" + fname + "</div><div><b>LAST NAME : </b>" + lname + "</div><div><b>MOBILE NO : </b>" + mno + "</div><div><b>EMAIL : </b>" + email + "</div><div><br/><b><hr><hr></b></div>";
document.getElementById('total').innerHTML = total;
}
}
},
function (error) {
console.log("Error: " + error.code);
});
}
To get the Next three records (which will be called when the NEXT button is pressed ), I have written a code as follows :
function next() {
var total="";
var lastRef = firebase.database().ref("Persons").orderByKey().startAt(key2 + "a").limitToFirst(3);
lastRef.on("value", function (data) {
c = data.val();
var keys = Object.keys(c);
for (var i = 0; i < keys.length; i++) {
var k = keys[i];
var visible = c[k].visible;
if(visible==true)
{
var fname = c[k].fname;
var lname = c[k].lname;
var mno = c[k].mno;
var email = c[k].email;
var image = c[k].image;
total += "<div><br/></div<div><b>KEY ID: </b><h1>" + k + "</h1></div><div><br/></div><div><img src=" + image + " alt=NoProfilePic class=imgsrc></div><div><b>FIRST NAME : </b>" + fname + "</div><div><b>LAST NAME : </b>" + lname + "</div><div><b>MOBILE NO : </b>" + mno + "</div><div><b>EMAIL : </b>" + email + "</div><div><br/><b><hr><hr></b></div>";
document.getElementById('total').innerHTML = total;
}
}
key3=key1;
key4=key2;
key2=keys[2];
key1=keys[0];
},
function (error) {
console.log("Error: " + error.code);
});
}
I am new to Firebase, so please do correct me if I am wrong and also, if anybody could help me with PREV, it would be great!!
Thanks!!

How to get next row of HTML table based on some condition using jQuery?

Ok, I am new to JQuery and I have requirement to do some manipulation on table based on rows.
The table consists of rows which belong to 3 different style classes Brand have category and category have products.
var table = $("table tbody");
table.find(".brand").each(function(i) {
var $tdsBrand = $(this).find("td"),
brand = $tdsBrand.eq(0).text(),
atyBrand = $tdsBrand.eq(1).text(),
alyBrand = $tdsBrand.eq(2).text();
console.log('Brand Row ' + (i + 1) + ':\nBrand Name: ' + brand + '\nActual TY: ' + atyBrand + '\nActual LY: ' + alyBrand);
var brandClass = $(this).attr("class");
console.log('brand class : ' + brandClass);
if (this row has next row as category) {
//if(brand.next($( "tr[class='category']" ))) {
//if ("(.band):has(.category)") {
//if ($(this).parents(".category").length == 1) {
table.find(".category").each(function(i) {
var catClass = $(this).attr("class");
console.log('category class : ' + catClass);
var $tdsCategory = $(this).find("td"),
category = $tdsCategory.eq(0).text(),
atyCategory = $tdsCategory.eq(1).text(),
alyCategory = $tdsCategory.eq(2).text();
console.log('Category Row ' + (i + 1) + ':\nCategory Name: ' + category + '\nActual TY: ' + atyCategory + '\nActual LY: ' + alyCategory);
if (This row has next row as product) {
//if(next($( "tr[class='product']" ))) {
//if ("(.category):has(.product)") {
//if ($(this).parents("product").length == 1) {
table.find(".product").each(function(i) {
var proClass = $(this).attr("class");
console.log('product class : ' + proClass);
var $tds = $(this).find("td"),
product = $tds.eq(0).text(),
aty = $tds.eq(1).text(),
aly = $tds.eq(2).text();
console.log('Product Row ' + (i + 1) + ':\nProduct Name: ' + product + '\nActual TY: ' + aty + '\nActual LY: ' + aly);
});
}
});
}
});
What I want to do is, I have to sum up Actual TY values of products and display them on their category. Then sum up Actual TY of categories (which has been calculated from products for different categories) to their brand.
Please refer http://jsfiddle.net/cfhhz0zr/46/ for clear understanding of my requirement and code which I've tried till now.
Thank you.
Just modified a bit your code and it seems that is doing what you are looking for. See also the http://jsfiddle.net/88prg1dt/
I refactored a bit and renamed some variables to make a bit more sense so should be fairly clear now. If you want to calculate the total for a product / category now should be really super simple.
Here is the JS code:
var $table = $("table tbody");
$table.find(".brand").each(function (brandIndex) {
var $brandRow = $(this);
var $tdsBrand = $(this).find("td");
var brandName = $tdsBrand.eq(0).text();
var atyBrand = $tdsBrand.eq(1).text();
var alyBrand = $tdsBrand.eq(2).text();
console.log('Brand Row ' + (brandIndex + 1) + ':\nBrand Name: ' + brandName + '\nActual TY: ' + atyBrand + '\nActual LY: ' + alyBrand);
var $categoryRows = $brandRow.nextUntil('.brand').filter('.category');
$categoryRows.each(function (categoryIndex) {
var $categoryRow = $(this);
var $tdsCategory = $categoryRow.find("td");
var categoryName = $tdsCategory.eq(0).text();
var atyCategory = $tdsCategory.eq(1).text();
var alyCategory = $tdsCategory.eq(2).text();
console.log('Category Row: ' + (categoryIndex + 1) + ':\nCategory Name: ' + categoryName + '\nActual TY: ' + atyCategory + '\nActual LY: ' + alyCategory);
var $productRows = $categoryRow.nextUntil('.brand, .category').filter('.product');
$productRows.each(function (productIndex) {
var $productRow = $(this);
var $tdProducts = $productRow.find("td");
var productName = $tdProducts.eq(0).text();
var atyProduct = $tdProducts.eq(1).text();
var aly = $tdProducts.eq(2).text();
console.log('Product Row ' + (productIndex + 1) + ':\nProduct Name: ' + productName + '\nActual TY: ' + atyProduct + '\nActual LY: ' + aly);
});
});
});
I played a bit with jQuery nextUntil() method as the documentation:
Description: Get all following siblings of each element up to but not
including the element matched by the selector, DOM node, or jQuery
object passed.
Is this answering your question ?

For Loop - passing dynamic variables to a click function

I have a basic for loop to create a gallery of thumbnail images:
//code to query spreadsheet...data returned as 'rows'
for (var i = 0; i<rows.length; i++){
im = rows[i][0];
n = rows[i][1];
d = rows[i][2];
c = rows[i][3];
$('#frame').append('<div class = box><img height = 290 src = ' + im + '>');
}
For each image there is additional information (in other columns of the spread sheet) - this is also returned as 'rows' as per the above.
Next, there is a click function to display a larger image:
$('#frame').on('click', 'img', function() {
var s = this.src.replace(/.jpg/, '');
$('#show').append('<img src = ' + s + 'L.jpg><div id = details><strong>' + n + '</strong><br>' + d + '<br><span class = status>' + c +'</span></div>');
});
The aim of the last bit is to display the additional information from the same row as the clicked image - and obviously it won't work as written. How do I pass the value of [i] for the clicked image to the click function to get the additional data from the same row[i] as the clicked image?
Thanks.
This code may work try this
for(var i = 0; i<rows.length; i++){
im = rows[i][0];
$('#frame').append('<div class = "box"> <img height =290 src = "'+ im +
'" onclick="clickImg('+i+')" >');
}
function clickImg(i){
im = rows[i][0];
n = rows[i][1];
d = rows[i][2];
c = rows[i][3];
var s = im.replace(/.jpg/, '');
$('#show').append('<img src = "' + s + 'L.jpg" /> <div id = details><strong>' + n
+ '</strong> <br>'+ d +'<br> <span class = "status"> ' + c +' </span> </div>');
}
Try this:
var im;
for (var i = 0; i<rows.length; i++){
im = rows[i][0];
$('#frame').append('<div class = box><img id = ' + i + ' height = 290 src = ' + im + '>');
}
$('#frame').on('click', 'img', function() {
var i = this.id;
n = rows[i][1];
d = rows[i][2];
c = rows[i][3];
var s = im.replace(/.jpg/, '');
$('#show').append('<img src = "' + s + 'L.jpg" /> <div id = details><strong>' + n + '</strong> <br>'+ d +'<br> <span class = "status"> ' + c +' </span> </div>');

Categories