After an ajax call, results is returned in success, then:
var the_data = results;
var buildHTML = [];
buildHTML.push("<tr><td>Department</td><td>Count</td><td>Value</td>");
for (var i = 0; i < the_data.length; i++) {
buildHTML.push("<tr><td>" + the_data[i].department + "</td><td>" + the_data[i].count + "</td><td>£" + the_data[i].value + "</td>");
}
$('.portlet-content').empty().append("<table>" + buildHTML.join('</tr>') + "</table>");
Which builds something like:
<table>
<tr>
<td>
Department
</td>
<td>
Count
</td>
<td>
Value
</td>
</tr>
<tr>
<td>
Marketing
</td>
<td>
10
</td>
<td>
£100,000
</td>
</tr>
<tr>
<td>
Information Technology
</td>
<td>
20
</td>
<td>
£1,000,000
</td>
</tr>
</table>
I know how to add another final row at the bottom of this table, but in that row, I want to display totals, i.e. a total of the count and a total of the value, e.g:
<table>
<tr>
<td>
Department
</td>
<td>
Count
</td>
<td>
Value
</td>
</tr>
<tr>
<td>
Marketing
</td>
<td>
10
</td>
<td>
£100,000
</td>
</tr>
<tr>
<td>
Information Technology
</td>
<td>
20
</td>
<td>
£1,000,000
</td>
</tr>
<tr>
<td>
Total
</td>
<td>
30
</td>
<td>
£1,100,000
</td>
</tr>
</table>
How can this be done at clientside?
Here is a generic solution that will work for any table with a tfoot and tbody:
$("table tfoot td").each(function(columnIndex) {
var totalsElement = $(this);
if (totalsElement.hasClass("sumTotal")) {
var sum = 0.0;
totalsElement.parents("table").find("tbody tr").each(function() {
sum += parseFloat($(this).children("td").eq(columnIndex).html());
});
totalsElement.html(sum);
}
});
You need to mark the computed footer cells with "sumTotal" CSS class. To keep it simple I had to remove the pound characters from the table but it works:
http://jsfiddle.net/fRdpJ/47/
You could simply amend the for loop in your code to get the sums.
...
// vars for sum
var the_count = 0, the_sum = 0;
for (var i = 0; i < the_data.length; i++) {
the_count += the_data[i].count;
the_sum += the_data[i].value;
buildHTML.push("<tr><td>" + the_data[i].department + "</td><td>" + the_data[i].count + "</td><td>£" + the_data[i].value + "</td>");
}
buildHTML.push("<tr><td>Total</td><td>" + the_count + "</td><td>" + the_sum + "</td>");
...
add a class="Count" on the TD for which you want to calculate count and then calculate count using JQuery like this:
http://jsfiddle.net/sv2dg/13/
Related
I have this HTML Code from Invoice:-
<tr>
<td colspan="3" class="blank"></td>
<td colspan="2" class="total-line">Subtotal Rs.</td>
<td td class="total-value">
<textarea id="subtotal" name="i_subt" readonly="readonly"></textarea>
</td>
</tr>
<tr>
<td colspan="3" class="blank"></td>
<td colspan="2" class="total-line">CGST (2.5%) Rs.</td>
<td td class="total-value">
<textarea id="cgst" name="i_cgst">.00</textarea>
</td>
</tr>
<tr>
<td colspan="3" class="blank"></td>
<td colspan="2" class="total-line">SGST (2.5%) Rs.</td>
<td td class="total-value">
<textarea id="sgst" name="i_sgst">.00</textarea>
</td>
</tr>
<tr>
<td colspan="3" class="blank"></td>
<td colspan="2" class="total-line">Total Rs. </td>
<td class="total-value">
<textarea id="total" name="i_ttl" readonly="readonly"></textarea>
</td>
</tr>
i have this code, I want too add 2 taxes namely CGST (2.5%) & SGST (2.5%) in subtotal...
function update_total() {
var total = 0;
$('.price').each(function(i){
price = $(this).html().replace("$","");
if (!isNaN(price)) total += Number(price);
});
total = roundNumber(total,2);
$('#subtotal').html(total);
//NEED some Code here to add CGST & SGST to Total
$('#total').html(total);
update_balance();
}
My Code is adding "Qty * Unit Price = Item total" of each item in Subtotal Perfectly. I need some code to add CGST * SGST in Sub-Total to make Total.
Use the equation (total * 2.5)/100 to find GST # 2.5%.
See below code to find the GST of Subtotal and add it to total
function update_total() {
var total = 0;
var gst = 0;
$('.price').each(function(i){
price = $(this).html().replace("$","");
if (!isNaN(price)) total += Number(price);
});
total = roundNumber(total,2);
$('#subtotal').html(total);
//NEED some Code here to add CGST & SGST to Total
gst = roundNumber((total * 2.5)/100,2);
$('#cgst').html(gst);
$('#sgst').html(gst);
$('#total').html(total + gst);
update_balance();
}
I'm making a total and subtotal table using jQuery but I get a lot of problems. The first problem, when I reload this page, the total and subtotals display NaN even though the values from the input have been entered by default.
The second problem, data in the second row and so on, still takes the price on the first row only.
What I want:
I want the total and subtotal to be calculated automatically at the
beginning and can be changed in the future.
I want each Total to
calculate the price of each row
This is my code:
$(document).ready(function () {
$counter = 1;
$('table#invoiceitems').on('keyup', '.quantity , .price',function () {
UpdateTotals(this);
});
$counter = 1;
CalculateSubTotals();
CalculateTotal();
});
function UpdateTotals(elem) {
// This will give the tr of the Element Which was changed
var $container = $(elem).parent().parent();
var quantity = $container.find('.quantity').val();
var price = $('.price').html();
var subtotal = parseInt(quantity) * parseFloat(price);
$container.find('.subtotal').text(subtotal.toFixed(2));
CalculateTotal();
}
function CalculateSubTotals() {
// Calculate the Subtotals when page loads for the
// first time
var lineTotals = $('.subtotal');
var quantity = $('.quantity');
var price = $('.price').html();
$.each(lineTotals, function (i) {
var tot = parseInt($(quantity[i]).val()) * parseFloat($(price[i]).val());
$(lineTotals[i]).text(tot.toFixed(2));
});
}
function CalculateTotal() {
// This will Itearate thru the subtotals and
// claculate the grandTotal and Quantity here
var lineTotals = $('.subtotal');
var quantityTotal = $('.quantity');
var grandTotal = 0.0;
var totalQuantity = 0;
$.each(lineTotals, function (i) {
grandTotal += parseFloat($(lineTotals[i]).text());
totalQuantity += parseInt($(quantityTotal[i]).val())
});
$('.totalquantity').text(totalQuantity);
$('.grandtotal').text(parseFloat(grandTotal).toFixed(2));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table border="1" id="invoiceitems">
<thead>
<tr>
<td><strong>Paper</strong>
</td>
<td><strong>Price</strong>
</td>
<td><strong>Quantity</strong>
</td>
<td><strong>Total</strong>
</td>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="3"><strong>SUBTOTAL</strong>
</td>
<td>
<label class="grandtotal"></label>
</td>
</tr>
</tfoot>
<tbody>
<tr>
<td>
Glossy Paper A5
</td>
<td>
<span class="price">15000</span>
</td>
<td>
<input type="text" name="item[1][quantity]" class="quantity" value="1"/>
</td>
<td>
<label class="subtotal"></label>
</td>
</tr>
<tr>
<td>
Glossy Paper A5
</td>
<td>
<span class="price">20000</span>
</td>
<td>
<input type="text" name="item[1][quantity]" class="quantity" value="1"/>
</td>
<td>
<label class="subtotal"></label>
</td>
</tr>
</tbody>
</table>
Inside CalculateSubTotals, price is a string:
var price = $('.price').html();
so
$(price[i]).val()
doesn't make sense - it's a plain string already, and can't be meaningfully wrapped in jQuery.
If you want to access individual .price elements, then use just $('.price').
Also, the .prices are spans, not inputs - to get the text in a span, you should use .text(). Only use .val() to get text from input-like elements, such as from input and textarea:
var price = $('.price');
// ...
var tot = parseInt($(quantity[i]).val()) * parseFloat($(price[i]).text());
// ^^^^^^^
The same fix needs to be made to your UpdateTotals function.
$(document).ready(function() {
$counter = 1;
$('table#invoiceitems').on('keyup', '.quantity , .price', function() {
UpdateTotals(this);
});
$counter = 1;
CalculateSubTotals();
CalculateTotal();
});
function UpdateTotals(elem) {
// This will give the tr of the Element Which was changed
var $container = $(elem).parent().parent();
var quantity = $container.find('.quantity').val();
var price = $container.find('.price').text();
var subtotal = parseInt(quantity) * parseFloat(price);
$container.find('.subtotal').text(subtotal.toFixed(2));
CalculateTotal();
}
function CalculateSubTotals() {
// Calculate the Subtotals when page loads for the
// first time
var lineTotals = $('.subtotal');
var quantity = $('.quantity');
var price = $('.price');
$.each(lineTotals, function(i) {
var tot = parseInt($(quantity[i]).val()) * parseFloat($(price[i]).text());
$(lineTotals[i]).text(tot.toFixed(2));
});
}
function CalculateTotal() {
// This will Itearate thru the subtotals and
// claculate the grandTotal and Quantity here
var lineTotals = $('.subtotal');
var quantityTotal = $('.quantity');
var grandTotal = 0.0;
var totalQuantity = 0;
$.each(lineTotals, function(i) {
grandTotal += parseFloat($(lineTotals[i]).text());
totalQuantity += parseInt($(quantityTotal[i]).val())
});
$('.totalquantity').text(totalQuantity);
$('.grandtotal').text(parseFloat(grandTotal).toFixed(2));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table border="1" id="invoiceitems">
<thead>
<tr>
<td><strong>Paper</strong>
</td>
<td><strong>Price</strong>
</td>
<td><strong>Quantity</strong>
</td>
<td><strong>Total</strong>
</td>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="3"><strong>SUBTOTAL</strong>
</td>
<td>
<label class="grandtotal"></label>
</td>
</tr>
</tfoot>
<tbody>
<tr>
<td>
Glossy Paper A5
</td>
<td>
<span class="price">15000</span>
</td>
<td>
<input type="text" name="item[1][quantity]" class="quantity" value="1" />
</td>
<td>
<label class="subtotal"></label>
</td>
</tr>
<tr>
<td>
Glossy Paper A5
</td>
<td>
<span class="price">20000</span>
</td>
<td>
<input type="text" name="item[1][quantity]" class="quantity" value="1" />
</td>
<td>
<label class="subtotal"></label>
</td>
</tr>
</tbody>
</table>
The problem is, You already got content of price in line var price = $('.price').html(); Then why are you trying to get value in this line $(price[i]).val() ?
There is no value key to get, And input fields only have value attribute.
Solution is,
var price = $('.price');
AND
var tot = parseInt($(quantity[i]).val()) * parseFloat($(price[i]).text());
$(document).ready(function () {
$counter = 1;
$('table#invoiceitems').on('keyup', '.quantity , .price',function () {
UpdateTotals(this);
});
$counter = 1;
CalculateSubTotals();
CalculateTotal();
});
function UpdateTotals(elem) {
// This will give the tr of the Element Which was changed
var $container = $(elem).parent().parent();
var quantity = $container.find('.quantity').val();
var price = $('.price').html();
var subtotal = parseInt(quantity) * parseFloat(price);
$container.find('.subtotal').text(subtotal.toFixed(2));
CalculateTotal();
}
function CalculateSubTotals() {
// Calculate the Subtotals when page loads for the
// first time
var lineTotals = $('.subtotal');
var quantity = $('.quantity');
var price = $('.price');
$.each(lineTotals, function (i) {
var tot = parseInt($(quantity[i]).val()) * parseFloat($(price[i]).text());
$(lineTotals[i]).text(tot.toFixed(2));
});
}
function CalculateTotal() {
// This will Itearate thru the subtotals and
// claculate the grandTotal and Quantity here
var lineTotals = $('.subtotal');
var quantityTotal = $('.quantity');
var grandTotal = 0.0;
var totalQuantity = 0;
$.each(lineTotals, function (i) {
grandTotal += parseFloat($(lineTotals[i]).text());
totalQuantity += parseInt($(quantityTotal[i]).val())
});
$('.totalquantity').text(totalQuantity);
$('.grandtotal').text(parseFloat(grandTotal).toFixed(2));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table border="1" id="invoiceitems">
<thead>
<tr>
<td><strong>Paper</strong>
</td>
<td><strong>Price</strong>
</td>
<td><strong>Quantity</strong>
</td>
<td><strong>Total</strong>
</td>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="3"><strong>SUBTOTAL</strong>
</td>
<td>
<label class="grandtotal"></label>
</td>
</tr>
</tfoot>
<tbody>
<tr>
<td>
Glossy Paper A5
</td>
<td>
<span class="price">15000</span>
</td>
<td>
<input type="text" name="item[1][quantity]" class="quantity" value="1"/>
</td>
<td>
<label class="subtotal"></label>
</td>
</tr>
<tr>
<td>
Glossy Paper A5
</td>
<td>
<span class="price">20000</span>
</td>
<td>
<input type="text" name="item[1][quantity]" class="quantity" value="1"/>
</td>
<td>
<label class="subtotal"></label>
</td>
</tr>
</tbody>
</table>
I am trying to build a table that will allow users to change the value of a cell(s) and then "submit" that data
to a JavaScript (only please) method that turns the tables data into a json dataset.
I started by trying to updated the value of just one field. QTY in this case. I am able to loop over the table and get the static values, but I am not able to catch the user input value.
question: What is a JavaScript only (if possible) way to capture user change(able) values from a table?
function updateQTY() {
//getData from table
//gets table
var lines = "";
var oTable = document.getElementById('items');
//gets rows of table
var rowLength = oTable.rows.length;
var line = "";
//loops through rows, skips firts row/header
for (i = 1; i < rowLength; i++) {
//gets cells of current row
var oCells = oTable.rows.item(i).cells;
var qty = oCells.item(2).innerHTML;
//alert("qty: " + wty);
qty = qty.substr(oCells.item(2).innerHTML.indexOf('value=') + 7);
qty = qty.substr(0, qty.indexOf('" class='));
//alert(qty);
line = line +
'{ "item": "' + oCells.item(0).innerHTML + '",' +
' "discription": "' + oCells.item(1).innerHTML + '",' +
' "qty": "' + qty + '"},'
}
//alert(line);
var jsonData = JSON.parse('[' + line + '{"quickwayto":"dealwith,leftbyloop"}]');
alert("lines: " + JSON.stringify(jsonData));
}
<form action='#'>
<table class='mdl-data-table mdl-js-data-table' id='items'>
<thead>
<tr>
<th>item</th>
<th>discription</th>
<th>QTY</th>
</tr>
</thead>
<tbody>
<tr>
<td class='mdl-data-table__cell--non-numeric'> widget_1 </td>
<td class='mdl-data-table__cell--non-numeric'>it's fun</td>
<td>
<div class='mdl-textfield mdl-js-textfield'><input type='text' name='qty1' id='value1' value='5' class='mdl-textfield__input'></div>
</td>
</tr>
<tr>
<td class='mdl-data-table__cell--non-numeric'> widget_2 </td>
<td class='mdl-data-table__cell--non-numeric'>it's super fun</td>
<td>
<div class='mdl-textfield mdl-js-textfield'><input type='text' name='qty2' id='value2' value='5' class='mdl-textfield__input'></div>
</td>
</tr>
</tbody>
</table>
<div>
<input type='button' value='update' onclick='updateQTY()' class='mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect'>
</div>
</form>
THANK YOU
Instead of selecting the entire td element, retrieve only what you really need using querySelector (or use jQuery if possible). Find the input element and access the value, it's a lot easier than doing all of that unecessary parsing of the inner html of the entire cell.
function updateQTY() {
//getData from table
//gets table
var lines = "";
var oTable = document.getElementById('items');
//gets rows of table
var rowLength = oTable.rows.length;
var line = "";
//loops through rows, skips firts row/header
for (i = 1; i < rowLength; i++) {
//gets cells of current row
var oCells = oTable.rows.item(i).cells;
var qty = oCells.item(2).querySelector(".mdl-textfield__input").value;
line = line +
'{ "item": "' + oCells.item(0).innerHTML + '",' +
' "discription": "' + oCells.item(1).innerHTML + '",' +
' "qty": "' + qty + '"},'
}
//alert(line);
var jsonData = JSON.parse('[' + line + '{"quickwayto":"dealwith,leftbyloop"}]');
alert("lines: " + JSON.stringify(jsonData));
}
<form action='#'>
<table class='mdl-data-table mdl-js-data-table' id='items'>
<thead>
<tr>
<th>item</th>
<th>discription</th>
<th>QTY</th>
</tr>
</thead>
<tbody>
<tr>
<td class='mdl-data-table__cell--non-numeric'> widget_1 </td>
<td class='mdl-data-table__cell--non-numeric'>it's fun</td>
<td>
<div class='mdl-textfield mdl-js-textfield'><input type='text' name='qty1' id='value1' value='5' class='mdl-textfield__input'></div>
</td>
</tr>
<tr>
<td class='mdl-data-table__cell--non-numeric'> widget_2 </td>
<td class='mdl-data-table__cell--non-numeric'>it's super fun</td>
<td>
<div class='mdl-textfield mdl-js-textfield'><input type='text' name='qty2' id='value2' value='5' class='mdl-textfield__input'></div>
</td>
</tr>
</tbody>
</table>
<div>
<input type='button' value='update' onclick='updateQTY()' class='mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect'>
</div>
</form>
You need to use document.getElementById('value2').value instead of .innerHTML.indexOf('value=')
You're making yourself a lot of work here. You have a table. All you need to do is convert that to JSON. I would suggest you look at the library below that does that in around one line of native java-script.
http://www.developerdan.com/table-to-json/
I have a div with the ID="ranking" and I'd like to put there some info of a JavaScript array with a table where every row has tow columns: one for dados[i][25] and other for dados[i][26].
My code is this:
function dadosRanking(dados){
document.getElementById("ranking").innerHTML += '<table class="table"><tr><td valign="middle" class="question" colspan=2><h1>RANKING (+ PONTOS)</h1></td></tr><tr><td>PONTOS</td><td>UTILIZADOR</td></tr>'
for(var i=1;i<6;i++)
{
document.getElementById("ranking").innerHTML += '<tr><td>' + dados[i][25] + '</td><td>' + dados[i][26] + '</td></tr>';
}
document.getElementById("ranking").innerHTML += '</table>';
}
The code I expect was this:
<table class="table">
<tr>
<td valign="middle" class="question" colspan=2>
<h1>RANKING (+ PONTOS)</h1>
</td>
</tr>
<tr>
<td>PONTOS</td>
<td>UTILIZADOR</td>
</tr>
<tr>
<td>
100
</td>
<td>
Username
</td>
</tr>
</table>
However, the HTML code script write is this:
<table class="table">
<tr>
<td valign="middle" class="question" colspan=2>
<h1>RANKING (+ PONTOS)</h1>
</td>
</tr>
<tr>
<td>PONTOS</td>
<td>UTILIZADOR</td>
</tr>
</table>
"100Username"
Everytime you update innerHTML the browser will parse it and render it, to do that it will also try to 'fix' your HTML. This can have unintended consequences. Instead of pushing to innerHTML with a partial table definition, collect the HTML in a separate value and push to innerHTML once.
function dadosRanking(dados){
var s = "";
s += '<table class="table"><tr><td valign="middle" class="question" colspan=2><h1>RANKING (+ PONTOS)</h1></td></tr><tr><td>PONTOS</td><td>UTILIZADOR</td></tr>'
for(var i=1;i<6;i++) {
s += '<tr><td>' + dados[i][25] + '</td><td>' + dados[i][26] + '</td></tr>';
}
s += '</table>';
document.getElementById("ranking").innerHTML += s;
}
After
document.getElementById("ranking").innerHTML += '<table class="table"><tr><td valign="middle" class="question" colspan=2><h1>RANKING (+ PONTOS)</h1></td></tr><tr><td>PONTOS</td><td>UTILIZADOR</td></tr>'
innerHTML becomes:
<table class="table">
<tr><td valign="middle" class="question" colspan=2><h1>RANKING (+ PONTOS)</h1></td></tr>
<tr><td>PONTOS</td><td>UTILIZADOR</td></tr>
</table>
Note that the table has been closed!
After
document.getElementById("ranking").innerHTML += '<tr><td>foo</td><td>bar</td></tr>';
innerHTML becomes
<table>..</table>
foobar
<tr> and <td> are not valid outside of a table context so they're removed.
After
document.getElementById("ranking").innerHTML += '</table>';
innerHTML doesn't change because </table> doesn't do anything, there is no table to close.
It's part of the larger task. Why is the problem Nan and how to solve it? The table is added together elements from several pools <input> which elemenatymi table. All code is summed up in the table of size k / d.
Why is the problem Nan and how to solve it?
function licz(tableID){
var table = document.getElementById(tableID);
var k, d, s=0, temp;
var i = table.rows.length;
for(k=1; k<=i; k++){
for(d=0; d<2; d++){
temp = parseFloat(document.getElementById(tableID).rows[k].cells[d].innerHTML);
alert(temp);
s=s+temp;
}
document.getElementById(tableID).rows[k].cells[d].innerHTML = s;
}
}
<form name="roz" action="">
<table id="tyg" class="product_values" style="width: 20%" border=1>
<tr>
<td> Pon </td>
<td> Wt </td>
<td> Sum </td>
</tr><tr>
<td> <input type="number" name="inp_a" ></td>
<td> 4 </td>
<td></td>
</table>
</form>
<button onclick="licz('tyg')">go</button>
This is not right way for getting value from child elements you should do something like this :
JavaScript:
function licz(tableID){
var table = document.getElementById(tableID);
var k, d, temp;
var i = table.rows.length;
for (k = 1; k <= i; k++) {
for (d = 0; d < 2; d++) {
if (d == 0) {
temp = parseFloat(document.getElementById(tableID).rows[k].cells[d].childNodes[1].value);
}
if (d == 1) {
temp = temp + parseFloat(document.getElementById(tableID).rows[k].cells[d].innerHTML);
}
}
document.getElementById(tableID).rows[k].cells[d].innerHTML = temp;
document.getElementById('num').v
}
}
HTML:
<table id="tyg" class="product_values" style="width: 20%" border=1>
<tr>
<td> Pon </td>
<td> Wt </td>
<td> Sum </td>
</tr>
<tr>
<td> <input id = 'num' type="number" name="inp_a" ></td>
<td> 4 </td>
<td></td>
</tr>
</table>
well... it's a good question. You should read DOM for knowing more about this.