add sum of the a table with multiple header - javascript

I have drupal view that generate one table split to multiple table thead and tbody, I need to sum the total of the columns and rows per tbody and not for all the table
I have this code, see code here
HTML
<table id="sum_table" width="300" border="1">
<thead>
<tr class="titlerow">
<td></td>
<td>A</td>
<td>B</td>
<td>C</td>
<td>D</td>
<td>Total By Row</td>
</tr>
</thead>
<tbody>
<tr>
<td> Row1</td>
<td class="rowAA">1</td>
<td class="rowAA">2</td>
<td class="rowBB">3</td>
<td class="rowBB">4</td>
<td class="totalRow"></td>
</tr>
<tr>
<td> Row2</td>
<td class="rowAA">1</td>
<td class="rowAA">2</td>
<td class="rowBB">3</td>
<td class="rowBB">4</td>
<td class="totalRow"></td>
</tr>
<tr class="totalColumn">
<td class="totalCol"></td>
<td class="totalCol"></td>
<td class="totalCol"></td>
<td class="totalCol"></td>
<td class="totalCol"></td>
<td class="totalCol"></td>
</tr>
</tbody>
<thead>
<tr class="titlerow">
<td></td>
<td>AA</td>
<td>BB</td>
<td>CC</td>
<td>DD</td>
<td>Total By Row</td>
</tr>
</thead>
<tbody>
<tr>
<td> Row1</td>
<td class="rowAA">11</td>
<td class="rowAA">22</td>
<td class="rowBB">33</td>
<td class="rowBB">44</td>
<td class="totalRow"></td>
</tr>
<tr>
<td> Row2</td>
<td class="rowAA">11</td>
<td class="rowAA">22</td>
<td class="rowBB">33</td>
<td class="rowBB">44</td>
<td class="totalRow"></td>
</tr>
<tr class="totalColumn">
<td class="totalCol"></td>
<td class="totalCol"></td>
<td class="totalCol"></td>
<td class="totalCol"></td>
<td class="totalCol"></td>
<td class="totalCol"></td>
</tr>
</tbody>
<thead>
<tr class="titlerow">
<td></td>
<td>AAA</td>
<td>BBB</td>
<td>CCC</td>
<td>DDD</td>
<td>Total By Row</td>
</tr>
</thead>
<tbody>
<tr>
<td> Row1</td>
<td class="rowAA">111</td>
<td class="rowAA">222</td>
<td class="rowBB">333</td>
<td class="rowBB">444</td>
<td class="totalRow"></td>
</tr>
<tr>
<td> Row2</td>
<td class="rowAA">111</td>
<td class="rowAA">222</td>
<td class="rowBB">333</td>
<td class="rowBB">444</td>
<td class="totalRow"></td>
</tr>
<tr class="totalColumn">
<td class="totalCol"></td>
<td class="totalCol"></td>
<td class="totalCol"></td>
<td class="totalCol"></td>
<td class="totalCol"></td>
<td class="totalCol"></td>
</tr>
</tbody>
</table>
CSS
#sum_table {
white-space: nowrap;
}
#sum_table td {
padding: 5px 10px;
}
JavaScript in onLoad
$("#sum_table tr:not(:first,:last) td:last-child").text(function(){
var t = 0;
$(this).prevAll().each(function(){
t += parseInt( $(this).text(), 10 ) || 0;
});
return t;
});
$("#sum_table tr:last td:not(:first,:last)").text(function(i){
var t = 0;
$(this).parent().prevAll().find("td:nth-child("+(i+2)+")").each(function(){
t += parseInt( $(this).text(), 10 ) || 0;
});
return "Total: " + t;
});
How can I sum total after every category?
Thanks a lot

Here is a FIDDLE that does most of what you want.
I just saw your comment about the totals after every tbody...I'll have to work on it a bit more. Still doable.
JS
var totrow = 0, totcol=0; //setting totalsforrow and totalsforcolumns variables to zero
$('.numrow').each( function(){ //for each of the rows with class='numrow'
for(var n=1; n<5; n++) //do a loop four times for the right column totals
{
totrow = totrow + parseInt( $(this).children("td:eq("+ n +")").text() );
} //grab the values of each of the four tds and add them together
$( $(this).children('td:eq(5)') ).html(totrow); //put the summed value in the 'total' td
totrow = 0; // reset the value for the next "each .numrow"
});
for(var m = 1; m < 5; m++) //for loop for four column totals
{
$('.numrow').each( function(){ // for each of the rows with class .numrow
totcol = totcol + parseInt($(this).children("td:eq("+ m +")").text() );//add up values
console.log(totcol); // just a view of the totcol printed to the console log
});
$( "#sum_table tr:eq(11) td:eq(" + m + ")" ).html( 'Col total: ' + totcol );//put total at bottom of column
totcol = 0; //reset total to get read for the next loop
}
Edit: Here's the update FIDDLE. It's brute-force, inelegant, but it works.

Related

How to calculate the difference of two values in a <td> tag in another <td> tag in HTML

I have a table in HTML which is rendered and it is like,
{% for element in combined_list %}
<td id='first'>element.first</td>
<td id='second'>element.second</td>
<td id='diff>I want the difference of first and second here</td>
{% endfor %}
I tried with jQuery also like:
jQuery(document).ready(function($) {
let first_= jQuery('#first','/^[0-9]*$/' ).text();
let second_ = jQuery('#second').html();
let diff = first_- second_ ;
$('#diff').html(diff)
});
But Im getting for only one column. Thanks in advance.
You can't have multiple column with the same id, use class instead
$(document).ready(function(){
var rows = document.getElementById("table").getElementsByTagName("tr");
for(var i = 0; i < rows.length; i++)
{
var first = parseInt(rows[i].getElementsByClassName("first")[0].textContent);
var second = parseInt(rows[i].getElementsByClassName("second")[0].textContent);
var diff = first - second;
console.log("First: "+first+" - second : "+second+" = "+diff);
rows[i].getElementsByClassName("diff")[0].textContent = diff;
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id='table'>
<tr>
<td class='first'>5</td>
<td class='second'>4</td>
<td class='diff'>diffhere</td>
</tr>
<tr>
<td class='first'>9</td>
<td class='second'>3</td>
<td class='diff'>diffhere</td>
</tr>
</table>
You have a typo in the second id - missing quote
IDs need to be unique so use instead a class and you can loop over all the first columns
you can use relative addressing via .next and/or .closest to get the other columns
$(function() {
$("#tb .first").each(function() {
const val1 = +$(this).text();
const val2 = +$(this).next().text();
$(this).closest("tr").find(".diff").text(val1 - val2);
})
})
td {
border: 1px solid black;
padding: 3px;
text-align: right;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>1st</th>
<th>2nd</th>
<th>Diff</th>
</tr>
</thead>
<tbody id="tb">
<tr>
<td class="first">11</td>
<td class="second">9</td>
<td class="diff"></td>
</tr>
<tr>
<td class="first">12</td>
<td class="second">8</td>
<td class="diff"></td>
</tr>
<tr>
<td class="first">13</td>
<td class="second">7</td>
<td class="diff"></td>
</tr>
<tr>
<td class="first">14</td>
<td class="second">6</td>
<td class="diff"></td>
</tr>
<tr>
<td class="first">15</td>
<td class="second">5</td>
<td class="diff"></td>
</tr>
</tbody>
</table>
Plain JS
window.addEventListener('load', function() {
[...document.querySelectorAll('#tb .first')].forEach(cell => {
const parent = cell.closest('tr');
const val1 = +cell.textContent;
const val2 = +parent.querySelector('.second').textContent;
parent.querySelector('.diff').textContent = val1 - val2;
})
})
td {
border: 1px solid black;
padding: 3px;
text-align: right;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>1st</th>
<th>2nd</th>
<th>Diff</th>
</tr>
</thead>
<tbody id="tb">
<tr>
<td class="first">11</td>
<td class="second">9</td>
<td class="diff"></td>
</tr>
<tr>
<td class="first">12</td>
<td class="second">8</td>
<td class="diff"></td>
</tr>
<tr>
<td class="first">13</td>
<td class="second">7</td>
<td class="diff"></td>
</tr>
<tr>
<td class="first">14</td>
<td class="second">6</td>
<td class="diff"></td>
</tr>
<tr>
<td class="first">15</td>
<td class="second">5</td>
<td class="diff"></td>
</tr>
</tbody>
</table>

Attempting to sum html tables results in numbers being concatenated like strings?

While trying to get the sum total of the values of an html table column, my variable is returning concatenated strings: instead of 1 + 2 + 3 = 6, I am seeing 1 + 2 + 3 = 123.
The "votes" column values are incremented by an ajax call when the users click on the colors, which is correct. But I also hope to see the sum of all values when "total" is clicked.
Jquery:
$('#total').on('click', function() {
var sumofval = 0;
$(".val").each(function () {
sumofval = sumofval + ($(this).html());
$('#totalr').html(sumofval);
console.log(sumofval);
});
});
The HTML Color-Votes Table:
<table id="tcol" style="width:60%;">
<thead>
<tr>
<th>Color</th>
<th>Votes</th>
</tr>
</thead>
<tr>
<td id="red">Red</td>
<td id="redr" class="val"></td>
</tr>
<tr>
<td id="orange">Orange</td>
<td id="oranger" class="val"></td>
</tr>
<tr>
<td id="yellow">Yellow</td>
<td id="yellowr" class="val"></td>
</tr>
<tr>
<td id="green">Green</td>
<td id="greenr" class="val"></td>
</tr>
<tr>
<td id="blue">Blue</td>
<td id="bluer" class="val"></td>
</tr>
<tr>
<td id="indigo">Indigo</td>
<td id="indigor" class="val"></td>
</tr>
<tr>
<td id="total">TOTAL</td>
<td id="totalr"></td>
</tr>
</table>
Convert it to number. (You can do it by adding + at the start, or using parseInt function)
sumofval = sumofval +.. can be replaced with sumofval+=..
do $('#totalr').html(sumofval); at each step in the loop is redandent. better do it once at the end
$('#total').on('click', function() {
var sumofval = 0;
$(".val").each(function () {
sumofval += +$(this).html() || 0;
});
$('#totalr').html(sumofval);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tcol" style="width:60%;">
<thead>
<tr>
<th>Color</th>
<th>Votes</th>
</tr>
</thead>
<tr>
<td id="red">Red</td>
<td id="redr" class="val"></td>
</tr>
<tr>
<td id="orange">Orange</td>
<td id="oranger" class="val">2</td>
</tr>
<tr>
<td id="yellow">Yellow</td>
<td id="yellowr" class="val">3</td>
</tr>
<tr>
<td id="green">Green</td>
<td id="greenr" class="val">4</td>
</tr>
<tr>
<td id="blue">Blue</td>
<td id="bluer" class="val">5</td>
</tr>
<tr>
<td id="indigo">Indigo</td>
<td id="indigor" class="val">6</td>
</tr>
<tr>
<td id="total">TOTAL</td>
<td id="totalr"></td>
</tr>
Also you can do:
$('#totalr').html(Array.from($(".val")).reduce(function(a,b){return (+$(b).html() ||0)+a}, 0));
If one term isn't a number, JavaScript will treat everything as string and concatenate the values instead. So you need to make sure the value's you're adding up are all number types:
$('#total').on('click', function() {
var sumofval = 0;
$(".val").each(function () {
sumofval = sumofval + getInt($(this).html());
$('#totalr').html(sumofval); //this line should be moved outside .each loop
console.log(sumofval);
)};
});
function getInt(t){
if(!isNaN(parseFloat(t)) && isFinite(t)){
return parseInt(t,10);
}
return 0;
}
As suggested, use parseInt to parse strings and convert them to integers. Then you can add them to the sumofval correctly.
$('#total').on('click', function() {
var sumofval = 0;
$(".val").each(function() {
if ($(this).text() !== '') {
sumofval = sumofval + parseInt(($(this).text()));
$('#totalr').text(sumofval);
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tcol" style="width:60%;">
<thead>
<tr>
<th>Color</th>
<th>Votes</th>
</tr>
</thead>
<tr>
<td id="red">Red</td>
<td id="redr" class="val">2</td>
</tr>
<tr>
<td id="orange">Orange</td>
<td id="oranger" class="val"></td>
</tr>
<tr>
<td id="yellow">Yellow</td>
<td id="yellowr" class="val">3</td>
</tr>
<tr>
<td id="green">Green</td>
<td id="greenr" class="val">3</td>
</tr>
<tr>
<td id="blue">Blue</td>
<td id="bluer" class="val">3</td>
</tr>
<tr>
<td id="indigo">Indigo</td>
<td id="indigor" class="val">3</td>
</tr>
<tr>
<td id="total">TOTAL</td>
<td id="totalr"></td>
</tr>
</table>
Also, consider using .text() to get the value of the element instead of .html().

JS loop through table and print text in column based on condition

I have a simple table, and I need to print a text in a certain column based on condition over hidden columns. There are multiple rows as a record which have same TD ID. What I need to do is, to go through each row of table and check status1 (gv-field-15-139), status2 (gv-field-15-140) and status3 (gv-field-15-141). If one of this status (gv-field-15-150) is 'Completed' I want to print Completed in Status column. is it possible?
$(document).ready(function(){
if(($('td#gv-field-15-139').text() == 'Completed') || ($('td#gv-field-15-
140').text() == 'Completed') || ($('td#gv-field-15-141').text() == 'Completed') ) {
$("td#gv-field-15-150").text('Completed');
}
<table>
<tr>
<th>Student Name</th>
<th>Nationality</th>
<th>Status</th>
<th>Status1</th>
<th>Status2</th>
<th>Status3</th>
</tr>
<tr>
<td id="gv-field-15-1">Student A</td>
<td id="gv-field-15-90">India</td>
<td id="gv-field-15-150"> </td>
<td id="gv-field-15-139">Completed</td>
<td id="gv-field-15-140">Pending</td>
<td id="gv-field-15-141">Pending</td>
</tr>
<tr>
<td id="gv-field-15-1">Student B</td>
<td id="gv-field-15-90">China</td>
<td id="gv-field-15-150"> </td>
<td id="gv-field-15-139">Completed</td>
<td id="gv-field-15-140">Pending</td>
<td id="gv-field-15-141">Pending</td>
</tr>
</table>
This only works for 1 row and when it becomes 2 row or more it doesn't work. Could you please show me a way to achieve this.
Loop your tr except the first tr which has th and check td. Though you can achieve the solution to your problem with ids, its recommended to use class instead of ids.
$(document).ready(function() {
var trs = $('tr').not(':eq(0)');
$.each(trs, function() {
var $this = $(this);
if (($this.find('>td#gv-field-15-139').text() == 'Completed') || ($this.find('>td#gv-field-15-140').text() == 'Completed') || ($this.find('>td#gv-field-15-141').text() == 'Completed')) {
$this.find(">td#gv-field-15-150").text('Completed');
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<th>Student Name</th>
<th>Nationality</th>
<th>Status</th>
<th>Status1</th>
<th>Status2</th>
<th>Status3</th>
</tr>
<tr>
<td id="gv-field-15-1">Student A</td>
<td id="gv-field-15-90">India</td>
<td id="gv-field-15-150"> </td>
<td id="gv-field-15-139">Completed</td>
<td id="gv-field-15-140">Pending</td>
<td id="gv-field-15-141">Pending</td>
</tr>
<tr>
<td id="gv-field-15-1">Student B</td>
<td id="gv-field-15-90">China</td>
<td id="gv-field-15-150"> </td>
<td id="gv-field-15-139">Completed</td>
<td id="gv-field-15-140">Pending</td>
<td id="gv-field-15-141">Pending</td>
</tr>
<tr>
<td id="gv-field-15-1">Student B</td>
<td id="gv-field-15-90">China</td>
<td id="gv-field-15-150"> </td>
<td id="gv-field-15-139">Pending</td>
<td id="gv-field-15-140">Pending</td>
<td id="gv-field-15-141">Pending</td>
</tr>
</table>
Do not use duplicate id's, you can use the index of the cells intead:
const table = document.querySelector('table');
//take all rows except the header
const rows = Array.from(table.querySelectorAll('tr')).slice(
1,
);
rows.forEach((row) => {
const cells = Array.from(
row.querySelectorAll('td')
);
//get the 3rd cell
const [, , toSet] = cells;
//all values after 3rd cell
const [, , ,...values] = cells.map(
(cell) => cell.innerText.trim()//map to the innerText of the cell
);
if(values.includes('Completed')){
toSet.innerHTML = 'Completed'
}
});
<table>
<tr>
<th>Student Name</th>
<th>Nationality</th>
<th>Status</th>
<th>Status1</th>
<th>Status2</th>
<th>Status3</th>
</tr>
<tr>
<td>Student A</td>
<td>India</td>
<td>xxx</td>
<td>Completed</td>
<td>Pending</td>
<td>Pending</td>
</tr>
<tr>
<td>Student B</td>
<td>China</td>
<td>xxx</td>
<td>Completed</td>
<td>Pending</td>
<td>Pending</td>
</tr>
<tr>
<td>Student C</td>
<td>Not Completed</td>
<td>xxx</td>
<td>Pending</td>
<td>Pending</td>
<td>Pending</td>
</tr>
</table>
This solution is so simplistic it doesn't even have a need for jQuery, I also thought that it might be nicer to read if you broke the logic up a bit, i.e. rather than having an ugly & long looking if statement, I've implemented the isComplete function.
FYI. ID's are meant to be unique throughout the entire page, it may be a better idea to change them to classes if you can.
Edit
After having looked at the beautiful solution produced by #HMR I thought I'd include some of the elegant code that was implemented into this solution, I can't take all the credit there!
// Just short hand.
const $e = queryString => document.querySelectorAll(queryString);
const term = 'Completed';
// Returns a boolean.
const isComplete = td => td.textContent.replace(/\ /, '') === term;
// Some fallback function.
const fallback = () => console.log('Next...');
// Render the update(s).
const render = (v, t) => v.includes(true) ? t.textContent = term : fallback();
// Updates the relevant td tags.
const update = tr => {
const tds = Array.from(tr.querySelectorAll('td'));
const [, , , ...values] = tds.map(td => isComplete(td));
const [, , td] = tds;
render(values, td);
};
// Iterate over the relevant tr tags.
const loop = () => Array.from($e("table tr")).splice(1, ).forEach(tr => update(tr));
// Start the process.
loop();
<table>
<tr>
<th>Student Name</th>
<th>Nationality</th>
<th>Status</th>
<th>Status1</th>
<th>Status2</th>
<th>Status3</th>
</tr>
<tr>
<td id="gv-field-15-1">Student A</td>
<td id="gv-field-15-90">India</td>
<td id="gv-field-15-150"> </td>
<td id="gv-field-15-139">Completed</td>
<td id="gv-field-15-140">Pending</td>
<td id="gv-field-15-141">Pending</td>
</tr>
<tr>
<td id="gv-field-15-1">Student B</td>
<td id="gv-field-15-90">China</td>
<td id="gv-field-15-150"> </td>
<td id="gv-field-15-139">Completed</td>
<td id="gv-field-15-140">Pending</td>
<td id="gv-field-15-141">Pending</td>
</tr>
<tr>
<td id="gv-field-15-1">Student C</td>
<td id="gv-field-15-90">China</td>
<td id="gv-field-15-150"> </td>
<td id="gv-field-15-139">Pending</td>
<td id="gv-field-15-140">Pending</td>
<td id="gv-field-15-141">Pending</td>
</tr>
</table>
There are couple of issues:
You have duplicate IDs. ID must be unique. In your current code, you will always get first element with necessary ID. So you should use classes instead
You are not looping. Since its a table and you have to handle each row, you have to loop over all rows and based on current row, you have to check/update necessary column's value.
$(document).ready(function() {
var $tr = $('table tr');
$.each($tr, function(index, tr) {
if (
($('.gv-field-15-139', tr).text() == 'Completed') ||
($('.gv-field-15- 140', tr).text() == 'Completed') ||
($('.gv-field-15-141', tr).text() == 'Completed')
) {
$(".gv-field-15-150", tr).text('Completed');
}
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<table>
<tr>
<th>Student Name</th>
<th>Nationality</th>
<th>Status</th>
<th>Status1</th>
<th>Status2</th>
<th>Status3</th>
</tr>
<tr>
<td class="gv-field-15-1">Student A</td>
<td class="gv-field-15-90">India</td>
<td class="gv-field-15-150"> </td>
<td class="gv-field-15-139">Completed</td>
<td class="gv-field-15-140">Pending</td>
<td class="gv-field-15-141">Pending</td>
</tr>
<tr>
<td class="gv-field-15-1">Student B</td>
<td class="gv-field-15-90">China</td>
<td class="gv-field-15-150"> </td>
<td class="gv-field-15-139">Pending</td>
<td class="gv-field-15-140">Pending</td>
<td class="gv-field-15-141">Pending</td>
</tr>
</table>
Loop through all the rows in the table except the first row(and hence => $('tr').length-1).
.eq() function is used to access each element/text by index..
$(document).ready(function () {
for(i=0;i<$('tr').length-1;i++){
if( ($('td#gv-field-15-139').eq(i).text() == 'Completed') || ($('td#gv-field-15-140').eq(i).text() == 'Completed') || ($('td#gv - field - 15 - 141').eq(i).text() == 'Completed') ) {
$("td#gv-field-15-150").eq(i).text('Completed');
}
}
});
#IDs Must Always be Unique
Having duplicated #ids makes HTML invalid, more importantly it cripples JS/jQ because it is expected that #ids are unique so once found, no efforts are made to continue for second occurrence of an #id.
Changes
All #ids have been changed to .classes
The last 3 <td> of each row have a shared class: .status
The 3rd <td> of each row has a new class: .primary
Reference
.each()
.prevAll()
Demo
Three lines of code...that's all you need.
$('.status').each(function() {
if ($(this).text() === 'Completed') {
$(this).prevAll('.primary').text('Completed');
}
});
<table>
<tr>
<th>Student Name</th>
<th>Nationality</th>
<th>Status</th>
<th>Status1</th>
<th>Status2</th>
<th>Status3</th>
</tr>
<tr>
<td class="gv-field-15-1">Student A</td>
<td class="gv-field-15-90">India</td>
<td class="gv-field-15-150 primary"> </td>
<td class="gv-field-15-139 status">Completed</td>
<td class="gv-field-15-140 status">Pending</td>
<td class="gv-field-15-141 status">Pending</td>
</tr>
<tr>
<td class="gv-field-15-1">Student B</td>
<td class="gv-field-15-90">China</td>
<td class="gv-field-15-150 primary"> </td>
<td class="gv-field-15-139 status">Completed</td>
<td class="gv-field-15-140 status">Pending</td>
<td class="gv-field-15-141 status">Pending</td>
</tr>
<tr>
<td class="gv-field-15-1">Student C</td>
<td class="gv-field-15-90">USA</td>
<td class="gv-field-15-150 primary"> </td>
<td class="gv-field-15-139 status">ERROR</td>
<td class="gv-field-15-140 status">Pending</td>
<td class="gv-field-15-141 status">Pending</td>
</tr>
<tr>
<td class="gv-field-15-1">Student D</td>
<td class="gv-field-15-90">France</td>
<td class="gv-field-15-150 primary"> </td>
<td class="gv-field-15-139 status">Pending</td>
<td class="gv-field-15-140 status">Pending</td>
<td class="gv-field-15-141 status">Completed</td>
</tr>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Extracting table column values from html table using javascript

Only started using javascript 2 weeks ago so I only have a limited understanding.
I have some javascript code that generates a html table from excel documents and i need to extract the values from part of one column and place those values into an array. Which i later will use to generate a line graph. The code mainly needs to work on IE11.
Truncated example table below.
<tbody>
// several other rows here
<tr>
<td id="sjs-A16">column head A</td>
<td id="sjs-B16">column head B</td>
<td id="sjs-C16">column head C</td>
<td id="sjs-D16">column head D</td>
<td id="sjs-E16">column head E</td>
<td id="sjs-F16">column head F</td>
<td id="sjs-G16">column head G</td>
<td id="sjs-H16">column head H</td>
</tr>
<tr>
<td id="sjs-A17">1A</td>
<td id="sjs-B17">1B</td>
<td id="sjs-C17">1C</td>
<td id="sjs-D17">1D</td>
<td id="sjs-E17">1E</td>
<td id="sjs-F17">1F</td>
<td id="sjs-G17">1G</td>
<td id="sjs-H17">1H</td>
</tr>
<tr>
<td id="sjs-A18">2A</td>
<td id="sjs-B18">2B</td>
<td id="sjs-C18">2C</td>
<td id="sjs-D18">2D</td>
<td id="sjs-E18">2E</td>
<td id="sjs-F18">2F</td>
<td id="sjs-G18">2G</td>
<td id="sjs-H18">2H</td>
</tr>
<tr>
<td id="sjs-A19">3A</td>
<td id="sjs-B19">3B</td>
<td id="sjs-C19">3C</td>
<td id="sjs-D19">3D</td>
<td id="sjs-E19">3E</td>
<td id="sjs-F19">3F</td>
<td id="sjs-G19">3G</td>
<td id="sjs-H19">3H</td>
</tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
//several more empty rows here
</tbody>
I need the value of all cells with ids in the E(xx) but only id sjs-E17 and greater (sjs-Exx where xx >= 17), so value 1E-3E+ but no cell above that one (so not sjs-E16 to sjs-E1).
The number of rows i varies but the needed values always start on row 17. And as seen the scrip generates several empty rows after the values stop, but none of them have any id.
Expected results is just an array (or function) containing the values from cell E17+
var test_array = ["1E", "2E", "3E", ...];
Using jQuery, you can do this:
var td = $('[id^="sjs-E"]'),
valArray = [];
td.each(function() {
var id = $(this).attr('id'),
idVal = +id.substring(5); //parse value after `E` to number using (+)
//check if idVal is number
if (!isNaN(idVal)) {
if (idVal >= 17) {
valArray.push($(this).html());
}
}
});
console.log(valArray);
.header {
background-color: grey;
font-size: 15px;
}
td {
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr class="header">
<td id="sjs-A16">column head A</td>
<td id="sjs-B16">column head B</td>
<td id="sjs-C16">column head C</td>
<td id="sjs-D16">column head D</td>
<td id="sjs-E16">column head E</td>
<td id="sjs-F16">column head F</td>
<td id="sjs-G16">column head G</td>
<td id="sjs-H16">column head H</td>
</tr>
<tr>
<td id="sjs-A17">1A</td>
<td id="sjs-B17">1B</td>
<td id="sjs-C17">1C</td>
<td id="sjs-D17">1D</td>
<td id="sjs-E17">1E</td>
<td id="sjs-F17">1F</td>
<td id="sjs-G17">1G</td>
<td id="sjs-H17">1H</td>
</tr>
<tr>
<td id="sjs-A18">2A</td>
<td id="sjs-B18">2B</td>
<td id="sjs-C18">2C</td>
<td id="sjs-D18">2D</td>
<td id="sjs-E18">2E</td>
<td id="sjs-F18">2F</td>
<td id="sjs-G18">2G</td>
<td id="sjs-H18">2H</td>
</tr>
<tr>
<td id="sjs-A19">3A</td>
<td id="sjs-B19">3B</td>
<td id="sjs-C19">3C</td>
<td id="sjs-D19">3D</td>
<td id="sjs-E19">3E</td>
<td id="sjs-F19">3F</td>
<td id="sjs-G19">3G</td>
<td id="sjs-H19">3H</td>
</tr>
<!-- several empty rows -->
</tbody>
</table>
Or, using vanilla javascript:
var tdRE = /^sjs-E([2-9]\d|1[7-9]|[1-9]{3,})$/,
els = document.getElementsByTagName('*'),
valArray = [];
for (var i = 0; i < els.length; i++) {
var match = tdRE.exec(els[i].id);
if (match) {
if ((+match[1]) >= 17) { //the (+) operator again, convert string to number and check if >= 17
valArray.push(els[i].innerHTML);
}
}
}
console.log(valArray);
.header {
background-color: grey;
font-size: 15px;
}
td {
text-align: center;
}
<table>
<tbody>
<tr class="header">
<td id="sjs-A16">column head A</td>
<td id="sjs-B16">column head B</td>
<td id="sjs-C16">column head C</td>
<td id="sjs-D16">column head D</td>
<td id="sjs-E16">column head E</td>
<td id="sjs-F16">column head F</td>
<td id="sjs-G16">column head G</td>
<td id="sjs-H16">column head H</td>
</tr>
<tr>
<td id="sjs-A17">1A</td>
<td id="sjs-B17">1B</td>
<td id="sjs-C17">1C</td>
<td id="sjs-D17">1D</td>
<td id="sjs-E17">1E</td>
<td id="sjs-F17">1F</td>
<td id="sjs-G17">1G</td>
<td id="sjs-H17">1H</td>
</tr>
<tr>
<td id="sjs-A18">2A</td>
<td id="sjs-B18">2B</td>
<td id="sjs-C18">2C</td>
<td id="sjs-D18">2D</td>
<td id="sjs-E18">2E</td>
<td id="sjs-F18">2F</td>
<td id="sjs-G18">2G</td>
<td id="sjs-H18">2H</td>
</tr>
<tr>
<td id="sjs-A19">3A</td>
<td id="sjs-B19">3B</td>
<td id="sjs-C19">3C</td>
<td id="sjs-D19">3D</td>
<td id="sjs-E19">3E</td>
<td id="sjs-F19">3F</td>
<td id="sjs-G19">3G</td>
<td id="sjs-H19">3H</td>
</tr>
<!-- several empty rows -->
</tbody>
</table>
Regex explanation:
^sjs-E([2-9]\d|[1-9][7-9]|\d{3,})$
^ - asserts beginning of string
() - catching group
| - logical OR
$ - end of string
^sjs-E - starts with sjs-E
[2-9]\d - matches between 20 - 99
OR
1[7-9] - matches 17 - 19
OR
[1-9]{3,} - matches 100 and above
let result = [];
$('table tr td[id^="sjs-E"]').each(function(){
let ele = $(this);
//extracting last two digits of id
let digits = ele.attr('id').slice(-2);
if(!isNaN(digits) && digits >= 17){
result.push(ele.html());
}
});
console.log(result);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td id="sjs-A16">column head A</td>
<td id="sjs-B16">column head B</td>
<td id="sjs-C16">column head C</td>
<td id="sjs-D16">column head D</td>
<td id="sjs-E16">column head E</td>
<td id="sjs-F16">column head F</td>
<td id="sjs-G16">column head G</td>
<td id="sjs-H16">column head H</td>
</tr>
<tr>
<td id="sjs-A17">1A</td>
<td id="sjs-B17">1B</td>
<td id="sjs-C17">1C</td>
<td id="sjs-D17">1D</td>
<td id="sjs-E17">1E</td>
<td id="sjs-F17">1F</td>
<td id="sjs-G17">1G</td>
<td id="sjs-H17">1H</td>
</tr>
<tr>
<td id="sjs-A18">2A</td>
<td id="sjs-B18">2B</td>
<td id="sjs-C18">2C</td>
<td id="sjs-D18">2D</td>
<td id="sjs-E18">2E</td>
<td id="sjs-F18">2F</td>
<td id="sjs-G18">2G</td>
<td id="sjs-H18">2H</td>
</tr>
<tr>
<td id="sjs-A19">3A</td>
<td id="sjs-B19">3B</td>
<td id="sjs-C19">3C</td>
<td id="sjs-D19">3D</td>
<td id="sjs-E19">3E</td>
<td id="sjs-F19">3F</td>
<td id="sjs-G19">3G</td>
<td id="sjs-H19">3H</td>
</tr>
</tbody>
</table>
var test_array = [];
var isGreaterThan = 17;
var until = 1000; // i don't know
for (var i=isGreaterThan; i < until; i++) {
var html = document.getElementById('sjs-E' + i.toString());
if (html) {
test_array.push(html.innerText);
}
}

merge cell duplicate values

This is the image
<table id="tblSample">
<!--Heading-->
<tbody>
<th>Super Partner</th><th>Products</th><th></th>
<th>Plan</th><th>Actual</th><th>Difference</th><th>%</th>
<th>Plan</th><th>Actual</th><th>Difference</th><th>%</th>
<th>Plan</th><th>Actual</th><th>Difference</th><th>%</th>
<th>Plan</th><th>Actual</th><th>Difference</th><th>%</th>
<th>Total Plan</th><th>Actual YTD + Plan</th><th>Difference</th><th>%</th>
</tr>
<tr class="getfor counter_row_0 hide_other_prtnr" colspan="" for="20" id="myTable">
<td style="border-top:1px solid #ddd;border-bottom:none;" class="inner_for">
Gagan </td>
</tr>
<tr class="counter_row_0 hide_other_prtnr">
<td style="border:none;"></td>
<td rowspan="2">Sales Play 1</td>
</tr>
<tr class="counter_row_0 hide_other_prtnr">
<td style="border:none;"></td>
<td rowspan="2">Sales Play 2</td>
</tr>
<tr class="getfor counter_row_1 hide_other_prtnr" colspan="" for="20" id="myTable">
<td style="border-top:1px solid #ddd;border-bottom:none;" class="inner_for">
Gagan </td>
</tr>
<tr class="counter_row_1 hide_other_prtnr">
<td style="border:none;"></td>
<td rowspan="2">Sales Play 10</td>
</tr>
<tr class="counter_row_1 hide_other_prtnr">
<td style="border:none;"></td>
<td rowspan="2">Monika_Testing_Product</td>
</tr>
<tr class="getfor counter_row_2 hide_other_prtnr" colspan="" for="20" id="myTable">
<td style="border-top:1px solid #ddd;border-bottom:none;" class="inner_for">
Gagan </td>
</tr>
<tr class="counter_row_2 hide_other_prtnr">
<td style="border:none;"></td>
<td rowspan="2">Sales Play 1</td>
</tr>
<tr class="counter_row_2 hide_other_prtnr">
<td style="border:none;"></td>
<td rowspan="2">Sales Play 2</td>
</tr>
</tr>
<tr class="counter_row_2 hide_other_prtnr">
<td style="border:none;"></td>
<td rowspan="2">Sales Play 3</td>
</tr>
<tr class="counter_row_2 hide_other_prtnr">
<td style="border:none;"></td>
<td rowspan="2">Sales Play 4</td>
</tr>
<!-- cam total total -->
</tr>
<tr class="getfor counter_row_3 hide_other_prtnr" colspan="" for="21" id="myTable">
<td style="border-top:1px solid #ddd;border-bottom:none;" class="inner_for">
Gaurav </td>
</tr>
<tr class="counter_row_3 hide_other_prtnr">
<td style="border:none;"></td>
<td rowspan="2">Sales Play 10</td>
</tr>
<tr class="counter_row_3 hide_other_prtnr">
<td style="border:none;"></td>
<td rowspan="2">Monika_Testing_Product</td>
</tr>
</tr>
<tr class="getfor counter_row_4 hide_other_prtnr" colspan="" for="22" id="myTable">
<td style="border-top:1px solid #ddd;border-bottom:none;" class="inner_for">
RaviKant </td>
</tr>
<tr class="counter_row_4 hide_other_prtnr">
<td style="border:none;"></td>
<td rowspan="2">Macross Sales</td>
</tr>
</tr>
<tr class="counter_row_4 hide_other_prtnr">
<td style="border:none;"></td>
<td rowspan="2">Sales infinity</td>
</tr>
</tr>
<tr class="counter_row_4 hide_other_prtnr">
<td style="border:none;"></td>
<td rowspan="2">Sales Play 3</td>
</tr>
</tr>
<script>
$(document).ready(function() {
var span = 1;
var prevTD = "";
var prevTDVal = "";
$("#myTable td:first-child").each(function() { //for each first td in every tr
var $this = $(this);
if ($this.text() == prevTDVal) { // check value of previous td text
span++;
if (prevTD != "") {
// prevTD.attr("rowspan", span); // add attribute to previous td
$this.text("");// remove current td
// $this.attr("rowspan","1");
}
} else {
prevTD = $this; // store current td
prevTDVal = $this.text();
span = 1;
}
});
var count_row = [] ;
var unique_for = [] ;
$(".getfor").each(function(){
var for_data = $(this).attr('for') ;
var row_count = $(this).find(".inner_for").attr('rowspan');
if(jQuery.inArray(for_data, unique_for) == -1)
{
count_row[for_data] = row_count;
unique_for.push(for_data);
}
else
{
count_row[for_data] = parseInt(count_row[for_data]) + parseInt(row_count) ;
}
});
alert(count_row);
$.each(count_row, function() {
var key = Object.keys(this)[0];
var value = this[key];
if(value > 0 ){
//unique_for.setAttribute("rowspan",count_row);
//alert(value+' : key : ' +key);
}
})
});
</script>
i just want that the empty cell filled combine with the "Gagan".in above code i just empty the duplicate name but now i want that the gagan name should be varies in middle of the cell.

Categories

Resources