Count number of rows for each printed table - javascript

I need your assistant in getting the total number of rows for each printed table in my html to be shown at the top of it.
I am having multiple tables in the html which their id is unique "detailsTable". Each table has different number of rows. I search for a script to print the total number of rows and I found the below script:
function count()
{
var rows = document.getElementById("detailsTable").getElementsByTagName("tr").length;
alert(rows);
}
and in the body tag, I placed:
<body onload="count()">
When I ran the page, it shows an alert for the first table which it has 22 records and the script ignores the below tables.
So, can you please help me to modify the above code and to display the alert for the other tables.

The id should be unique for every html element.
You can use class instead, and then:
function count()
{
var tables = document.getElementsByClassName("detailsTable");
var rows;
for (var i = 0; i < tables.length; i++) {
rows = tables[i].rows.length;
alert(rows);
}
}

If you want to count table rows with id = "detailsTable"
var rowCount = $('#detailsTable tr').length;
If you want to find it for every table, it would look something like:
$('.details').each(function(index) {
var rowCount = this.rows.length;
})

Related

Append a New Table Row (1 Row 2 Columns) on Google Apps Script

I'm trying to make an automation script that updates an existing Google Docs based on user responses from Google Form. so there are 3 questions (Name, University Number Identification or NIM in Bahasa, and Department or bidang), the department question used for categorizing each respondent.
So the goal is whenever a form is submitted, then the Docs is updated too. So I want to make the update make a new row with a cell that contains a template string that I already used in my script on the spreadsheets. But the problem is it only appends a single column for each row, however, that's not what I intended to have happened. I want it to update 1 row and 2 columns.
Screenshot Of the Google Form
Screenshot of the Google Docs Error
Screenshot of what I intended the Google Docs when it's updated to be
function appendTable(variabel){
var rangePSDI = body.findText(variabel);
var searchElement = body.findElement(DocumentApp.ElementType.TABLE, rangePSDI);
element = searchElement.getElement();
table = element.asTable();
table.appendTableRow().appendTableCell(variabel);
}
if (bidang == 'PSDI') {
body.replaceText('{{NamaPSDI}}', nama);
body.replaceText('{{NIMPSDI}}', nim);
appendTable("{{NamaPSDI}}");
appendTable("{{NIMPSDI}}");
return;
} else if (bidang == 'PSDM') {
body.replaceText('{{NamaPSDM}}', nama);
body.replaceText('{{NIMPSDM}}', nim);
appendTable("{{NamaPSDM}}");
appendTable("{{NIMPSDM}}");
return;
}
Think of the appendTableRow as <tr> in HTML where you have to set the cell using <td>or appendTableCell.
See Table Row element in HTML.
Try this:
Code:
function appendTable(){
var doc = DocumentApp.openById('someid');
var body = doc.getBody();
var tables = body.getTables();
var text = "PSDM";
tables.forEach(table => {
if(table.getCell(0,0).getText() == text){
table.replaceText("{{Nama"+text+"}}", "test nama"+text)
table.replaceText("{{NIM"+text+"}}", "test NIM"+text)
var tr = table.appendTableRow();
tr.appendTableCell("{{Nama"+text+"}}");
tr.appendTableCell("{{NIM"+text+"}}");
}
})
}
Before:
After:
PSDI
PSDM

How to create an array from the columns of a table in Javascript?

I have an HTML table like this:
SALES RENTS
ROME MILAN ROME MILAN MONEY
The HTML code is the following:
<TR>
<TD CLASS=HD1 COLSPAN=2>SALES</TD>
<TD CLASS=HD1 COLSPAN=2>RENTS</TD>
<TD CLASS=HDCOLSEP> </TD>
</TR>
<TR>
<TD>ROME</TD>
<TD>MILAN</TD>
<TD>ROME</TD>
<TD>MILAN</TD>
<TD>MONEY</TD>
</TR>
What I need, is to create with javascript an array like this:
(ROME-SALES, MILAN-SALES, ROME-RENTS, MILAN-RENTS, MONEY).
I have already created the array that contains the element of the first row.
Below you can find my code as it was in the past (At the beginning I needed just to take the elements of the first TR). Now I need to modify it and to create an array as specified before.
I don't know if it is clear from the table, but the first ROME and MILAN columns are referred to the column SALES, the second ROME and MILAN are referred to the RENTS column, while MONEY doesn't have any dependence.
Do you have any idea to do this?
Thanks in advance.
function getColumnsVal(id) {
var header = $("table#" + id + " thead tr:eq(1)");
var header_fields = $("td", header);
var header_vals = [];
header_fields.each(function(idx, val) {
var $$ = $(val);
header_vals.push($$.text());
});
return header_vals;
}
It is definitely possible to read values from the table cells. I edited the post a bit to illustrate the code.
I presume that HTML structure is rigid and you always have two rows of titles in the thead and somewhat random number of merged cells in the first row.
You’d want to match the number of columns in both rows, i.e. take the colspan number into account when traversing the cells.
Read both rows and generate strings by combining cell values in corresponding columns.
For example:
function readTableRow(row) {
var values = [];
$("td", row).each(function(index, field) {
var span = $(field).attr("colspan");
var val = $(field).text();
if (span && span > 1) {
for (var i = 0; i<span; i++ ) {
values.push(val);
}
} else {
values.push(val);
}
});
return values;
}
function getColumnsVal(id) {
// Read the first row, taking colspans into account
var first_row = $("table#" + id + " thead tr:eq(0)");
var first_row_vals = readTableRow(first_row);
// Read the second row, taking colspans into account
var second_row = $("table#" + id + " thead tr:eq(1)");
var second_row_vals = readTableRow(second_row);
if (first_row_vals.length != second_row_vals.length) {
return null;
}
var results = [];
for (var i = 0; i<first_row_vals.length; i++) {
results.push([first_row_vals[i].trim(), second_row_vals[i].trim()].filter(function (el) {return el}).join("-"));
}
return results;
}
function displayResults(results) {
var result = "RESULT: <br />";
results.forEach(function(r) {
result = result + r + "<br />";
});
$("#result").html(result);
}
displayResults(getColumnsVal("sample"));
JSFiddle:
https://jsfiddle.net/adanchenkov/n61dqfrs/

Param in js function not working

I try to get the row id, on expand row.
$table.on('expand-row.bs.table', function(e, index, row, $detail) {
var res = $("#desc" + index).html();
$detail.html(res);
var table = document.getElementById("actionTable");
var row = table.rows[index];
Cookies.set(row.id, 'show');
alert(row.id)
});
When I try alert(index), the index is shown.
When I try var row = table.rows[1];, alert(row.id) shows me the id of the row (I have 3 rows in the table)
But when I try with var row = table.rows[index];, I am not getting the row id.
I tried with parseInt(), but no success.

Issue with getting a keyup function to get sum of input field values using plain Javascript

I'm working on a personal project and I've run into an issue that I haven't been able to solve.
Here is a function that generates new table rows into a table (with id of "tableData") when a button is clicked:
function addNewRow(){
var tableEl = document.getElementById("tableData");
var newLine = '<tr class="newEntry">';
var classArray = ["classA", "classB", "classC", "classD"];
for (var i = 0; i < classArray.length; i++){
newLine += '<td><input class="' + classArray[i] + '"></td>';
}
newLine += '</tr>';
tableEl.insertAdjacentHTML("beforeend", newLine);
}
document.getElementById("addRow").addEventListener("click", addNewRow, false);
//the element with id="addRow" is a button
I've simplified the code for the above function for the sake of readability as it's not the focus of the problem. When the button is clicked, a new row is added successfully.
The problematic part involves another function that takes the sum of the respective classes of each row and displays them in a div.
The goal is to get the sum of the values of all input fields with matching class names. For example, let's say I use the addNewRow function to get six rows. Then I want to have the div showing the sum of the values of all input fields with the class name of "classA"; the number in that div should be the sum of those six values, which gets updated as I type in the values or change the existing values in any of the input fields with class name of "ClassA".
function sumValues(divId, inputClass){
var sumVal = document.getElementsByClassName(inputClass);
var addedUp = 0;
for (var j = 0; j < sumVal.length; j++){
addedUp += Number(sumVal[j].value);
}
document.getElementById(divId).innerHTML = addedUp;
}
Here are a couple (out of several) failed attempts:
document.input.addEventListener("keyup", sumValues("genericDivId", "classA"), false);
document.getElementsByClassName("classA").onkeyup = function(){sumValues("genericDivId", "classA");}
Unfortunately, after scouring the web for a solution and failing to find one, I just added an event listener to a button that, when clicked, would update the div to show the sum of values. Also had to modify the sumValues function to take values from an array rather than accepting arguments.
My question is: How can I modify the code so that the sum value updates as I type in new values or change existing values using pure Javascript (vanilla JS)?
You are very close, document.getElementsByClassName() returns an array of DOM objects, you need to set the onkeyup function for each and every element by looping through that array.
var classA = document.getElementsByClassName('classA'); // this is an array
classA.forEach(function(elem){ // loop through the array
elem.onkeyup = function(){ // elem is a single element
sumValues("genericDivId", "classA");
}
}
Hopefully this fixes your issue
Maybe the example below is not same with your situation, but you'll get the logic, easily. Anyway, do not hesitate to ask for more guide.
document.getElementById("row_adder").addEventListener("click", function() {
var t = document.getElementById("my_table");
var r = t.insertRow(-1); // adds rows to bottom - change it to 0 for top
var c = r.insertCell(0);
c.innerHTML = "<input class='not_important_with_that_way' type='number' value='0' onchange='calculate_sum()'></input>";
});
function calculate_sum() {
var sum = ([].slice.call(document.querySelectorAll("[type=number]"))).map(e=>parseFloat(e.value)).reduce((a, b) => a+b);
document.getElementById("sum").innerHTML = sum;
}
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div>
<p>
<strong>Sum</strong>:<span id="sum">0</span>
</p>
</div>
<button id="row_adder">
Click me
</button>
<table id="my_table">
</table>
</body>
</html>

Creating html table from multidimensional javascript array

I was trying to create an html table from a nested for loop array in Javascript. When I try to append the <tr> tags to the table they get put in an element called tbody. How can I get the tr tags to be appended in the to the table element rather than the tbody element?
<html>
<head>
<script src='jq.js'></script>
</head>
<body>
<table id='tb'></table>
</body>
<script>
$('#tb').ready(
function() {
console.log('table loaded');
var ar = Array(2);
for(var i=0;i<ar.length;i++){
ar[i]=Array(2);
}
ar[0][0]='1';
ar[1][0]='2';
ar[0][1]='3';
ar[1][1]='4';
console.log('multidimensional array created!');
for(var j=0;j<ar.length;j++){
console.log('<tr>');
$('#tb').append('<tr>');
for(var k=0;k<2;k++){
console.log('<td>'+ar[k][j]+'</td>');
$('#tb').append('<td>'+ar[k][j]+'</td>');
}
console.log('</tr>');
$('#tb').append('</tr>');
}
//expected:
//12
//34
//actual
//1 2 3 4
});
</script>
</html>
Here's a jsfiddle
You can't. HTML tables are composed of three sections:
thead contains the header rows
tbody contains the data rows. You can have multiple of these if you want to make different groups of rows (e.g. if rows = months, you could have a separate tbody for each year).
tfoot contains the footer rows
If you put rows directly within the table tag, they're assumed to be part of tbody, and the browser creates this element automatically for you. You either have to put all your rows in tbody elements, or put them all directly within table.
The problem with your code has nothing to do with the tbody element. The problem is that you're trying to append td elements directly to the table, rather than to the tr elements. You're treating $('#tb').append() as if it's concatenating HTML text to the document, not inserting entire HTML elements. It should be something like:
for(var j=0;j<ar.length;j++){
console.log('<tr>');
var row = $('<tr/>').appendTo('#tb');
for(var k=0;k<2;k++){
console.log('<td>'+ar[k][j]+'</td>');
row.append('<td>'+ar[k][j]+'</td>'); // Append TD to TR
}
}
Or you can use CtrlX's answer, where he composes the entire table as a string, then inserts it into the DOM in one step. This is more efficient than building up the table incrementally.
You shouldn't append content like this to your table, because the browser must redraw the whole DOM, so it's not very efficient.
You should build your table inside a string, then append the whole string to your table, like this :
$('#tb').ready(
function() {
console.log('table loaded');
var ar = Array(2);
for(var i=0;i<ar.length;i++){
ar[i]=Array(2);
}
ar[0][0]='1';
ar[1][0]='2';
ar[0][1]='3';
ar[1][1]='4';
console.log('multidimensional array created!');
//Prepare the outputed string
var theTable = "";
for(var j=0;j<ar.length;j++){
theTable += '<tr>';
for(var k=0;k<2;k++){
theTable += '<td>'+ar[k][j]+'</td>';
}
theTable += '</tr>';
}
//Finally appended the whole string to the table
$('#tb').append(theTable);
//expected:
//12
//34
//actual
//1 2 3 4
});
I've made a Jsfiddle for you : JSFiddle
Have fun !
<body>
<table id='tb1'>
<tbody id='tb'>
</tbody>
</table>
</body>
<script>
$('#tb').ready(
function() {
console.log('table loaded');
var ar = Array(2);
for(var i=0;i<ar.length;i++){
ar[i]=Array(2);
}
ar[0][0]='1';
ar[1][0]='2';
ar[0][1]='3';
ar[1][1]='4';
console.log('multidimensional array created!');
for(var j=0;j<ar.length;j++){
$('#tb').append('<tr>');
for(var k=0;k<2;k++){
$('#tb').append('<td>'+ar[k][j]+'</td>');
}
$('#tb').append('</tr>');
}
//expected:
//12
//34
//actual
//1 2 3 4
});
</script>
</html>
this is the working code, on this fiddle http://jsfiddle.net/fn4Wz/

Categories