I am using the below code to loop through the cells in my table which contain an input and totaling them up to display in the total column. Ultimately the #testerField will be changes to $this and fired off of a jQuery listener over the whole table.
The table structure is something like this:
Non Input Cell -> Non Input Cell -> Cell with Input (x8) -> Total Cell
For some reason, it keeps double counting (iterating over) the first cell in the loop. Why is this occurring?
sumFunction = function() {
var row = $("#testerField").closest("tr");
var lastCell = row.find("td:last");
var total = 0;
row.add('td:has(:input)').each(function() {
var value = $(this).find(":input").val();
if (value > 0) {
total = Number(total) + Number(value);
}
});
lastCell.html(total);
}
Here is the HTML of one Table Row
<tr>
<td>1</td>
<td>Trouble</td>
<td><input id="testerField" type="number"/></td>
<td><input type="number"/></td>
<td><input type="number"/></td>
<td><input type="number"/></td>
<td><input type="number"/></td>
<td><input type="number"/></td>
<td><input type="number"/></td>
<td><input type="number"/></td>
<td><input type="number"/></td>
<td><input type="number"/></td>
<td><input type="number"/></td>
<td><input type="number"/></td>
<td></td>
</tr>
Consider the following example.
$(function() {
function calcSum() {
var row = $("#testerField").closest("tr");
var lastCell = $("td:last", row);
var total = 0;
$("td > input", row).filter(function() {
return $(this).val() > 0;
}).each(function(i, el) {
total += parseInt($(el).val());
});
lastCell.html(total);
}
$("table").ready(calcSum);
$("table input").change(calcSum);
});
table input {
width: 3em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td>1</td>
<td>Trouble</td>
<td><input id="testerField" type="number" /></td>
<td><input type="number" /></td>
<td><input type="number" /></td>
<td><input type="number" /></td>
<td><input type="number" /></td>
<td><input type="number" /></td>
<td><input type="number" /></td>
<td><input type="number" /></td>
<td><input type="number" /></td>
<td><input type="number" /></td>
<td><input type="number" /></td>
<td><input type="number" /></td>
<td></td>
</tr>
</table>
Here we iterate over each input in the row and only if they have a Value higher than 0.
var row = $("#testerField").closest("tr");
var lastCell = row.find("td:last");
$("table input").change(() => {
var total = 0;
$("td > input", row).each((i, el) => total += Number($(el).val()));
lastCell.html(total);
});
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<table>
<tr>
<td>1</td>
<td>Trouble</td>
<td><input id="testerField" type="number"/></td>
<td><input type="number"/></td>
<td><input type="number"/></td>
<td><input type="number"/></td>
<td><input type="number"/></td>
<td><input type="number"/></td>
<td><input type="number"/></td>
<td><input type="number"/></td>
<td><input type="number"/></td>
<td><input type="number"/></td>
<td><input type="number"/></td>
<td><input type="number"/></td>
<td></td>
</tr>
</table>
Related
I'm new to programming and still learn. I just want to ask how to make code validation for more than one input? I have data table item. I want to run validation input for each row.
My Code below is only run for the first row, and cannot running in the second row.
<tr>
<td><input id="stock" type="number" name="stock" value="<?php echo $row->stock; ?>" readonly></td>
<td><input id="qty" onInput="calc();" type="number" name="qty"></td>
</tr>
<script type="text/javascript">
function calc(){
var stock = document.getElementById("stock").value;
var qty = document.getElementById("qty").value;
if(qty > stock){
alert("Qty More Than Stock!");
document.getElementById("qty").value = 1;
}
}
</script>
You can use querySelectorAll with an data-attribute for select all inputs then forEach it and check the value like:
document.querySelectorAll('input[data-check]').forEach(el => {
el.addEventListener('change', () => {
if (parseInt(el.value) > parseInt(el.parentElement.previousElementSibling.children[0].value)) {
alert("Qty More Than Stock!");
el.value = 0;
}
});
});
<table>
<tr>
<td>Stock</td>
<td>Qty</td>
</tr>
<tr>
<td><input id="stock" type="number" name="stock" value="2" readonly></td>
<td><input data-check type="number" name="qty"></td>
</tr>
<tr>
<td><input id="stock" type="number" name="stock" value="3" readonly></td>
<td><input data-check type="number" name="qty"></td>
</tr>
</table>
PS. Remember to use always a structure like my example else my code probably doesn't work.in fact el.parentElement.previousElementSibling.children[0].value it's like say: element - parent of element (td) - previous element (other td) - the first children of the previus element (input).
Another option is use another data-attribute for select the stock value like:
document.querySelectorAll('input[data-check]').forEach(el => {
el.addEventListener('change', () => {
let stock = document.querySelector('input[data-index="'+el.dataset.stock+'"]');
if (parseInt(el.value) > parseInt(stock.value)) {
alert("Qty More Than Stock!");
el.value = 0;
}
});
});
<table>
<tr>
<td>Stock</td>
<td>Qty</td>
</tr>
<tr>
<td><input data-index='0' type="number" name="stock" value="2" readonly></td>
<td><input data-check data-stock='0' type="number" name="qty"></td>
</tr>
<tr>
<td><input data-index='1' type="number" name="stock" value="25" readonly></td>
<td><input data-check data-stock='1' type="number" name="qty"></td>
</tr>
</table>
I have a some inputs with different ids as you see down here
<tr>
<td><input type="number" id="cell1" ></td>
<td><input type="number" id="cell2" ></td>
<td><input type="number" id="cell3" ></td>
<td><input type="number" id="cell4"></td>
<td><input type="number" id="cell5"></td>
<td><input type="number" id="cell6"></td>
<td><input type="number" id="cell7" ></td>
<td><input type="number" id="cell8" ></td>
<td><input type="number" id="cell9" ></td>
</tr>
Now I want to use jquery to restrict the number the user enters in the inputs with something like this
for(var i = 0 ; i <= 81 ; i++) {
$(document).ready(function () {
$("#cell" , i).change(function () {
var n = $("#cell",i).val();
console.log($("#cell", i));
if (n < 1)
$("#cell", i).val(1);
if (n > 9)
$("#cell" , i).val(9);
});
});
}
But it doesn't get the ids. How can I pass the i variable to "#cell"?
Several things. You likely want this selector - id starts with cell
$(function() {
$("[id^=cell]").on("input",function() {
const val = this.value
if (val < 0) this.value = 1
if (val > 0) this.value = 9
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td><input type="number" id="cell1"></td>
<td><input type="number" id="cell2"></td>
<td><input type="number" id="cell3"></td>
<td><input type="number" id="cell4"></td>
<td><input type="number" id="cell5"></td>
<td><input type="number" id="cell6"></td>
<td><input type="number" id="cell7"></td>
<td><input type="number" id="cell8"></td>
<td><input type="number" id="cell9"></td>
</tr>
</tbody>
</table>
HTML version
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td><input type="number" id="cell1" min=1 max=9></td>
<td><input type="number" id="cell2" min=1 max=9></td>
<td><input type="number" id="cell3" min=1 max=9></td>
<td><input type="number" id="cell4" min=1 max=9></td>
<td><input type="number" id="cell5" min=1 max=9></td>
<td><input type="number" id="cell6" min=1 max=9></td>
<td><input type="number" id="cell7" min=1 max=9></td>
<td><input type="number" id="cell8" min=1 max=9></td>
<td><input type="number" id="cell9" min=1 max=9></td>
</tr>
</tbody>
</table>
First, move your loop inside the $document.ready
Then simply append i to the id prefix to make the correct querySelector for the cell.
Although it doesn't answer your question you could also use the min and max attributes to accomplish your task.
Here is a working example of appending the loop counter i.
// create 81 inputs for demo purposes
$(document).ready(function () {
var row= $('#myrow');
for(var i = 0 ; i <= 81 ; i++)
{
row.append($('<td/>').append('<input type="number" />').attr("id", "cell" + i));
}
});
$(document).ready(function () {
for(var i = 0 ; i <= 81 ; i++) {
$("#cell"+ i).change(function (e) {
var input= $(e.target);
var n = input.val();
if (n < 1)
input.val(1);
else if (n > 9)
input.val(9);
});
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<table>
<tr id='myrow'>
</tr>
</table>
I have a table in razor and I sent the data by ViewBag from controller
<table>
<thead>
<tr>
<th>Name</th>
<th>Category</th>
<th>Price</th>
<th>Count</th>
</tr>
</thead>
<tbody>
#foreach(var item in ViewBag.Products)
{
<tr>
<td>#item.Name</td>
<td>#item.Category</td>
<td>
<input type="text" class="form-control" value="#item.Price" />
</td>
<td>
<input type="text" class="form-controll" value="#item.Count" />
</td>
</tr>
}
</tbody>
</table>
<input type="text" class="form-control" value="#Model.TotalPrice" />
I want to multiple count and price of each row and put it in another input using javascript. and when the user change the value of input, that input that holds the value could change automatically.
if anyone can help me i would be appreciated.
If you are using jquery then it can be achieve as below.
You can update your total on every key press in price or count input.
Add some class to your input. In my example I've took class as price, and class total for display sum.
Add keyup event as below. Also trigger it on $(document).ready to initially set the total value.
$('.price').on('keyup', function() {
var val = +$(this).val();
var valSibling = +$(this).parent().siblings('td').find('.price').val();
if (isNaN(val) || isNaN(valSibling))
return;
$(this).parent().siblings('td').find('.total').val(val * valSibling);
var finaltotal = 0;
$('.total').each(function() {
if(!isNaN($(this).val()))
finaltotal += Number($(this).val());
});
$('.finaltotal').val(finaltotal);
});
$(document).ready(function(){
$('.price').trigger('keyup');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Name</th>
<th>Category</th>
<th>Price</th>
<th>Count</th>
</tr>
</thead>
<tbody>
<tr>
<td>Name1</td>
<td>Category1</td>
<td><input type="text" class="price form-control" value="40" /></td>
<td><input type="text" class="price form-control" value="4" /></td>
<td><input type="text" class="total form-control" /></td>
</tr>
<tr>
<td>Name2</td>
<td>Category2</td>
<td><input type="text" class="price form-control" value="20" /></td>
<td><input type="text" class="price form-control" value="2" /></td>
<td><input type="text" class="total form-control" /></td>
</tr>
</tbody>
</table>
<input type="text" class="finaltotal form-control" />
var inputs = $('#container input');
inputs.keyup(function() {
var arr = inputs.toArray();
var sum = 0;
for (var i = 0; i < arr.length / 2; i++)
sum += arr[i * 2].value * arr[i * 2 + 1].value;
$('#result').val(sum);
})
table,
th,
td {
border: 1px solid black;
border-collapse: collapse;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Count</th>
<th>Price</th>
<tr>
</thead>
<tbody id='container'>
<tr>
<td><input type='number' value='1' /></td>
<td><input type='number' value='2' /></td>
</tr>
<tr>
<td><input type='number' value='10' /></td>
<td><input type='number' value='20' /></td>
</tr>
</tbody>
</table>
Total: <input type='number' readonly id='result' readonly value='202' />
I want to multiple count and price of each row and put it in another input using javascript.
You can add another td in each tr. Then loop through all the tbody tr to calculate the value:
var tr = document.querySelectorAll('tbody tr');
function calculate(){
tr.forEach(function(el){
var td = el.querySelectorAll('td');
// If there is invalid number in input then no change in total.
if (isNaN(td[2].querySelector('input').value) || isNaN(td[3].querySelector('input').value))
return;
td[4].querySelector('input').value = td[2].querySelector('input').value * td[3].querySelector('input').value;
});
}
calculate();
.form-control{
width: 50px;
}
<table>
<thead>
<tr>
<th>Name</th>
<th>Category</th>
<th>Price</th>
<th>Count</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>Name1</td>
<td>Category1</td>
<td><input type="text" oninput="calculate()" class="form-control" value="40" /></td>
<td><input type="text" oninput="calculate()" class="form-control" value="4" /></td>
<td><input type="text" class="form-control" /></td>
</tr>
<tr>
<td>Name2</td>
<td>Category2</td>
<td><input type="text" oninput="calculate()" class="form-control" value="20" /></td>
<td><input type="text" oninput="calculate()" class="form-control" value="2" /></td>
<td><input type="text" class="form-control" /></td>
</tr>
<tr>
<td>Name3</td>
<td>Category3</td>
<td><input type="text" oninput="calculate()" class="form-control" value="30" /></td>
<td><input type="text" oninput="calculate()" class="form-control" value="3" /></td>
<td><input type="text" class="form-control" /></td>
</tr>
</tbody>
</table>
I have table with quantity cell when change quantity it need to multiply with other parent td value.and sum the column values .
(i.e) if i change quantity to 2 then the parent rows need multiply by 2 & columns get value get added
I done all the calculation part without input in td now i added input and the calculation got affected i debug and checked it i don't know what would be the problem
Here my fiddle:
https://jsfiddle.net/hahkarthick/57zpk59k/3/
$(document).ready(function(){
$('.quantity').on('change, keyup',function(){
var val=$(this).val();
console.log(val)
// To avoid auto inc while pressing arrow keys
var preVal =$(this).data('val');
$(this).data('val',val);
//To avoid auto inc while pressing arrow keys //
if(val =='' || isNaN(val) || val < 1 || val == undefined){
val = 1;
}
$(this).siblings().each(function(){
var tbvalue=$(this).data("val");
var result= parseInt(tbvalue)*parseInt(val);
$(this).text(result);
});
autoSum();
});
autoSum();
});
function autoSum(){
for (var i = 1; i <= 4; i++) {
var sum = 0;
var tdBoxes = $('.auto_sum>tbody>tr>td>input:nth-child(' + i + ')');
for(var j=0; j<tdBoxes.length-1;j++)
{
var value = $(tdBoxes[j]).val();
sum += (value == undefined || value == "")? 0 : parseInt(value);
}
// set total in last cell of the column
$('.auto_sum>tbody>tr>td>input:nth-child(' + i + ')').last().html(sum);
// $('.auto_sum>tbody>tr>td:nth-child(' + i + ')').last().toggleClass('total');
}
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="container">
<h2>Table calculation</h2>
<p>Calculaton</p>
<table class="auto_sum table table-hover">
<thead>
<tr>
<th>value1</th>
<th>value2</th>
<th>value3</th>
<th>Quantity</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="number" data-val="" value="20" name=""></td>
<td><input type="number" data-val="" value="10" name=""></td>
<td><input type="number" data-val="" value="10" name=""></td>
<td><input class="quantity" type="number" name=""></td>
</tr>
<tr>
<td><input type="number" data-val="" value="5" name=""></td>
<td><input type="number" data-val="" value="6" name=""></td>
<td><input type="number" data-val="" value="12" name=""></td>
<td><input class="quantity" type="number" name=""></td>
</tr>
<tr>
<td><input type="number" data-val="" value="45" name=""></td>
<td><input type="number" data-val="" value="23" name=""></td>
<td><input type="number" data-val="" value="22" name=""></td>
<td><input class="quantity" type="number" name=""></td>
</tr>
<tr class="total">
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
</tbody>
</table>
</div>
Hope this helps...
<div class="container">
<h2>Table calculation</h2>
<p>Calculaton</p>
<table class="auto_sum table table-hover" id="sum_table">
<thead>
<tr class="title">
<th>value1</th>
<th>value2</th>
<th>value3</th>
<th>Quantity</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" data-val="" value="20[2]" name=""></td>
<td><input type="number" data-val="" value="10" name=""></td>
<td><input type="number" data-val="" value="10" name=""></td>
<td><input class="quantity" type="number" name=""></td>
</tr>
<tr>
<td><input type="number" data-val="" value="5" name=""></td>
<td><input type="number" data-val="" value="6" name=""></td>
<td><input type="number" data-val="" value="12" name=""></td>
<td><input class="quantity" type="number" name=""></td>
</tr>
<tr>
<td><input type="number" data-val="" value="45" name=""></td>
<td><input type="number" data-val="" value="23" name=""></td>
<td><input type="number" data-val="" value="22" name=""></td>
<td><input class="quantity" type="number" name=""></td>
</tr>
<tr class="totalColumn">
<td class="totalCol">Total:</td>
<td class="totalCol">Total:</td>
<td class="totalCol">Total:</td>
<td></td>
</tr>
</tbody>
</table>
</div>
<script>
$(document).ready(function(){
$('.quantity').on('change',function(){
var val=$(this).val();
console.log(val)
// To avoid auto inc while pressing arrow keys
var preVal =$(this).data('val');
$(this).data('val',val);
//To avoid auto inc while pressing arrow keys //
if(val =='' || isNaN(val) || val < 1 || val == undefined){
val = 1;
}
$(this).parent().siblings().each(function(){
var oldval = $(this).find('input').val();
var arr = oldval.split("[");
console.log(arr);
//var newval = val * oldval;
var newval = (val * parseFloat(arr[0])).toFixed(2);
console.log(newval);
if(arr.length > 1) {
newval = newval + "[" + arr[1];
}
$(this).find('input').val(newval);
});
autoSum();
});
autoSum();
});
function autoSum(){
var $dataRows=$("#sum_table tr:not('.total, .title')");
var totals=[0,0,0];
$dataRows.each(function() {
$(this).find('input').each(function(i){
totals[i]+=parseFloat( $(this).val());
});
});
$("#sum_table td.totalCol").each(function(i){
$(this).html("total:"+totals[i]);
});
}
</script>
I have updated the fiddle.
I have made following changes :-
$('.quantity').on('change, keyup',function(){ changed to $('.quantity').on('keyup',function(){
$(this).siblings().each(function(){ changed to $(this).parent().siblings().each(function(){
var tbvalue=$(this).data("val"); changed to var tbvalue=$(this).find("input[type=number]").val();
Hope it helps.
Let's have a table like this:
<table>
<tr>
<td><input type="text" name="FirstName1" /></td>
<td><input type="text" name="LastName1" /></td>
</tr>
<tr>
<td><input type="text" name="FirstName2" /></td>
<td><input type="text" name="LastName2" /></td>
</tr>
</table>
I want to have a button that will add new row at the end of the table with incremented name attributes so it will look like this:
<table>
<tr>
<td><input type="text" name="FirstName1" /></td>
<td><input type="text" name="LastName1" /></td>
</tr>
<tr>
<td><input type="text" name="FirstName2" /></td>
<td><input type="text" name="LastName2" /></td>
</tr>
<tr>
<td><input type="text" name="FirstName3" /></td>
<td><input type="text" name="LastName3" /></td>
</tr>
</table>
And so on.
So far I have this but it does not increment name attributes:
$("#newRowButton").click(function(){
$("table tr:last").clone().appendTo("table");
});
$("#newRowButton").click(function() {
$("table tr:last")
.clone()
.appendTo("table")
.find(':input')
.attr('name', function(index, name) {
return name.replace(/(\d+)$/, function(fullMatch, n) {
return Number(n) + 1;
});
})
});
Live demo.
$("#newRowButton").click(function(){
var trows = $("table tr:last").clone();
trows.find('td input').attr("name",function(i,a){
var p = new RegExp("((?:[a-z][a-z]+))(\\d+)",["i"]);
var m = p.exec(a);
var index = parseInt(m[1]);
index++;
return m[0]+index;
});
trows.appendTo("table");
});
var clonedRow = $("#EventType tr:last").clone();
$("input", clonedRow).attr('name', 'FirstName3'); // reset the name
you can get the name attribute and increment by 1
Reference