Reputation: 23
I have a page where several tables displayed with the data from the backend with php foreach
functionality.
Each table has few rows with a column " m3 "
<td class="p-0 singleUnitCubic-{{$container->id}}">
{{$item->prettyDecimal('total_cubic')}}
</td>
rendered result is:
_______________________________________________________
<td class="p-0 singleUnitCubic-13">
12.600
</td>
<td class="p-0 singleUnitCubic-13">
4.000
</td>
_______________________________________________________
Total: <span id="totalCubic-13">16.600</span>
_______________________________________________________
<td class="p-0 singleUnitCubic-69">
4.230
</td>
<td class="p-0 singleUnitCubic-69">
3.000
</td>
_______________________________________________________
Total: <span id="totalCubic-69">7.230</span>
Now I can easily get the sum for one of the tables because I marked each class="singleUnitCubic"
with corresponding table id number, in this case, it's class="singleUnitCubic-13"
and my sum function is:
cubicOutput = document.getElementById('totalCubic-13');
var sumSingleUnits = 0;
$('.singleUnitCubic-13').each(function(){
sumSingleUnits += parseFloat($(this).text());
cubicOutput.innerText = SingleUnits.toFixed(3);
});
but how can I do the same dynamically for other tables where class="singleUnitCubic-69"
and also display that sum under each corresponding table where <span id="totalCubic-69">
?
Should it be something like finding what is the id
number after singleUnitCubic-
which I could do by:
<td onload="getTableid(this.class)" class="p-0 singleUnitCubic-{{$container->id}}">
{{$item->prettyDecimal('total_cubic')}}
</td>
function getTableId(Id) {
tableId = Id.split('-')[1];
totalCubic = document.getElementById("totalCubic-".concat(tableId));
and then somehow injecting it to the sum function?
P.S. I can't do the sum in back-end which would be easy.
Upvotes: 2
Views: 257
Reputation: 24638
First determine the tables that have the target columns, you can use :has()
or other method. Then iterate through each table and find the total. Array#reduce
comes in handy here:
//capture the table that have target columns
const tables = $('table:has(td[class*=singleUnitCubic])');
//now process each table
const totals = tables.each(function() {
//determine the id of span to update
const id = ['#totalCubic',$('td[class*=singleUnitCubic]',this).attr('class').split(' ')
.filter(c => c.indexOf('singleUnitCubic') === 0)[0]
.split('-')[1]].join('-');
//get this total
const total = $('td[class*=singleUnitCubic]', this)
.map((i,td) => +td.textContent).get()
.reduce((acc, cur) => acc += cur, 0);
//now update the dom
$(id).text( total.toFixed(3) );
});
DEMO
$(function() {
//capture the table that have target columns
const tables = $('table:has(td[class*=singleUnitCubic])');
//now process each table
const totals = tables.each(function() {
//determine the id of span to update
const id = ['#totalCubic',$('td[class*=singleUnitCubic]',this).attr('class').split(' ')
.filter(c => c.indexOf('singleUnitCubic') === 0)[0]
.split('-')[1]].join('-');
//get this total
const total = $('td[class*=singleUnitCubic]', this)
.map((i,td) => +td.textContent).get()
.reduce((acc, cur) => acc += cur, 0);
//now update the dom
$(id).text( total.toFixed(3) );
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td class="p-0 singleUnitCubic-13">
12.600
</td>
</tr>
<tr>
<td class="p-0 singleUnitCubic-13">
4.000
</td>
</tr></tbody>
</table>
Total: <span id="totalCubic-13"></span>
<table>
<tbody>
<tr>
<td class="p-0 singleUnitCubic-69">
4.230
</td>
</tr>
<tr>
<td class="p-0 singleUnitCubic-69">
3.000
</td>
</tr>
</tbody>
</table>
Total: <span id="totalCubic-69"></span>
Determining the ID for the Total
//just a way to concatenate strings ['totalCubic', '69'].join('-')
//to give rise to 'totalCubic-69'
//for example
In this version of the demo I have broken down the line determining the total id
into several lines just to make it simpler to follow what is being done:
//get class(es) of first td of this table as an array
const cl = $('td[class*=singleUnitCubic]',this).attr('class').split(' ');
console.log( cl );
//But we only need one 'singleUnitCubic-' ....
const onecl = cl.filter(c => c.indexOf('singleUnitCubic') === 0)[0];
console.log( onecl );
//And we just want to numeric part at the end
const thenumber = onecl.split('-')[1];
//So now the id where the total will be put is
const id = ['#totalCubic', thenumber].join('-');
//or const id = `#totalCubic-${thenumber}`;
$(function() {
//capture the table that have target columns
const tables = $('table:has(td[class*=singleUnitCubic])');
//now process each table
const totals = tables.each(function() {
//get class(es) of first td of this table as an array
const cl = $('td[class*=singleUnitCubic]',this).attr('class').split(' ');
console.log( cl );
//But we only need one 'singleUnitCubic-' ....
const onecl = cl.filter(c => c.indexOf('singleUnitCubic') === 0)[0];
console.log( onecl );
//And we just want to numeric part at the end
const thenumber = onecl.split('-')[1];
//So now the id where the total will be put is
const id = ['#totalCubic', thenumber].join('-');
//or const id = `#totalCubic-${thenumber}`;
/*determine the id of span to update
const id = ['#totalCubic',$('td[class*=singleUnitCubic]',this).attr('class').split(' ')
.filter(c => c.indexOf('singleUnitCubic') === 0)[0]
.split('-')[1]].join('-');*/
//get this total
const total = $('td[class*=singleUnitCubic]', this)
.map((i,td) => +td.textContent).get()
.reduce((acc, cur) => acc += cur, 0);
//now update the dom
$(id).text( total.toFixed(3) );
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td class="p-0 singleUnitCubic-13">
12.600
</td>
</tr>
<tr>
<td class="p-0 singleUnitCubic-13">
4.000
</td>
</tr></tbody>
</table>
Total: <span id="totalCubic-13"></span>
<table>
<tbody>
<tr>
<td class="p-0 singleUnitCubic-69">
4.230
</td>
</tr>
<tr>
<td class="p-0 singleUnitCubic-69">
3.000
</td>
</tr>
</tbody>
</table>
Total: <span id="totalCubic-69"></span>
Upvotes: 0
Reputation: 36
When making your td element you could take the id out of your classes and make it it's own attribute using data attributes.
Something like this:
<td data-table-id={{$container->id}} class="p-0 singleUnitCubic">
{{$item->prettyDecimal('total_cubic')}}
</td>
Then change your total to have the same attribute. Also change it's id to a class.
Total: <span data-table-id={{$container->id}} class="totalCubic">16.600</span>
Then you can get a node list of of all your totalCubic elements. Loop over it and pass each singleUnitCubic with matching data-table-id attribute to your sum function. Then update totalCubic.
Here's a working JSFiddle Example.
Upvotes: 1