Sum of <td> value from dynamic generated table based on checkbox attribute - javascript

I have been trying to find the sum of balance (column) of the selected checkbox as below
HTML
<h2>Sum of selected invoices is AED <div class="totalsum"></div></h2>
<table border="1" id="rcpt"><tr><th><input type="checkbox" onClick="selectAll(this),updateSum()" /></th><th>Invoice No.</th><th>Date</th><th>Balance</th></tr>
<tr>
<td><input type="checkbox" class="checkbox" name="select[]" value="2" onclick="updateSum()" /></td>
<td>INV-2020-0001</a></td>
<td>31-05-2020</td>
<td class="balance">56,842.50</td>
</tr>
<tr>
<td><input type="checkbox" class="checkbox" name="select[]" value="3" onclick="updateSum()" /></td>
<td>INV-2020-0002</a></td>
<td>10-06-2020</td>
<td class="balance">96,962.60</td>
</tr>
<tr>
<td><input type="checkbox" class="checkbox" name="select[]" value="4" onclick="updateSum()" /></td>
<td>INV-2020-0003</a></td>
<td>15-06-2020</td>
<td class="balance">100,251.20</td>
</tr>
</table>
PHP (Edit)
<?php
$query = 'QUERY';
$sql = mysqli_query($conn, $query);
while ($result = mysqli_fetch_array($sql)) {
$id = $result['id'];
$inv_no =$result['cinv_no'];
$inv_date = $result['cinv_date'];
$inv_bal = $result['cinv_bal'];
echo '<tr>';
echo '<td><input type="checkbox" class="checkbox" name="select[]" value="'.$id.'" onclick="updateSum()" /></td>';
echo '<td>'.$cinv_no.'</a></td>';
echo '<td>'.date("d-m-Y", strtotime($cinv_date)).'</td>';
echo '<td class="balance">'.number_format($cinv_bal,2).'</td>';
echo '</tr>';
}
?>
Javascript (JS + Jquery)
function selectAll(source) {
select = document.getElementsByName('select[]');
for(var i=0, n=select.length;i<n;i++) {
select[i].checked = source.checked;
}
}
function updateSum() {
var total = 0;
var select = $(".checkbox:checked");
var balance = $(".balance");
select.each(function() { total += parseFloat(balance.html().replace(/,/g, ''));})
$(".totalsum").html(total.toFixed(2));
}
Whenever I select a random checkbox, it adds the balance in order(first to last) rather than the selected balances
JSFiddle https://jsfiddle.net/cj19zban/

You need to find the .balance related to the checked checkbox.
function updateSum() {
var total = 0;
var select = $(".checkbox:checked");
select.each(function() {
// get the balance relative to the checked checkbox
const balance = select.parents('tr').find('.balance');
total += parseFloat(balance.html().replace(/,/g, ''));
})
$(".totalsum").text(total.toFixed(2));
}
However, this is somewhat inefficient. I would do something slightly different. You can store the relative balance as the value of the input.. which saves time figuring out which element to get it from.
const updateTotal = () => {
const total = $(".checkbox:checked")
.map((index, checkedCheckbox) => parseFloat(checkedCheckbox.dataset.value))
.toArray()
.reduce((acc, cur) => acc + cur, 0);
$('#totalsum').text(total.toFixed(2));
}
const toggleAll = (checked) => {
$('.checkbox').each((index, checkbox) => {
checkbox.checked = checked;
});
}
$('.checkbox').click(updateTotal);
$('#selectAll').click(function() {
toggleAll($(this).is(':checked'));
updateTotal();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1>Receipts</h1>
<h2>Sum of selected invoices is AED
<div id="totalsum">0.00</div>
</h2>
<table border="1" id="rcpt">
<tr>
<th><input id='selectAll' type="checkbox" /></th>
<th>Invoice No.</th>
<th>Date</th>
<th>Balance</th>
</tr>
<tr>
<td><input type="checkbox" class="checkbox" name="select[]" value="2" data-value="56842.50" /></td>
<td>INV-2020-0001</td>
<td>31-05-2020</td>
<td class="balance">56,842.50</td>
</tr>
<tr>
<td><input type="checkbox" class="checkbox" name="select[]" value="3" data-value="96962.60" /></td>
<td>INV-2020-0002</td>
<td>10-06-2020</td>
<td class="balance">96,962.60</td>
</tr>
<tr>
<td><input type="checkbox" class="checkbox" name="select[]" value="4" data-value="100251.20" /></td>
<td>INV-2020-0003</td>
<td>15-06-2020</td>
<td class="balance">100,251.20</td>
</tr>
</table>
I also removed some trailing </a> that seems to break your HTML.

Related

Select only checkboxes that are checked in a column

I have an html table that has 5 columns. 2 columns are checkboxes (entry and high) and the other 3 are data. I have 2 buttons, one is called entry and the other high. When a user clicks on the high button, I'm trying to check the column (high) only and get all that is checked, take those values and average them.
The same with entry, when the entry button is clicked, check only the checkboxes in column (entry) and take those values and average them.
So far I have a function to check both columns but not sure how to separately check and separate the columns to each button function only. I have tried the below, but the GetHigh function doesn't work.
Any points in the right direction would be appreciated!
Table
<td><input type="checkbox" class="entry" id="entry" value="{{$sup->entry}}" name="rows[]"></td>
<td><input type="checkbox" class="high" id="high" value="{{$sup->high}}" name="rows[]"></td>
<td><span style="color: #007E33">{{$sup->entry}} </span></td>
<td><span style="color: #007E33">{{$sup->high}} </span></td>
<td><span style="color: #007E33">{{$sup->days}} </span></td>
Buttons
<a href="#here" class="btn btn-primary btn-pill w-10" id="entry" onclick="GetEntry()">
Entry Average
</a>
<a href="#here" class="btn btn-primary btn-pill w-10" id="high" onclick="GetHigh()">
High Average
</a>
Javascript
function GetEntry() {
//Create an Array.
var selected = new Array();
//Reference the Table.
var supTable = document.getElementById("supTable");
//Reference all the CheckBoxes in Table. I WANT ONLY THE ENTRY COLUMN
var entry = supTable.getElementsByTagName("INPUT");
// Loop and push the checked CheckBox value in Array.
for (var i = 0; i < entry.length; i++) {
if (entry[i].checked) {
selected.push(entry[i].value);
}
}
// alert("Average: " + calculate(selected));
$(".text-message").text("Average: " + calculate(selected)).show();
}
function GetHigh() {
//Create an Array.
var selected = new Array();
//Reference the Table.
var supTable = document.getElementById("supTable");
//Reference all the CheckBoxes in Table. I WANT ONLY THE ENTRY COLUMN
var entry = supTable.getElementsByName("High");
// Loop and push the checked CheckBox value in Array.
for (var i = 0; i < high.length; i++) {
if (high[i].checked) {
selected.push(high[i].value);
}
}
// alert("Average: " + calculate(selected));
$(".text-message").text("Average: " + calculate(selected)).show();
}
getElementsByName is used to select HTML where their name="" attribute matches what you've entered, in this case 'High'. But your HTML in the example shows a different name.
You want to use querySelectorAll('high') to get all of the elements that have class="high" set.
You can use a css selector to get the cells of your table
const getCheckboxes = columnIndex =>document.querySelectorAll(`tbody td:nth-child(${columnIndex}) input:checked`);
Or add a common class and select by the class to the checkboxes
const getCheckboxes = className =>document.querySelectorAll(`tbody .${className}:checked`);
Basic example:
const getCheckedCheckboxesClassName = className => document.querySelectorAll(`tbody .${className}:checked`);
const getCheckedCheckboxesByIndex = columnIndex =>document.querySelectorAll(`tbody td:nth-child(${columnIndex}) input:checked`);
const sumValues = cbs => [...cbs].reduce((total, cb) => total + +cb.value, 0);
const getTotal = (group) => {
const cbs = getCheckedCheckboxesClassName(group);
const value = sumValues(cbs);
console.log(value);
}
const getTotalIndex = (index) => {
const cbs = getCheckedCheckboxesByIndex(index);
const value = sumValues(cbs);
console.log(value);
}
<button type="button" onclick="getTotal('low'); getTotalIndex(1)">low</button>
<button type="button" onclick="getTotal('high'); getTotalIndex(2)">high</button>
<table>
<tbody>
<tr>
<td><input class="low" type="checkbox" value="1" /></td>
<td><input class="high" type="checkbox" value="10" /></td>
</tr>
<tr>
<td><input class="low" type="checkbox" value="2" /></td>
<td><input class="high" type="checkbox" value="20" /></td>
</tr>
<tr>
<td><input class="low" type="checkbox" value="3" /></td>
<td><input class="high" type="checkbox" value="30" /></td>
</tr>
<tr>
<td><input class="low" type="checkbox" value="4" /></td>
<td><input class="high" type="checkbox" value="40" /></td>
</tr>
<tr>
<td><input class="low" type="checkbox" value="5" /></td>
<td><input class="high" type="checkbox" value="50" /></td>
</tr>
</tbody>
</table>

Use JavaScript to get value of the for each

I'm new using JavaScript. I need to get the value ${prdcts.precioUnidad} of the checked line. The idea is to set the total price in a dynamic way, so when the user checks or unchecks each line the value of total either adds the new value when checked, or subtracts the previous value when unchecked.
I tried to get the value using the getElement() methods, but I don't know how to access the value of the variable within that specific row.
This is the HTML:
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Ventas</title>
</head>
<body>
<center><h1>Venta de Productos</h1>
<form action="venta.htm" method="post">
<table id="tableID" border="4">
<tbody><tr>
<th>ID</th>
<th>Nombre</th>
<th>Valor</th>
<th>Comprado</th>
</tr>
<tr>
<td>2</td>
<td>Chupetin</td>
<td>5.0</td>
<td><input name="check" type="checkbox" value="2" label="2" path="prdcts"></td>
</tr>
<tr>
<td>3</td>
<td>Alfajor DDL</td>
<td>30.0</td>
<td><input name="check" type="checkbox" value="3" label="3" path="prdcts"></td>
</tr>
<tr>
<td>4</td>
<td>Sanguche Mila</td>
<td>60.0</td>
<td><input name="check" type="checkbox" value="4" label="4" path="prdcts"></td>
</tr>
</tbody></table>
<br>
<br>
<br>
<table border="4">
<tbody><tr>
<td>Total Compra: <input name="total" id="total" type="number" readonly="" value="0"></td>
</tr>
<tr>
<td>Monto Pagado: <input name="monto" id="monto" type="number" value="0"></td>
</tr>
<tr>
<td>Vuelto: <input name="vuelto" id="vuelto" type="number" readonly="" value="0"></td>
</tr>
<tr>
<td><input name="begin" onclick="calcularVuelto()" type="button" value="Calcular Vuelto"></td>
</tr>
</tbody></table>
<br>
<br>
<input name="clear" onclick="window.location.href = 'venta.htm'" type="button" value="Borrar venta">
<input name="begin" onclick="window.location.href = 'principal.htm'" type="button" value="Inicio">
<input name="confirm" type="submit" value="Confirmar Venta">
<br>
</form>
</center>
<script>
// Make it an Array with "Array.from" so we can use reduce() on it
var $$checkboxes = Array.from(document.querySelectorAll('input[name=check]')),
$total = document.getElementById('total');
// For each checkbox
$$checkboxes.forEach(function ($checkbox) {
// When its value changes, update total
$checkbox.addEventListener('change', updateTotal);
});
function updateTotal() {
// For each checkbox
alert("aca");
var total = $$checkboxes.reduce(function (sum, $checkbox) {
// If it's checked
alert("aca2")
if ($checkbox.checked) {
var price = $checkbox.parentNode.parentNode // parent <tr>
.querySelectorAll('td')[2].innerText.trim(); // remove spaces
// Add price to the sum
return sum + parseFloat(price);
} else {
// If it's not checked, just return the current sum
return sum;
}
}, 0);
$total.value = total.toFixed(2); // Always 2 decimals
}
function calcularVuelto() {
var total = document.getElementById("total").value;
var pago = document.getElementById("monto").value;
var fTotal = parseFloat(total);
var fPago = parseFloat(pago);
totalResta = fPago - fTotal;
document.getElementById("vuelto").value = totalResta;
}
</script>
</body></html>
You can use Array.prototype.reduce() to calculate the total:
// Make it an Array with "[].slice.call" so we can use reduce() on it
var $$checkboxes = [].slice.call(document.querySelectorAll('input[name=check]')),
$total = document.getElementById('total');
// For each checkbox
$$checkboxes.forEach(function ($checkbox) {
// When its value changes, update total
$checkbox.addEventListener('change', updateTotal);
});
function updateTotal() {
// For each checkbox
var total = $$checkboxes.reduce(function (sum, $checkbox) {
// If it's checked
if ($checkbox.checked) {
var price = $checkbox.parentNode.parentNode // parent <tr>
.querySelectorAll('td')[2].innerText.trim(); // remove spaces
// Add price to the sum
return sum + parseFloat(price);
} else {
// If it's not checked, just return the current sum
return sum;
}
}, 0);
$total.value = total.toFixed(2); // Always 2 decimals
}
<table border="4">
<tr><th>ID</th> <th>Nombre</th> <th>Valor</th> <th>Comprado</th> </tr>
<tr><td>x</td><td>X</td><td>5.99</td><td><input name="check" type="checkbox" value="x" label="X"/></td></tr>
<tr><td>y</td><td>Y</td><td>3.95</td><td><input name="check" type="checkbox" value="y" label="Y"/></td></tr>
<tr><td>z</td><td>Z</td><td>14.20</td><td><input name="check" type="checkbox" value="z" label="Z"/></td></tr>
</table>
<p>Total Compra: <input name="total" id="total" type="number" value="0" readonly/></p>
The checked flag is either on or off. It doesn't take an argument. So it looks like
<input type="checkbox" name="name" checked> checked </input>
<br/>
<input type="checkbox" name="name"> unchecked</input>
In your code you'll need something like: ${prdcts.idProducto ? "checked" : ""}

Jquery Trigger is firing the wrong table column

I have a dynamically generated table with many checkboxes with same name and click event. I am using an ALL checkbox in every column which will check all the checkbox in that column .
The code is
***dynamically generated checkboxes
if (discountProductGroupBuyer != null)
{
sb.Append("<td><input name=productGroupWiseCustomer id='" + "GetProduct" + customerGroup + "' type=checkbox checked=true value=mlb onclick=GetProduct('" + customerGroup + "') ></td>");
}
****onclick of generated checkboxes
function GetProduct(ids) {
debugger;
var str = ids;
var temp = [];
temp.length = 0;
temp = str.toString().split('-');
var addOrDelete = "";
var checkboxid = "#GetProduct" + ids;
if ($(checkboxid).is(":checked")) {
addOrDelete = true;
var flag = 0;
$.grep(ProductGroupID, function (item, idx) {
if (item.DiscountTypeId == temp[0] && item.BuyerId == temp[1] && item.ProductGroupId == temp[2]) {
//ProductGroupID.splice(idx, 1);
item.DiscountTypeId = temp[0];
item.BuyerId = temp[1];
item.ProductGroupId = temp[2];
item.AddOrDelete = addOrDelete;
flag = 1;
}
});
if (flag == 0) {
ProductGroupID.push({
DiscountTypeId:temp[0],
BuyerId:temp[1],
ProductGroupId:temp[2],
AddOrDelete:addOrDelete
});
}
}
else {
addOrDelete = false;
flag = 0;
$.grep(ProductGroupID, function(item, idx) {
if (item.DiscountTypeId == temp[0] && item.BuyerId == temp[1] && item.ProductGroupId == temp[2]) {
//ProductGroupID.splice(idx, 1);
item.DiscountTypeId = temp[0];
item.BuyerId = temp[1];
item.ProductGroupId = temp[2];
item.AddOrDelete = addOrDelete;
flag = 1;
}
});
if (flag == 0) {
ProductGroupID.push({
DiscountTypeId:temp[0],
BuyerId:temp[1],
ProductGroupId:temp[2],
AddOrDelete:addOrDelete
});
}
}
}
*** Check all code
$(document).on("click", "#chkAll", function () {
var cbody = $(this),
theader = cbody.parent(),
column = theader.index() + 1;
$("#tbody td:nth-child(" + column + ") input").prop("checked", this.checked);
});
Which seems to work and its checking all the checkbox in that specific column
like below image.
But the problem arise after adding a trigger event. Let me explain
I have also a trigger click event which will be fired by clicking that all checkbox for that specific column only. The problem is when I click the #chkAll checkbox its not triggering that specific column but triggering for the other column checkbox.
$(document).on("click", "#chkAll", function () {
var cbody = $(this),
theader = cbody.parent(),
column = theader.index() + 1;
$("#tbody td:nth-child(" + column + ") input").prop("checked", this.checked);
$("input:checkbox[name='productGroupWiseCustomer']").trigger('click');
});
What I am trying to achieve that by clicking individual column's #chkAll checkbox it will trigger only the checkboxes under that column only.Help Needed .Thanks for help
I also added a photo.
From what I understand, you not only want to (un)check the whole column of checkboxes, you also want the checkboxes that change because of this action, to have their event handlers executed. That second requirement is not happening when using prop. You could chain a call to trigger, but be aware that this will toggle the check again.
The solution is to select only those checkboxes in the column whose checkbox needs to toggle (which might not be all of them), and then to call .trigger("click") on those. This will both change their checked status and call the corresponding event handlers.
Here is how you could do it:
$("#tbody td:nth-child(" + column + ") input"
+ (this.checked ? ":not(:checked)" : ":checked").trigger('click');
Here is a working fiddle:
$(document).on("click", ".chkAll", function () {
var cbody = $(this),
theader = cbody.parent(),
column = theader.index() + 1;
$("#tbody td:nth-child(" + column + ") input"
+ (this.checked ? ":not(:checked)" : ":checked")).trigger('click');
});
// Dummy click handler just to give visual clue that it gets called
function GetProduct(input) {
$(input).fadeOut(100).fadeIn(100);
}
th { background-color: silver }
td { text-align: center }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table border=1>
<tr>
<th>Noodles<br><input class="chkAll" type="checkbox"></th>
<th>Detergent<br><input class="chkAll" type="checkbox"></th>
<th>Chocolate<br><input class="chkAll" type="checkbox"></th>
</tr>
<tbody id="tbody">
<tr>
<td><input name="productGroupWiseCustomer" type="checkbox" onclick="GetProduct(this)"></td>
<td><input name="productGroupWiseCustomer" type="checkbox" onclick="GetProduct(this)"></td>
<td><input name="productGroupWiseCustomer" type="checkbox" onclick="GetProduct(this)"></td>
</tr>
<tr>
<td><input name="productGroupWiseCustomer" type="checkbox" onclick="GetProduct(this)"></td>
<td><input name="productGroupWiseCustomer" type="checkbox" onclick="GetProduct(this)"></td>
<td><input name="productGroupWiseCustomer" type="checkbox" onclick="GetProduct(this)"></td>
</tr>
<tr>
<td><input name="productGroupWiseCustomer" type="checkbox" onclick="GetProduct(this)"></td>
<td><input name="productGroupWiseCustomer" type="checkbox" onclick="GetProduct(this)"></td>
<td><input name="productGroupWiseCustomer" type="checkbox" onclick="GetProduct(this)"></td>
</tr>
</tbody>
</table>
The fickering of the checkboxes is intentional: it is evidence of the click handlers being invoked.
Calling the event handler for all checkboxes
Checkboxes that do not change state should not need to get their click event handler caller. Since you insist in comments on this point, and I failed to convince you that this is conceptually wrong, you could use .triggerHandler (instead of .trigger) to call the event handler on all checkboxes of the clicked column -- but without any real click being simulated.
Again, this is not best practice:
$("#tbody td:nth-child(" + column + ") input").prop("checked", this.checked))
.each(function() {
$(this).triggerHandler('click');
});
Here is a working fiddle:
$(document).on("click", ".chkAll", function () {
var cbody = $(this),
theader = cbody.parent(),
column = theader.index() + 1;
$("#tbody td:nth-child(" + column + ") input").prop("checked", this.checked)
.each(function() {
$(this).triggerHandler('click');
});
});
// Dummy click handler just to give visual clue that it gets called
function GetProduct(input) {
$(input).fadeOut(100).fadeIn(100);
}
th { background-color: silver }
td { text-align: center }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table border=1>
<tr>
<th>Noodles<br><input class="chkAll" type="checkbox"></th>
<th>Detergent<br><input class="chkAll" type="checkbox"></th>
<th>Chocolate<br><input class="chkAll" type="checkbox"></th>
</tr>
<tbody id="tbody">
<tr>
<td><input name="productGroupWiseCustomer" type="checkbox" onclick="GetProduct(this)"></td>
<td><input name="productGroupWiseCustomer" type="checkbox" onclick="GetProduct(this)"></td>
<td><input name="productGroupWiseCustomer" type="checkbox" onclick="GetProduct(this)"></td>
</tr>
<tr>
<td><input name="productGroupWiseCustomer" type="checkbox" onclick="GetProduct(this)"></td>
<td><input name="productGroupWiseCustomer" type="checkbox" onclick="GetProduct(this)"></td>
<td><input name="productGroupWiseCustomer" type="checkbox" onclick="GetProduct(this)"></td>
</tr>
<tr>
<td><input name="productGroupWiseCustomer" type="checkbox" onclick="GetProduct(this)"></td>
<td><input name="productGroupWiseCustomer" type="checkbox" onclick="GetProduct(this)"></td>
<td><input name="productGroupWiseCustomer" type="checkbox" onclick="GetProduct(this)"></td>
</tr>
</tbody>
</table>
The fickering of the checkboxes is intentional: it is evidence of the click handlers being invoked.
Here you go with the solution https://jsfiddle.net/d9x95q2q/1/
$(document).on("click", ".checkAll", function () {
var cbody = $(this);
var theader = cbody.parent();
var column = theader.index() + 1;
$('.col' + column ).prop('checked', $(this).is(':checked'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>
col 1 <input type="checkbox" class="checkAll" />
</th>
<th>
col 2 <input type="checkbox" class="checkAll" />
</th>
<th>
col 3 <input type="checkbox" class="checkAll" />
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input type="checkbox" class="col1" />
</td>
<td>
<input type="checkbox" class="col2" />
</td>
<td>
<input type="checkbox" class="col3" />
</td>
</tr>
<tr>
<td>
<input type="checkbox" class="col1" />
</td>
<td>
<input type="checkbox" class="col2" />
</td>
<td>
<input type="checkbox" class="col3" />
</td>
</tr>
<tr>
<td>
<input type="checkbox" class="col1" />
</td>
<td>
<input type="checkbox" class="col2" />
</td>
<td>
<input type="checkbox" class="col3" />
</td>
</tr>
</tbody>
</table>
It looks your click triggers next column.
Try this:
$(document).on("click", "#chkAll", function () {
var cbody = $(this),
theader = cbody.parent(),
// index already makes the +1 for you
column = theader.index();
var td_set = $("#tbody td:nth-child(" + column + ") input");
td_set.prop("checked", this.checked);
td_set.trigger('click');
});
The sentence $("input:checkbox[name='productGroupWiseCustomer']").trigger('click'); fires a new click in your table and check, still, the next column.
Update
Now the code triggers click for every checkbox that is set as checked.

calculate grand total with javascript

I don't know how to get Grand total value
grand total is sum of all total
here is the code
<?php
$con = mysqli_connect('localhost', 'root', '', 'a.karat');
if(isset($_POST['product_id']))
{
$prno=$_POST['prno'];
$i=1;
$sql = mysqli_query($con,"select * from detail_pr where prNo='$prno'");
while ($r = mysqli_fetch_array($sql)) {
echo
'<tr>
<td><input type="checkbox" name="check[]" id="check'.$i.'" value="'.$i.'"></td>
<td><label for="productCode"></label>
<input type="text" name="productCode'.$i.'" id="productCode'.$i.'" readonly value="'.$r["productCode"].'" size="12" ></td>
<td><label for="productName"></label>
<input type="text" name="productName'.$i.'" id="productName'.$i.'" readonly value="'.$r["productName"].'"size="35" ></td>
<td><label for="qty"></label>
<input type="number" onkeyup="calc(this);" name="qty'.$i.'" id="qty'.$i.'" readonly value="'.$r["qty"].'" size="8" ></td>
<td><input type="number" onkeyup="calc(this);" name="price'.$i.'" id="price'.$i.'" size="10" min="1" max="99" onchange="calc(this);" ></td>
<td><input type="number" onkeyup="calc(this);" name="discount'.$i.'" id="discount'.$i.'" size="10" min="0" max="99" onchange="calc(this);"></td>
<td><input type="number" name="total'.$i.'" id="total'.$i.'" size="10" min="1" max="99" onchange="calc(this);" ></td>
</tr>';
$i++;
}
}
?>
<table width="400" border="0" align="right">
<tr>
<th scope="row">Grand Total</th>
<td>:</td>
<td><input name="grandtotal" id="grandtotal" type="text"></td>
</tr>
</table>
<script>
function calc(id) {
var row = id.parentNode.parentNode;
var quant = row.cells[3].getElementsByTagName('input')[0].value;
var price = row.cells[4].getElementsByTagName('input')[0].value;
var disc = row.cells[5].getElementsByTagName('input')[0].value;
if (disc == null || disc == '') {
res = parseFloat(quant) * parseFloat(price);
} else {
var res = (parseFloat(quant) * parseFloat(price)) - (parseFloat(quant) * parseFloat(price) * (parseFloat(disc) / 100));
}
row.cells[6].getElementsByTagName('input')[0].value = res;
}
</script>
I have manage to calculate total per row
now I need your help to sum all total and put the value in the grandtotal textbox
I guess on every change of a value of one of your input elements in your form the grand total should be updated, right? I 'd place an event listener on the form tag to keep it simple.
<form id="your-form" method="post" action="">
<!-- All your other inputs here -->
<input type="text" name="grandtotal" id="grandtotal">
</form>
<script>
document.querySelector('#your-form').addEventListener('change', function( event ) {
if (event.target.id && event.target.id !== 'grandtotal') {
var allTotals = document.querySelectorAll('input[name^="total"]'),
allTotalSum = 0;
Array.prototype.forEach.call(allTotals, function( element ) {
if (element.value) {
allTotalSum += parseFloat(element.value);
}
});
document.querySelector('#grandtotal').value = allTotalSum;
}
});
</script>
So on every change of one of your input fields the sum is updated. This code is untested.

jquery - get html string of table cells

I have some HTML that is being generated by some server-side code. The HTML that's generated looks like this:
<table id="myChoices">
<tr>
<td><input type="radio" name="choice" value="1" /></td>
<td>Monday</td>
<td>Mar 7</td>
</tr>
<tr>
<td><input type="radio" name="choice" value="2" /></td>
<td>Tuesday</td>
<td>Mar 8</td>
</tr>
<tr>
<td><input type="radio" name="choice" value="3" /></td>
<td>Wednesday</td>
<td>Mar 9</td>
</tr>
<tr>
<td><input type="radio" name="choice" value="4" /></td>
<td>Thursday</td>
<td>Mar 10</td>
</tr>
<tr>
<td><input type="radio" name="choice" value="5" /></td>
<td>Friday</td>
<td>Mar 11</td>
</tr>
</table>
When a user makes a choice, I need to get the two cells next to it. For example, if someone chooses the third option, I'm trying to get the following:
<td>Wednesday</td><td>Mar 9</td>
In my attempt to do this, I have the following jQuery:
function getHtml() {
var html = '';
var item = $("#myChoices input[type='radio']:checked");
if (item.length > 0) {
var grandparent = item.parent().parent();
var cells = grandparent.children();
var html = '';
for (var i = 0; i < cells.length; i++) {
if (i > 0) {
var cellHtml = cells[i];
html += cellHtml;
}
}
}
return html;
}
Unfortunately, my approach is not working. When I do the following:
var test = getHtml();
console.log(test);
I see the following in the console window:
[object HTMLTableCellElement][object HTMLTableCellElement]
Why? How do I get the actual HTML string?
Use outerHTML, instead you are storing the jQuery object in the variable.
var cellHtml = cells[i];
should be
var cellHtml = cells[i].outerHTML;
JS
function getHtml() {
var item = $("#myChoices input[type='radio']:checked");
if (item.length > 0) {
var grandparent = item.closest('tr'),
cells = grandparent.children();
var html = '';
for (var i = 1; i < cells.length; i++) {
html += cells[i].outerHTML + ' ';
}
}
return html;
}
js Fiddle
I propose you change the script a bit to simplify the process altogether.
$("#myChoices input").change( function() {
var string = $(this).parent().nextAll("td").text();
});
Variable "string" will contain the text you are looking for.
I believe you could just use something simple like:
$("input[type='radio']:checked").parents("tr").first().text();
Example: http://codepen.io/cchambers/pen/ONNawo
JSFIDDLE DEMO
Use this instead
var cellHtml = cells[i].outerHTML;
Complete JS
var html = '';
var item = $("#myChoices input[type='radio']:checked");
if (item.length > 0) {
var grandparent = item.parent().parent();
var cells = grandparent.children();
var html = '';
for (var i = 0; i < cells.length; i++) {
if (i > 0) {
var cellHtml = cells[i].outerHTML; //change here
html += cellHtml;
}
}
}
console.log(html);
Result format:
<td>Monday</td><td>Mar 7</td>
The easiest way would be to use the .html() method on a dynamic tr which contains the other two td elements.
A trick is to clone them then wrap them in a tr and get the html of that
var others = $(this).closest('td').siblings().clone();
alert( others.wrapAll('<tr>').parent().html());
$(function(){
$('#myChoices [name="choice"]').on('change', function(){
var others = $(this).closest('td').siblings().clone();
alert( others.wrapAll('<tr>').parent().html());
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myChoices">
<tr>
<td><input type="radio" name="choice" value="1" /></td>
<td>Monday</td>
<td>Mar 7</td>
</tr>
<tr>
<td><input type="radio" name="choice" value="2" /></td>
<td>Tuesday</td>
<td>Mar 8</td>
</tr>
<tr>
<td><input type="radio" name="choice" value="3" /></td>
<td>Wednesday</td>
<td>Mar 9</td>
</tr>
<tr>
<td><input type="radio" name="choice" value="4" /></td>
<td>Thursday</td>
<td>Mar 10</td>
</tr>
<tr>
<td><input type="radio" name="choice" value="5" /></td>
<td>Friday</td>
<td>Mar 11</td>
</tr>
</table>
In a function form it would be
function getHtml() {
var item = $("#myChoices input[type='radio']:checked");
var otherTD = item.closest('td').siblings().clone();
return otherTD.wrapAll('<tr>').parent().html();
}
You could use jquery's siblings method:
var textContents = $("#myChoices input[type='radio']:checked").siblings().html();

Categories

Resources