Accessing cells in dynamically generated tables with jQuery - javascript

I have a file where php dynamically generates a bunch of tables and each of these tables also has a dynamically generated number of rows.
<?php foreach($trees as $tree): ?>
<div class="tree">
<table>
<thead>
<tr>
<th>Fruit</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<?php foreach($tree as $fruit => $fruitPrice) ?>
<tr>
<td><?php echo $fruit; ?></td>
<td><?php echo $fruitPrice; ?></td>
</tr>
<?php endforeach; ?>
<tr>
<td>Total:</td>
<td class="totalPrice"></td>
</tr>
</tbody>
<table>
</div>
<?php endforeach; ?>
A resulting table would look something like this (but there would be close to 100 of those tables):
<div class="tree">
<table>
<thead>
<tr>
<th>Fruit</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>Apple</td>
<td>$1.99</td>
</tr>
<tr>
<td>Banana</td>
<td>$1.29</td>
</tr>
<tr>
<td>Peach</td>
<td>$2.25</td>
</tr>
<tr>
<td>Total:</td>
<td class="totalPrice"></td>
</tr>
</tbody>
<table>
</div>
How would I access the <td>s using jQuery to sum total of the values and display the total price in .totalPrice?
The table being dynamic irritates me here.
I tried to write a loop within a loop, but couldn't get it to access the correct fields.

This should do it:
<?php foreach($trees as $tree): ?>
<div class="tree">
<table>
<thead>
<tr>
<th>Fruit</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<?php foreach($tree as $fruit => $fruitPrice) ?>
<tr>
<td><?php echo $fruit; ?></td>
<td id="fruitPrice"><?php echo $fruitPrice; ?></td>
</tr>
<?php endforeach; ?>
<tr>
<td>Total:</td>
<td class="totalPrice"></td>
</tr>
</tbody>
<table>
</div>
<?php endforeach; ?>
<script>
var totalPrice = null;
$("#fruitPrice").each(function()
{
totalPrice += $(this).text();
$(".totalPrice").text(totalPrice);
});
</script>

$("table").each(function () {
var totalSum = 0;
//find all tr in current table
var $dataRow = $(this).find('tbody tr');
$dataRow.each(function () {
$(this).find('td:nth-child(2)').each(function (i) {
// remove currency symbol
totalSum += parseFloat($(this).text().replace("$", ""));
});
});
var totalFixedValue = parseFloat(totalSum).toFixed(2);
//find totalPrice td and update with result
$(this).find(".totalPrice").html(totalFixedValue);
});

Give your price a class attribute to make easy the retrieve of values :
<tr>
<td><?php echo $fruit; ?></td>
<td class="price"><?php echo $fruitPrice; ?></td>
</tr>
Then get the value of price of every table :
$('table').each(function(){
var total = 0;
$('.price',this).each(function(){
total += parseFloat($(this).text().replace('$',''));
})
$('.totalPrice',this).text('$'+total);
})
Hope this helps.
$('table').each(function(){
var total = 0;
$('.price',this).each(function(){
total += parseFloat($(this).text().replace('$',''));
})
$('.totalPrice',this).text('$'+total);
})
table,table td{
border: 1px solid;
}
.totalPrice{
color: #FFF;
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="tree">
<table>
<thead>
<tr>
<th>Fruit</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>Apple</td>
<td class='price'>$1.99</td>
</tr>
<tr>
<td>Banana</td>
<td class='price'>$1.29</td>
</tr>
<tr>
<td>Peach</td>
<td class='price'>$2.25</td>
</tr>
<tr>
<td>Total:</td>
<td class="totalPrice"></td>
</tr>
</tbody>
</table>
<br>
<table>
<thead>
<tr>
<th>Fruit</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>Peach</td>
<td class='price'>$1</td>
</tr>
<tr>
<td>Banana</td>
<td class='price'>$3.9</td>
</tr>
<tr>
<td>Total:</td>
<td class="totalPrice"></td>
</tr>
</tbody>
</table>
<br>
<table>
<thead>
<tr>
<th>Fruit</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>Banana</td>
<td class='price'>$1.96</td>
</tr>
<tr>
<td>Apple</td>
<td class='price'>$6.25</td>
</tr>
<tr>
<td>Total:</td>
<td class="totalPrice"></td>
</tr>
</tbody>
</table>
</div>

Related

Trying to get value from table on click

I have a table like this:
<table class="table" id = "posts_table">
<caption><h2>cars</h2></caption>
<tr class="success">
<th style="text-align:center"> post_id
<th style="text-align:center"> autor
<th style="text-align:center"> title
</tr>
<?php
$cursor = $MySQLdb->prepare("SELECT * FROM posts WHERE topic_id=:topic_id");
$cursor->execute( array(":topic_id"=>"1") ); //לשנות
foreach ($cursor->fetchAll() as $obj): ?>
<tr>
<td style="text-align:center"><? echo $obj['post_id'] ?></td>
<td style="text-align:center"><? echo $obj['full_name']?></td>
<td style="text-align:center"><? echo $obj['post_title']?></td>
</tr>
<? endforeach; ?>
</table
I want to create function that when u click on the title im getting the post_id for this raw. What should I do to make it happen?
So i try to do this code and it works:
<table class="table" id = "posts_table">
<caption><h2>cars</h2></caption>
<tr class="success">
<th style="text-align:center"> post_id </th>
<th style="text-align:center"> autor </th>
<th style="text-align:center"> title </th>
</tr>
<?php
$cursor = $MySQLdb->prepare("SELECT * FROM posts WHERE topic_id=:topic_id");
$cursor->execute( array(":topic_id"=>"1") ); //לשנות
foreach ($cursor->fetchAll() as $obj): ?>
<tr>
<td class="post_id_c" style="text-align:center"><? echo $obj['post_id'] ?></td>
<td style="text-align:center"><? echo $obj['full_name']?></td>
<td style="text-align:center"><a class="click_title"><? echo $obj['post_title']?></a></td>
</tr>
<? endforeach; ?>
</table>
<script>
$(".click_title").click(function() {
var $item = $(this).closest("tr") // Finds the closest row <tr>
.find(".post_id_c") // Gets a descendent with class="nr"
.text();
console.log($item);
});
</script>

Grab every TD then format it to currency

i'm pretty new to JS and after searching through the web, docs, friends and another questions here on stackoverflow I've gotten until this point. Now I can't get pass it.
$(document).ready(function() {
var $table = $("table.valores");
if ($table.length > 0) {
var ValorTh = $("th.header:contains('Valor')");
var ValorColumnIndex = $(ValorTh).index();
var Valor_rows = $($table).find('tr');
$(Valor_rows).each(function() {
$(this).find('td').eq(ValorColumnIndex).toLocaleString('pt-BR',{style:'currency', currency: 'BRL'});
});
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="valores">
<thead><th class="header">Valor</th></thead>
<tbody>
<tr>
<td>15.00</td>
</tr>
<tr>
<td >16.00</td>
</tr>
<tr>
<td >17.00</td>
</tr>
<tr>
<td >18.00</td>
</tr>
<tr>
<td >19.00</td>
</tr>
<tr>
<td >20.00</td>
</tr>
</tbody>
</table>
I can't get the following to work and properly format the td's value :C
toLocaleString('pt-BR',{style:'currency', currency: 'BRL'});
You need to actually set the content of the tds. Now, you don't change the content of the elements. Try this:
$(document).ready(function() {
var $table = $("table.valores");
if ($table.length > 0) {
var ValorTh = $("th.header:contains('Valor')");
var ValorColumnIndex = $(ValorTh).index();
var Valor_rows = $($table).find('tr');
$(Valor_rows).each(function() {
var $td = $(this).find('td').eq(ValorColumnIndex);
var formatted = Number($td.text()).toLocaleString('pt-BR', {style:'currency', currency: 'BRL'});
$td.text(formatted); // <-- here, you need to set the value
});
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="valores">
<thead><th class="header">Valor</th></thead>
<tbody>
<tr>
<td>15.00</td>
</tr>
<tr>
<td >16.00</td>
</tr>
<tr>
<td >17.00</td>
</tr>
<tr>
<td >18.00</td>
</tr>
<tr>
<td >19.00</td>
</tr>
<tr>
<td >20.00</td>
</tr>
</tbody>
</table>
It's because toLocaleString is a prototype of Number and not string
$(document).ready(function() {
var $table = $("table.valores tbody");
$table.find("td").each(function(i,el){
try{
$(el).text(parseFloat($(el).text()).toLocaleString('pt-BR', {style:'currency', currency: 'BRL'}));
}catch(e){
//not a number
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="valores">
<thead><th class="header">Valor</th></thead>
<tbody>
<tr>
<td>15.00</td>
</tr>
<tr>
<td >16.00</td>
</tr>
<tr>
<td >17.00</td>
</tr>
<tr>
<td >18.00</td>
</tr>
<tr>
<td >19.00</td>
</tr>
<tr>
<td >20.00</td>
</tr>
</tbody>
</table>

How to get a running sum on HTML table?

I searching a solution for give the running sun to a editable html table, like a spreadsheet:
Hi here is a basic example of what you want using :
The HTML content editable property.
A css class to append a focusout event to the table cell.
A simple loop to sum all values when one value changes.
$('#tbodyTest >tr').on('focusout', 'td.editable', (e) => {
let target = $(e.target),
parent_row = $(e.target).closest('tr'),
previous_row = parent_row.prev();
setTimeout(() => {
if (!isNaN(target.text())) {
$('#tbodyTest').children('tr').each((i,e)=>{
$(e).find('td').last().text(Number($(e).find('td:eq(2)').text()) +Number($(e).prev().find('td').last().text()))
})
}else{
target.text("0");
parent_row.find('td').last().text("0");
$('#tbodyTest').children('tr').each((i,e)=>{
$(e).find('td').last().text(Number($(e).find('td:eq(2)').text()) +Number($(e).prev().find('td').last().text()))
})
}
})
})
.editable {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="test" border=1>
<thead>
<th>date</th>
<th>desc</th>
<th>cost</th>
<th>running sum</th>
</thead>
<tbody id="tbodyTest">
<tr>
<td>01-01-2019</td>
<td>a</td>
<td class="editable" contenteditable='true'>1000</td>
<td>1000</td>
</tr>
<tr>
<td>01-02-2019</td>
<td>a</td>
<td class="editable" contenteditable='true'></td>
<td></td>
</tr>
<tr>
<td>01-03-2019</td>
<td>a</td>
<td class="editable" contenteditable='true'></td>
<td></td>
</tr>
<tr>
<td>01-04-2019</td>
<td>a</td>
<td class="editable" contenteditable='true'></td>
<td></td>
</tr>
</tbody>
</table>
Keep in mind that this is a basic example and you will probably add more stuff according to your needs since your ask is simple as well.
Hope it helps
Anyone still looking to this.
$('tr').each(function(index, el) {
if (index == 0) {
$(this).find('.running-balance').text($(this).find('.amount').text());
} else {
var prevRow = $(this).prev();
var prevBalance = Number(prevRow.find('.running-balance').text());
var currentAmount = Number($(this).find('.amount').text());
var newBalance = prevBalance + currentAmount;
$(this).find('.running-balance').text(newBalance.toFixed(2));
}
});
td,
th {
border: 1px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Description</th>
<th>Amount</th>
<th>Running Balance</th>
</tr>
</thead>
<tbody>
<tr>
<td>a</td>
<td class="amount">100</td>
<td class="running-balance"></td>
</tr>
<tr>
<td>b</td>
<td class="amount">150</td>
<td class="running-balance"></td>
</tr>
<tr>
<td>c</td>
<td class="amount">125</td>
<td class="running-balance"></td>
</tr>
<tr>
<td>d</td>
<td class="amount">205</td>
<td class="running-balance"></td>
</tr>
<tr>
<td>e</td>
<td class="amount">50</td>
<td class="running-balance"></td>
</tr>
</tbody>
</table>

How can I find the index of row in the table

I have one html table which consists of a button on each row. When I click on that button I want to get the index of the row. With my code I am getting the index value but it starts with 1 instead of 0. In other examples I saw that row index is starting from value "0", but in my case it starts with "1". Can anybody help me where I did mistake.
Here is my table.
<div class="table-style table-municipality table-edit-community-view">
<table id="sum_table">
<tr class="titlerow">
<th>S.N.</th>
<th>Community</th>
<th>Address</th>
<th>Area</th>
<th>Estimated</th>
<th>Total</th>
<th>Action</th>
</tr>
<?
$sn = 1;
while($result= mysql_fetch_row($res))
{
?>
<tr id="<?php echo $result[0];?>">
<td align="center"><? echo $sn++; ?></td>
<td align="center"><? echo $result[1] ?></td>
<td align="center"><? echo $result[2] ?></td>
<td align="center" class="rowDataSd"><? echo $result[3] ?></td>
<td align="center" class="rowDataSd"><? echo $result[4] ?></td>
<td align="center" class="rowDataSd"><? echo $result[5] ?></td>
<td>
<button class="test">Test</button>
</td>
</tr>
<?
}
?>
</table>
</div>
script:
$(".test").click(function(){
console.log("name: ", $(this).closest('td').parent()[0].sectionRowIndex);
});
You are getting index starting by 1 because you have one tr element in start of table for headers. You can -1 from returned index to get index starting with 0.
$(".test").click(function(){
console.log("name: ", $(this).closest('tr').index()-1);
});
Or find the current rows index in collection of desired rows excluding headers row:
$(".test").click(function(){
console.log("name: ", $('#sum_table tr:not(.titlerow)').index($(this).closest('tr')));
});
The index function tells you that.
$(".test").click(function(){
console.log("name: ", $(this).closest('td').parent().index());
});
Also note that you can probably just use .closest('tr') rather than .closest('td').parent().
$(".test").click(function(){
console.log("name: ", $(this).closest('tr').index());
});
Note, though, that your title row is in the same parent as your data rows, and so will occup the index = 0 position. If you want to avoid that, put it in its own thead with the data rows in a tbody:
<div class="table-style table-municipality table-edit-community-view">
<table id="sum_table">
<thead><!-- *** Note -->
<tr class="titlerow">
<th>S.N.</th>
<th>Community</th>
<th>Address</th>
<th>Area</th>
<th>Estimated</th>
<th>Total</th>
<th>Action</th>
</tr>
</thead><!-- *** Note -->
<tbody><!-- *** Note -->
<?
$sn = 1;
while($result= mysql_fetch_row($res))
{
?>
<tr id="<?php echo $result[0];?>">
<td align="center"><? echo $sn++; ?></td>
<td align="center"><? echo $result[1] ?></td>
<td align="center"><? echo $result[2] ?></td>
<td align="center" class="rowDataSd"><? echo $result[3] ?></td>
<td align="center" class="rowDataSd"><? echo $result[4] ?></td>
<td align="center" class="rowDataSd"><? echo $result[5] ?></td>
<td>
<button class="test">Test</button>
</td>
</tr>
<?
}
?>
</tbody><!-- *** Note -->
</table>
</div>
It's generally best practice to use thead and tbody anyway.
$(".test").click(function() {
console.log("name: ", $(this).closest('tbody tr').index());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="table-style table-municipality table-edit-community-view">
<table id="sum_table">
<thead>
<tr class="titlerow">
<th>S.N.</th>
<th>Community</th>
<th>Address</th>
<th>Area</th>
<th>Estimated</th>
<th>Total</th>
<th>Action</th>
</tr>
</thead>
<tr>
<td align="center">1</td>
<td align="center">1</td>
<td align="center">1</td>
<td align="center" class="rowDataSd">1</td>
<td align="center" class="rowDataSd">1</td>
<td align="center" class="rowDataSd">1</td>
<td>
<button class="test">Test</button>
</td>
</tr>
<tr>
<td align="center">2</td>
<td align="center">2</td>
<td align="center">2</td>
<td align="center" class="rowDataSd">2</td>
<td align="center" class="rowDataSd">2</td>
<td align="center" class="rowDataSd">2</td>
<td>
<button class="test">Test</button>
</td>
</tr>
</table>
</div>
Use tr with index()

HTML table with rowspan reorder item drag and drop issue

my html code is
<table border='1px' id='sort'>
<thead>
<tr>
<th>SL</th>
<th>Sub Group</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan='3'>1</td>
<td rowspan='3'>Fruit</td>
<td>Mango</td>
</tr>
<tr>
<td>Orange</td>
</tr>
<tr>
<td>pineapple</td>
</tr>
<tr>
<td rowspan='2'>2</td>
<td rowspan='2'>Flower</td>
<td>Rose</td>
</tr>
<tr>
<td>sunflower</td>
</tr>
</tbody>
</table>
and js
var fixHelperModified = function(e, tr) {
var $originals = tr.children();
var $helper = tr.clone();
$helper.children().each(function(index) {
$(this).width($originals.eq(index).width())
});
return $helper;
},
updateIndex = function(e, ui) {
$('td.index', ui.item.parent()).each(function (i) {
$(this).html(i + 1);
});
};
$("#sort tbody").sortable({
helper: fixHelperModified,
stop: updateIndex
}).disableSelection();
I want to reorder only subgroup like fruit mango,orange or sunflower,rose not the main group in the table.
The working fiddle is http://jsfiddle.net/p6c814o6/. How to solve this issue. Thank you.
Try this:
I have updated your fiddle JsFiddle. Your html was wrong according to your code. You must check your new html.
Instead Of using rowspans you must go with nested tables to achieve it.
<table border='1px' id='sort'>
<thead>
<tr>
<th>SL</th>
<th>Sub Group</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td >1</td>
<td >Fruit</td>
<td><table>
<tr>
<td>Mango</td>
</tr>
<tr>
<td>Orange</td>
</tr>
<tr>
<td>pineapple</td>
</tr></td>
</tr>
</table>
<tr>
<td >2</td>
<td >Flower</td>
<td><table>
<tr>
<td>
Rose
</td>
</tr>
<tr>
<td>sunflower</td>
</tr>
</table>
</td>
</tbody>
</table>
Check out the updated fiddle. If this is what you need.
Hope this helps JsFiddleUpdated

Categories

Resources