Calculate total sum of dynamically added items to a table - javascript

I would like to calculate the line total for each item using the itemPrice* Qty fields, the line amount is to be auto populated in the linePrice textbox. After which the grand total is then auto populated to the priceTotal field by summing up all the line prices.
I am having a challenge getting each Qty and itemPrice textbox value into my JavaScript function since the name(s) is/are Qty0, Qty1, Qty2... and itemPrice0, itemPrice1,.. depending on the added row, and also getting the final calculations into the respective textboxes.
Below is my code.
function isNumberKey(evt) {
var charCode = (evt.which) ? evt.which : event.keyCode
if (charCode > 31 && (charCode != 46 && (charCode < 48 || charCode > 57)))
return false;
return true;
}
$(document).ready(function() {
$(document).on("keyup", ".Qty", calculateTot);
$("button").click(function() {
addrow('tb')
});
});
function calculateTot() {
var sum = 0;
var price = document.getElementById('itemPrice').value;
var qtyPur = parseFloat(this.value);
$(".Qty").each(function() {
if (!isNaN(this.value) && this.value.length != 0) {
linePR = price * qtyPur;
}
});
$("#linePrice").val(linePR.toFixed(2));
calculateSum();
}
function calculateSum() {
var sum = 0;
$(".linePrice").each(function() {
if (!isNaN(this.value) && this.value.length != 0) {
sum += parseFloat(this.value);
}
});
$("#priceTotal").val(sum.toFixed(2));
}
$(document).ready(function() {
var i = 1,
j = 1;
$("#add_row").click(function() {
if (i < 10) {
$('#addr' + i).html("<td>" + (i + 1) + "</td><td><b>Select Item</b></td><td colspan='1'><select name='Sub_Name" + i + "' class='form-control'><option value=''>Select Item</option><option value='1000001'>Item A</option><option value='1000002'>Item B</option><option value='1000003'>Item C</option><option value='1000004'>Item D</option></select></td><td><input type='text' name='itemPrice" + i + "' id='itemPrice" + j + "' class='itemPrice form-control' placeholder='Unit Price'></td><td><input type='number' name='Qty" + i + "' id='Qty" + j + "' class='Qty form-control' onkeypress='return isNumberKey(event)' placeholder='Quantity'></td><td><input type='text' name='linePrice" + i + "' id='linePrice" + j + "' class='linePrice form-control' onkeypress='return isNumberKey(event)' placeholder='Line Price' readonly></td>");
$('#tab_add').append('<tr id="addr' + (i + 1) + '"></tr>');
i++;
j++;
$('#delete_row').show();
} else {
alert("You can only add upto a maximum of 10 items")
$('#add_row').hide();
}
});
$("#delete_row").click(function() {
if (i > 1) {
var r = confirm('Do you want to delete this item?');
if (r == true) {
$("#addr" + (i - 1)).html('');
i--;
$('#add_row').show();
}
} else {
alert("Entry cannot be deleted")
$('#delete_row').hide();
}
});
});
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"></script>
<script src="https://code.jquery.com/jquery-2.1.1.js"></script>
<table class="table table-bordered table-hover" id="tab_add">
<tbody>
<tr>
<td colspan="2"><b>Customer Name</b></td>
<td colspan="1">
<select name="Per_Name[]" class="form-control">
<option value="">Select Customer</option>
<option value="2000001">John Doe</option>
<option value="2000002">Jane Doe</option>
<option value="2000003">Tom Harry</option>
<option value="2000004">Steve Jobs</option>
</select>
</td>
</tr>
<tr id='addr0'>
<td><b>1</b></td>
<td><b>Select Item</b></td>
<td colspan="1">
<select name="Sub_Name[]" class="form-control">
<option value="">Select Item</option>
<option value="1000001">Item A</option>
<option value="1000002">Item B</option>
<option value="1000003">Item C</option>
<option value="1000004">Item D</option>
</select>
</td>
<td><input type="text" name="itemPrice0" id="itemPrice0" class="itemPrice form-control" placeholder="Unit Price"></td>
<td><input type="number" name="Qty0" id="Qty0" class="Qty form-control" onkeypress="return isNumberKey(event)" placeholder="Quantity"></td>
<td><input type="text" name="linePrice0" id="linePrice0" class="linePrice form-control" onkeypress="return isNumberKey(event)" placeholder="Line Price" readonly></td>
<th>
<span class="glyphicon glyphicon-plus"></span>
<span class="glyphicon glyphicon-minus"></span>
</th>
</tr>
<tr id='addr1'></tr>
</tbody>
</table>
<table class="table table-bordered table-hover">
<tr id="finRow">
<td colspan="2" width="75%"><b>TOTAL</b></td>
<td><input type="text" name="priceTotal" id="priceTotal" class="row-total form-control" disabled></td>
</tr>
</table>

In order to reduce the amount of DOM traversal that you have to do to accomplish this, I suggest adding data-* attributes to your elements so that you can get the index and use that to reference the other elements directly.
<td><input type="text" name="itemPrice0" id="itemPrice0" data-index="0" class="itemPrice form-control" placeholder="Unit Price"></td>
<td><input type="number" name="Qty0" id="Qty0" data-index="0" class="Qty form-control" onkeypress="if(!isNumberKey(event)){return false;}" placeholder="Quantity"></td>
<td><input type="text" name="linePrice0" id="linePrice0" data-index="0" class="linePrice form-control" onkeypress="return isNumberKey(event)" placeholder="Line Price" readonly></td>
Then in your $("#add_row").click(function() { function we add data-index='"+j+"' when creating the new elements ...
$('#addr' + i).html("<td>" + (i + 1) + "</td><td><b>Select Item</b></td><td colspan='1'><select name='Sub_Name" + i + "' class='form-control'><option value=''>Select Item</option><option value='1000001'>Item A</option><option value='1000002'>Item B</option><option value='1000003'>Item C</option><option value='1000004'>Item D</option></select></td><td><input type='text' name='itemPrice" + i + "' id='itemPrice" + j + "' data-index='"+j+"' class='itemPrice form-control' placeholder='Unit Price'></td><td><input type='number' name='Qty" + i + "' id='Qty" + j + "' data-index='"+j+"' class='Qty form-control' onkeypress='return isNumberKey(event)' placeholder='Quantity'></td><td><input type='text' name='linePrice" + i + "' id='linePrice" + j + "' data-index='"+j+"' class='linePrice form-control' onkeypress='return isNumberKey(event)' placeholder='Line Price' readonly></td>");
Finally, change your keyup handler to ...
$("#tab_add").on("keyup", ".Qty", function(e){
var qtyPur = parseFloat(this.value);
if (!isNaN(this.value) && this.value.length != 0) {
// this is where use use the data-index attribute to dynamically generate the target element ids
$("#linePrice"+$(this).data('index')).val(
parseFloat($("#itemPrice"+$(this).data('index')).val()) * qtyPur
);
}
calculateSum()
});
See Demo

This part of code will calculate linePrice of each row:
$("tr").each(function() {
if ($(this).children("td").length) {
$($($(this).children("td")[5]).children("input")[0]).val(
(($($($(this).children("td")[4]).children("input")[0]).val()) ? Number($($($(this).children("td")[4]).children("input")[0]).val()) : 0) *
(($($($(this).children("td")[3]).children("input")[0]).val()) ? Number($($($(this).children("td")[3]).children("input")[0]).val()) : 0)
)
}
});

function grosschanged_total1(a) {
var str = a;
var res = str.split("_");
//alert(res[2]);
var result = res[2];
var rate = parseFloat(document.getElementById("Gridview1_txtgross_" + result).value) * parseFloat(document.getElementById("Gridview1_txtrate_" + result).value);
var scale77 = 2;
// rate = roundNumberV2(rate, scale77);
var gresult = 0.00;
if(isNaN(rate)){
gresult= document.getElementById("Gridview1_txttotal_" + result).value = "";
} else{
gresult= document.getElementById("Gridview1_txttotal_" + result).value = parseFloat(Math.round(rate * 100) / 100).toFixed(2);
}
//GridView1_txtinvamt_0
var gfresult = parseFloat(gresult);
var ggresult = 0.00;
ggresult = gfresult + ggresult;
// $("[id*=lblGrandTotal]").html(ggresult);
//GridView1_txtdelinvnum_0 + GridView1_txtinvamt_0 = GridView1_txtgrosspt_0
// Calculate();
grosschanged_total1(a);
}
function Numerics(text) {
var regexp = /^[0-9]*$/;
if (text.value.search(regexp) == -1) {
text.value = text.value.substring(0, (text.value.length - 1));
alert('Numerics only allowed');
if (text.value.search(regexp) == -1)
text.value = "";
text.focus();
return false;
}
else
return true;
}

Related

with jquery I am adding input boxes and table row as shown in pic how can i subtract from total onkeyup when i create a box and put value in it

Here is how I am adding Bank names rows and the which will be added to it
How can i subtract from total row in real time > onkeyup > by creating input using jquery and putting value in it? please help. Actually I want my total sale to be deposited to different banks thats why I want it
<form method="GET" action="savebank.php" class="">
<table class="table table-bordered" id='TextBoxesGroup'>
<tr>
<th>Total Amount</th>
<th id="total" value="<?php echo $tsp; ?>">Rs. <?php echo $tsp; ?></th>
</tr>
<tr id="TextBoxDiv1">
<!-- INPUT BOXES WILL BE HERE-->
</tr>
</table>
<button type="submit" class="btn btn-lg btn-success btn-block" id="ttwo" style="display:none;">Submit</button>
</form>
<!-- Below is jquery -->
<script type="text/javascript">
$(document).ready(function() {
var counter = 2;
$("#addmore").click(function() {
if (counter > 30) {
alert("No more textboxes allowed");
return false;
}
var newTextBoxDiv = $(document.createElement('tr'))
.attr("id", 'TextBoxDiv' + counter);
newTextBoxDiv.after().html('<td><input type="text" name="bank[]" required class="form-control" placeholder="Bank Name" id="textbox' + counter + '"></td>' +
'<td><input type="number" name="amnt[]" required class="form-control textboz" placeholder="Amount" id="textbox' + counter + '"></td>');
newTextBoxDiv.appendTo("#TextBoxesGroup");
counter++;
});
$("ttwo").css("display", "block");
$("#remove").click(function() {
if (counter == 1) {
alert("No more textbox to remove");
return false;
}
counter--;
$("#TextBoxDiv" + counter).remove();
});
$("#getButtonValue").click(function() {
var msg = '';
for (i = 1; i < counter; i++) {
msg += "\n Textbox #" + i + " : " + $('#textbox' + i).val();
}
alert(msg);
});
});
</script>

How to change value inside input box that generated by jQuery?

please help me resolved this problem, I have an input value (weight) that generated by jQuery, I know it won't change it's value because of looping in my code, but is there another way to do this ?
The goal is I want to autogenerate the weight input value, but I can change it too.
if the snippet don't work, here's the link :
https://jsfiddle.net/s3grkqxm/
Thank you for your help.
var numRows = 2, ti = 5;
function isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
function recalc() {
var berat = 0;
var qty = 0;
var grandtotal = 0;
var grandtotalbtg = 0;
$('#kas_table').find('tr').each(function() {
var berat = $(this).find('input.berat').val();
var qty = $(this).find('input.qty').val();
var subtotal = (berat * qty);
let berat_max = $(this).find('option:selected').data('berat');
$(this).find('input.subtotal').val(Math.round(subtotal * 100) / 100);
$(this).find('input.berat').val(berat_max).text();
});
}
$(function() {
$('div.table-responsive').on("keyup change blur", recalc);
});
var i=0;
$('#add_new').click(function(){
i++;
$('#mainbody').append('<tr><td>' +
'<select class="form-control nama" name="addmore['+i+'][nama]" id="nama'+i+'" required >' +
'<option disabled="disabled" selected="selected" value="" >Select Produk</option>' +
'<option value="1" data-berat="100">Item 1</option>' +
'<option value="1" data-berat="170">Item 2</option>' +
'</select></td>' +
'<td><input class="form-control qty" type="number" name="addmore['+i+'][qty]" id="qty'+i+'" required ></td>' +
'<td><input step=".001" class="form-control berat" type="number" name="addmore['+i+'][berat]" id="berat'+i+'" required ></td>' +
'<td><input class="form-control subtotal" type="number" name="addmore['+i+'][subtotal]" id="subtotal'+i+'" required readonly></td>'
)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="table-responsive">
<table class="table-bordered" width="100%" id="kas_table">
<thead>
<tr>
<th width="40%">Name</th>
<th width="10%">Qty</th>
<th width="10%">Weight</th>
<th>Subtotal KG</th>
<th>
<button id="add_new" type="button" name="add_new" class="btn btn-sm btn-success"> +</button>
</th>
</tr>
</thead>
<tbody id="mainbody">
<tr>
<td><select class="form-control nama" name="addmore[0][nama]" id="nama0" required >
<option disabled="disabled" selected="selected" value="" >Select Produk</option>
<option value="1" data-berat="100">Item 1</option>
<option value="2" data-berat="170">Item 2</option>
</select></td>
<td><input class="form-control qty" type="number" name="addmore[0][qty]" id=qty0 required></td>
<td><input step=".001" class="form-control berat" type="number" name="addmore[0][berat]" id="berat0" required></td>
<td><input class="form-control subtotal" type="number" name="addmore[0][subtotal]" id="subtotal0" readonly></td>
</tr>
</tbody>
</table>
</div>
the reason when you change Weight it back to the original value is because you refresh the whole table including the drop-down that's why it set back the value which must be set after the dropdown change.$('div.table-responsive').on("keyup change blur", recalc); due this.
you just need to separate each element change event to get the proper results.
I set the value in Weight on the change dropdown by adding this
$(document).on('change', 'select', function() {
$('#kas_table').find('tr').each(function() {
let berat_max = $(this).find('option:selected').data('berat');
$(this).find('input.berat').val(berat_max).text();
});
});
and separately call qty and weight using this
$('.qty').on("keyup change blur", recalc);
$('.berat').on("keyup change blur", recalc);
finally here is your updated code working as expected hope it will helpful for you.
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
var numRows = 2, ti = 5;
function isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
function recalc() {
var berat = 0;
var qty = 0;
var grandtotal = 0;
var grandtotalbtg = 0;
$('#kas_table').find('tr').each(function() {
var berat = $(this).find('input.berat').val();
var qty = $(this).find('input.qty').val();
var subtotal = (berat * qty);
$(this).find('input.subtotal').val(Math.round(subtotal * 100) / 100);
});
}
function selectProduct(e)
{
let berat_max = $(e).find('option:selected').data('berat');
$(e).parent().parent().find('input.berat').val(berat_max).text();
var berat = $(e).parent().parent().find('input.berat').val();
var qty = $(e).parent().parent().find('input.qty').val();
var subtotal = (berat * qty);
$(e).parent().parent().find('input.subtotal').val(Math.round(subtotal * 100) / 100);
}
$(function() {
$(document).on('change', 'select', function() {
$('.qty').on("keyup change blur", recalc);
$('.berat').on("keyup change blur", recalc);
});
var i=0;
$('#add_new').click(function(){
i++;
$('#mainbody').append('<tr><td>' +
'<select class="form-control nama" name="addmore['+i+'][nama]" id="nama'+i+'" onchange="selectProduct(this)" required >' +
'<option disabled="disabled" selected="selected" value="">Select Produk</option>' +
'<option value="1" data-berat="100">Item 1</option>' +
'<option value="1" data-berat="170">Item 2</option>' +
'</select></td>' +
'<td><input class="form-control qty" type="number" name="addmore['+i+'][qty]" id="qty'+i+'" required ></td>' +
'<td><input step=".001" class="form-control berat" type="number" name="addmore['+i+'][berat]" id="berat'+i+'" required ></td>' +
'<td><input class="form-control subtotal" type="number" name="addmore['+i+'][subtotal]" id="subtotal'+i+'" required readonly></td>'
)
});
});
</script>
</head>
<body>
<div class="table-responsive">
<table class="table-bordered" width="100%" id="kas_table">
<thead>
<tr>
<th width="40%">Name</th>
<th width="10%">Qty</th>
<th width="10%">Weight</th>
<th>Subtotal KG</th>
<th>
<button id="add_new" type="button" name="add_new" class="btn btn-sm btn-success"> +</button>
</th>
</tr>
</thead>
<tbody id="mainbody">
<tr>
<td><select class="form-control nama" name="addmore[0][nama]" id="nama0" onchange="selectProduct(this)" required >
<option disabled="disabled" selected="selected" value="">Select Produk</option>
<option value="1" data-berat="100">Item 1</option>
<option value="2" data-berat="170">Item 2</option>
</select></td>
<td><input class="form-control qty" type="number" name="addmore[0][qty]" id=qty0 required></td>
<td><input step=".001" class="form-control berat" type="number" name="addmore[0][berat]" id="berat0" required></td>
<td><input class="form-control subtotal" type="number" name="addmore[0][subtotal]" id="subtotal0" readonly></td>
</tr>
</tbody>
</table>
</div>
</body>
</html>

JS when i add new row in table the previous one is cleared

I have specific problem. When I press button "Dodaj produkt", the values of inputs that have been inserted, are cleared. For example, fields: name, count, price_netto, vat_rate, price_brutto, summary_entity. Even if they're filled, after I press the button the values are default. I don't know why does this happens but I hope that someone will explain it to me.
var id_count = 1;
var price_summary = 0;
function delete_product(id) {
document.getElementById(id).remove();
}
function change_brutto(id) {
var netto = replace_dots(document.getElementById("price_netto" + id));
var vat = replace_dots(document.getElementById("vat_rate" + id));
var count = replace_dots(document.getElementById("count" + id));
if (vat > 0) {
vat = vat / 100;
vat += 1;
var calc = netto * vat;
document.getElementById("price_brutto" + id).value = Math.round((calc + Number.EPSILON) * 100) / 100;
calc = calc * count;
document.getElementById("summary" + id).value = Math.round((calc + Number.EPSILON) * 100) / 100;
} else if (vat == "" || vat == 0) {
document.getElementById("vat_rate" + id).value = "0";
document.getElementById("price_brutto" + id).value = netto;
document.getElementById("summary" + id).value = netto * count;
} else {
alert("Wpisz poprawną stawkę VAT");
}
}
function change_netto(id) {
var brutto = replace_dots(document.getElementById("price_brutto" + id));
var vat = replace_dots(document.getElementById("vat_rate" + id));
if (vat > 0) {
vat = vat / 100;
vat += 1;
var calc = brutto / vat;
document.getElementById("price_netto" + id).value = Math.round((calc + Number.EPSILON) * 100) / 100;
} else if (vat == "" || vat == 0) {
document.getElementById("vat_rate" + id).value = "0";
document.getElementById("price_netto" + id).value = brutto;
} else {
alert("Wpisz poprawną stawkę VAT");
}
}
function replace_dots(string) {
newString = string.value.replace(",", ".");
return newString;
}
function vat_changed(id) {
if (document.getElementById("price_netto" + id).value != "") {
change_brutto(id);
} else if (document.getElementById("price_brutto" + id).value != "") {
change_netto(id);
}
}
function count_changed(id) {
var count = replace_dots(document.getElementById("count" + id));
var brutto = replace_dots(document.getElementById("price_brutto" + id));
var summ = document.getElementsByName("summary_entity[]");
document.getElementById("summary" + id).value = brutto * count;
for (var i = 0; i < summ.length; i++) {
var val = summ[i];
price_summary += parseFloat(val.value);
}
document.getElementById("summary").innerHTML = price_summary;
}
function summary() {
}
window.onload = function() {
var btn = document.getElementById("add_product");
btn.addEventListener("click", function() {
id_count += 1;
document.getElementById("products_table").innerHTML +=
"<tr id='" + id_count + "'>\
<td><input type='text' class='form-control' name='name' id='name" + id_count + "' placeholder='Nazwa produktu'></td>\
<td><input type='number' class='form-control' onchange='count_changed(" + id_count + ")' name='count' id='count" + id_count + "' value='1' placeholder='Liczba produktów'></td>\
<td><input type='text' class='form-control' onchange='change_brutto(" + id_count + ")' name='price_netto' id='price_netto" + id_count + "' oninput='netto_changed()' value='0.00' placeholder='Cena netto'></td>\
<td class='input-group'><input type='text' class='form-control' onchange='vat_changed(" + id_count + ")' name='vat_rate' id='vat_rate" + id_count + "' value='23' placeholder='Stawka VAT'>\
<span class='input-group-addon'>%</span>\
</td>\
<td><input type='text' class='form-control' name='price_brutto' id='price_brutto" + id_count + "' oninput='brutto_changed()' value='0.00' placeholder='Stawka brutto'></td>\
<td><input type='text' class='form-control' name='summary_entity[]' id='summary" + id_count + "' value='0.00' readonly></td>\
<td><button type='button' onclick='delete_product(" + id_count + ")' class='btn btn-alert'>Usuń</button></td>\
</tr>";
}, false);
}
<table id="products_table" class="table table-bordered">
<tr>
<th>Nazwa produktu</th>
<th style="width: 7%;">Liczba produktów</th>
<th style="width: 10%;">Cena jednostkowa netto</th>
<th style="width: 10%;">Stawka VAT</th>
<th style="width: 10%;">Cena jednostkowa brutto</th>
<th style="width: 10%;">Wartość końcowa brutto</th>
<th style="width: 10%;">Akcje</th>
</tr>
<tr id="1">
<td><input type="text" class="form-control" name="name" id="name1" placeholder="Nazwa produktu"></td>
<td><input type="number" class="form-control" onchange="count_changed(1)" name="count" id="count1" value="1" placeholder="Liczba produktów"></td>
<td><input type="text" class="form-control" onchange="change_brutto(1)" name="price_netto" id="price_netto1" value="0.00" placeholder="Cena netto"></td>
<td class="input-group"><input type="text" class="form-control" onchange="vat_changed(1)" name="vat_rate" id="vat_rate1" value="23" placeholder="Stawka VAT">
<span class="input-group-addon">%</span>
</td>
<td><input type="text" class="form-control" onchange="change_netto(1)" name="price_brutto" id="price_brutto1" value="0.00" placeholder="Cena brutto"></td>
<td><input type="text" class="form-control" name="summary_entity[]" id="summary1" value="0.00" readonly></td>
<td><button type="button" onclick="delete_product(1)" class="btn btn-alert">Usuń</button></td>
</tr>
</table>
<table class="table table-bordered">
<tr>
<td style="width: 60%; text-align: right;">Razem do zapłaty: </td>
<td style="text-align: left;" name="summary" id="summary"></td>
</tr>
</table>
<button type="button" id="add_product" class="btn btn-success">Dodaj produkt</button>
The problem is:
your <tr> tags must be put inside <tbody>. Because you are missing it, so whenever you add a new <tr>, new <tbody> will automatically added and warpped around the <tr>. But one <table>, only have 1 <tbody>, adding more than 1 causing the entire table to reload.
Solution:
Create a <tbody> tag inside your table, give it an ID.
Whenever you want to insert new row, insert into that <tbody> instead
<table>
<tbody id="products_table">
</tbody>
</table>
Leo's answer is probably the best you should do, but I found an other way.
I used the insertRow and insertCell functions that append things without reloading the table.
Here's a working example (you can run it using the run code snippet at the bottom):
var id_count = 1;
var price_summary = 0;
function delete_product(id) {
document.getElementById(id).remove();
}
function change_brutto(id) {
var netto = replace_dots(document.getElementById('price_netto' + id));
var vat = replace_dots(document.getElementById('vat_rate' + id));
var count = replace_dots(document.getElementById('count' + id));
if (vat > 0) {
vat = vat / 100;
vat += 1;
var calc = netto * vat;
document.getElementById('price_brutto' + id).value =
Math.round((calc + Number.EPSILON) * 100) / 100;
calc = calc * count;
document.getElementById('summary' + id).value =
Math.round((calc + Number.EPSILON) * 100) / 100;
} else if (vat == '' || vat == 0) {
document.getElementById('vat_rate' + id).value = '0';
document.getElementById('price_brutto' + id).value = netto;
document.getElementById('summary' + id).value = netto * count;
} else {
alert('Wpisz poprawną stawkę VAT');
}
}
function change_netto(id) {
var brutto = replace_dots(document.getElementById('price_brutto' + id));
var vat = replace_dots(document.getElementById('vat_rate' + id));
if (vat > 0) {
vat = vat / 100;
vat += 1;
var calc = brutto / vat;
document.getElementById('price_netto' + id).value =
Math.round((calc + Number.EPSILON) * 100) / 100;
} else if (vat == '' || vat == 0) {
document.getElementById('vat_rate' + id).value = '0';
document.getElementById('price_netto' + id).value = brutto;
} else {
alert('Wpisz poprawną stawkę VAT');
}
}
function replace_dots(string) {
newString = string.value.replace(',', '.');
return newString;
}
function vat_changed(id) {
if (document.getElementById('price_netto' + id).value != '') {
change_brutto(id);
} else if (document.getElementById('price_brutto' + id).value != '') {
change_netto(id);
}
}
function count_changed(id) {
var count = replace_dots(document.getElementById('count' + id));
var brutto = replace_dots(document.getElementById('price_brutto' + id));
var summ = document.getElementsByName('summary_entity[]');
document.getElementById('summary' + id).value = brutto * count;
for (var i = 0; i < summ.length; i++) {
var val = summ[i];
price_summary += parseFloat(val.value);
}
document.getElementById('summary').innerHTML = price_summary;
}
function summary() {}
window.onload = function () {
var btn = document.getElementById('add_product');
btn.addEventListener(
'click',
function () {
id_count += 1;
let table = document.getElementById('products_table');
let row = table.insertRow();
row.id = id_count;
let cell0 = row.insertCell();
cell0.innerHTML =
"<td><input type='text' class='form-control' name='name' id='name" +
id_count +
"' placeholder='Nazwa produktu'></td>";
let cell1 = row.insertCell();
cell1.innerHTML =
"<td><input type='number' class='form-control' onchange='count_changed(" +
id_count +
")' name='count' id='count" +
id_count +
"' value='1' placeholder='Liczba produktów'></td>";
let cell2 = row.insertCell();
cell2.innerHTML =
"<td><input type='text' class='form-control' onchange='change_brutto(" +
id_count +
")' name='price_netto' id='price_netto" +
id_count +
"' oninput='netto_changed()' value='0.00' placeholder='Cena netto'></td>";
let cell3 = row.insertCell();
cell3.innerHTML =
"<td class='input-group'><input type='text' class='form-control' onchange='vat_changed(" +
id_count +
")' name='vat_rate' id='vat_rate" +
id_count +
"' value='23' placeholder='Stawka VAT'><span class='input-group-addon'>%</span></td>";
let cell4 = row.insertCell();
cell4.innerHTML =
"<td><input type='text' class='form-control' name='price_brutto' id='price_brutto" +
id_count +
"' oninput='brutto_changed()' value='0.00' placeholder='Stawka brutto'></td>";
let cell5 = row.insertCell();
cell5.innerHTML =
"<td><input type='text' class='form-control' name='summary_entity[]' id='summary" +
id_count +
"' value='0.00' readonly></td>";
let cell6 = row.insertCell();
cell6.innerHTML =
"<td><button type='button' onclick='delete_product(" +
id_count +
")' class='btn btn-alert'>Usuń</button></td>";
},
false
);
};
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="lib/style.css">
<script src="lib/script.js"></script>
</head>
<body>
<table id="products_table" class="table table-bordered">
<tr>
<th >Nazwa produktu</th>
<th style="width: 7%;">Liczba produktów</th>
<th style="width: 10%;">Cena jednostkowa netto</th>
<th style="width: 10%;">Stawka VAT</th>
<th style="width: 10%;">Cena jednostkowa brutto</th>
<th style="width: 10%;">Wartość końcowa brutto</th>
<th style="width: 10%;">Akcje</th>
</tr>
<tr id="1">
<td><input type="text" class="form-control" name="name" id="name1" placeholder="Nazwa produktu"></td>
<td><input type="number" class="form-control" onchange="count_changed(1)" name="count" id="count1" value="1" placeholder="Liczba produktów"></td>
<td><input type="text" class="form-control" onchange="change_brutto(1)" name="price_netto" id="price_netto1" value="0.00" placeholder="Cena netto"></td>
<td class="input-group"><input type="text" class="form-control" onchange="vat_changed(1)" name="vat_rate" id="vat_rate1" value="23" placeholder="Stawka VAT">
<span class="input-group-addon">%</span>
</td>
<td><input type="text" class="form-control" onchange="change_netto(1)" name="price_brutto" id="price_brutto1" value="0.00" placeholder="Cena brutto"></td>
<td><input type="text" class="form-control" name="summary_entity[]" id="summary1" value="0.00" readonly></td>
<td><button type="button" onclick="delete_product(1)" class="btn btn-alert">Usuń</button></td>
</tr>
</table>
<table class="table table-bordered">
<tr>
<td style="width: 60%; text-align: right;">Razem do zapłaty: </td>
<td style="text-align: left;" name="summary" id="summary"></td>
</tr>
</table>
<button type="button" id="add_product" class="btn btn-success">Dodaj produkt</button>
</body>
</html>

Alert message won't work using jquery

I created a form with the code below. There is a problem that I am unable to solve. The problem is the alert message won't work when the submit button is clicked.
$(document).ready(function() {
$("#btn_id").click(function() {
var valid = validate();
var name_order = $("#name").val();
var address_order = $("#address").val();
var city_order = $("#city").val();
var state_order = $("#state").val();
var zipcode_order = $("#zipcode_id").val();
var phone_order = $("#phone_id").val();
var email_order = $("#emailid").val();
var randID_order = $("#generateID").val();
var ICCID_order = $("#ID").val();
if (valid) {
$("form[name='workorder']").submit();
alert(" Name :" + name_order + " \n Address : " + address_order +
" \n City : " + city_order + " \n State: " + state_order +
" \n Zipcode: " + zipcode_order + " \n Phone: " + phone +
" \n Email: " + email_order + " \n ID: " + randID_order +
" \n SIM Card: " + ICCID_order)
}
});
// Give Alert if field not enter
function validate() {
if (document.workorder.name.value == "") {
alert("Please provide your Name!")
document.workorder.name.focus();
return false;
}
if (document.workorder.address.value == "") {
alert("Please provide your Address!")
document.workorder.address.focus();
return false;
}
if (document.workorder.city.value == "") {
alert("Please provide your City!")
document.workorder.city.focus();
return false
}
if (document.workorder.state.value == "-1") {
alert("Please select your State!")
document.workorder.state.focus();
return false
}
if (document.workorder.zipcode.value == " ") {
alert("Please provide your Zipcode!")
document.workorder.zipcode.focus();
return false;
}
if (document.workorder.phone.value == " ") {
alert("Please provide your Phone!")
document.workorder.zipcode.focus();
return false;
}
var email = document.workorder.emailid.value;
atpos = email.indexOf("#")
dotpos = email.lastIndexOf(".")
if (email == " " || atpos < 1 || (dotpos - atpos < 2)) {
alert("Please provide your Zipcode!")
document.workorder.emailid.focus();
return false;
}
console.log("validated");
return (true);
}
// Generate an random ID
function randomString() {
var string_length = 8;
var chars = "abcdefghijklmnopqrstuvwvxyz012345678";
var text = " ";
for (var i = 0; i < string_length; i++) {
var rnum = Math.floor(Math.random() * chars.length);
text += chars.substring(rnum, rnum + 1);
}
document.workorder.randomfield.value = text;
}
// Generate box with ID and CCID
function getData() {
var fs = require('fs');
var ICCID = require('./masterlist.json')
if (ICCID.length != 0) {
var index = Math.floor(Math.random() * ICCID.length);
var pickedID = ICCID[index];
ICCID.splice(index, 1); // This removes the picked element from the array
fs.writeFile("masterlist.json", JSON.stringify(ICCID), function(err) {
if (err) {
return consolo.log(err);
}
});
} else {
console.log("Sorry, There is no more ICCID to complete the form");
}
document.workorder.ID.value = pickedID
}
});
<html>
<head>
<title>Work Order Form</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js">
</script>
<script type="text/javascript" src="validate.js"></script>
</head>
<body>
<form action="#" name="workorder" id="form_id">
<table cellpadding="2" width="300" height="300" bgcolor=g reen align="center" cellspaceing="2">
<tr>
<td colspan=2>
<center>
<fontsize=4><b>Work Order Form</b>
</font>
</center>
</td>
</tr>
<tr>
<td>Name</td>
<td>
<input type="text" name="name" id="name" size="30" align="center">
</td>
</tr>
<tr>
<td>Address</td>
<td>
<input type="text" name="address" id="adress" size="30">
</td>
</tr>
<tr>
<td>City</td>
<td>
<input type="text" name="city" id="city" size="30">
</td>
</tr>
<tr>
<td>State</td>
<td>
<select name="state">
<option value="-1" selected>select..</option>
<option value="Alabam">AL</option>
<option value="Alaska">AK</option>
<option value="Arizona">AZ</option>
<option value="Arkansa">AR</option>
<option value="California">CA</option>
<option value="Colorado">CO</option>
<option value="Connecticut">CT</option>
<option value="Delaware">DE</option>
<option value="Florida">FL</option>
<option value="Georgia">GA</option>
<option value="Hawaii">HI</option>
<option value="Idaho">ID</option>
<option value="Illinois">IL</option>
<option value="Indiana">IN</option>
<option value="Iowa">IA</option>
<option value="Kansas">KS</option>
<option value="Kentucky">KY</option>
<option value="Louisiana">LA</option>
<option value="Maine">ME</option>
<option value="Maryland">MD</option>
<option value="Michigan">MI</option>
<option value="Minnesota">MN</option>
<option value="Mississpi">MS</option>
<option value="Missori">MO</option>
<option value="Montana">MT</option>
<option value="Nebraska">NE</option>
<option value="Nevada">NV</option>
<option value="New Hampshire">NH</option>
<option value="New Jersey">NJ</option>
<option value="New Mexico">NM</option>
<option value="New York">NY</option>
<option value="Nortj Carolina">NC</option>
<option value="North Dakota">ND</option>
<option value="Ohio">OH</option>
<option value="Oklahoma">OK</option>
<option value="Oregon">OR</option>
<option value="Pennsylvania">PA</option>
<option value="Rhode Island">RI</option>
<option value="South Carolina">SC</option>
<option value="South Dakota">SD</option>
<option value="Tennessee">TN</option>
<option value="Texas">TX</option>
<option value="Utah">UT</option>
<option value="Vermont">VT</option>
<option value="Virgina">VA</option>
<option value="Washington">WA</option>
<option value="West Virgina">WV</option>
<option value="Wisconsin">WI</option>
<option value="Wyoming">WY</option>
</select>
</td>
<tr>
<td>Zipcode</td>
<td>
<input type="text" name="zipcode" id="zipcode_id" size="30">
</td>
</tr>
<tr>
<td>Phone</td>
<td>
<input type="text" name="phone" id="phone_id" size="30">
</td>
</tr>
<tr>
<td>Email</td>
<td>
<input type="text" name="email" id="emailid" size="30">
</td>
</tr>
<tr>
<td>
<input type="reset">
</td>
<td>
<button name="sumbit" type="submit" id="btn_id" onlick="randomString(); getData();">Submit</button>
</td>
</tr>
<tr>
<td>
<name="randomfield" id="generateID" value=" ">
</td>
<td>
<name="ID" id="ID" value=" ">
</td>
</tr>
</form>
</table>
</body>
When you sumbit() the form, you leave the page. The alert() never fires! Try changing the code to:
if (valid)
{
alert(" Name :" + name_order + " \n Address : " + address_order +
" \n City : " + city_order + " \n State: " + state_order+
" \n Zipcode: " + zipcode_order + " \n Phone: " + phone +
" \n Email: "+ email_order + " \n ID: " + randID_order +
" \n SIM Card: " + ICCID_order);
$("form[name='workorder']").submit();
}
instead of $(button).click() use $(form).submit for your listener
in your code the form does not have a post location. You can add a return false to the bottom of the submit anonymous function for now
you have a reference to a variable "phone" in your alert call that is not defined
$("form#form_id").submit(function() {
var valid = validate();
var name_order = $("#name").val();
var address_order = $("#address").val();
var city_order = $("#city").val();
var state_order = $("#state").val();
var zipcode_order = $("#zipcode_id").val();
var phone_order = $("#phone_id").val();
var email_order = $("#emailid").val();
var randID_order = $("#generateID").val();
var ICCID_order = $("#ID").val();
if (valid) {
// you don't need to manually submit it since we attached to the submit listener above instead of click
// $("form[name='workorder']").submit();
alert(" Name :" + name_order + " \n Address : " + address_order +
" \n City : " + city_order + " \n State: " + state_order +
" \n Zipcode: " + zipcode_order + " \n Phone: " + phone_order + // you had a bad reference here
" \n Email: " + email_order + " \n ID: " + randID_order +
" \n SIM Card: " + ICCID_order)
}
// return false until you put in a proper post location
return false;
});
I fixed all these in an example at https://jsfiddle.net/algorithmicMoose/n0t83ees/ with comments

Jquery .on(change) event on <select> input only changes first row.

I have a table whereby people can add rows.
There is a select input in the table that when changed, changes the values in a second select field via ajax.
The problem I have is that if a person adds an additional row to the table, the .on(change) event alters the second field in the first row, not the subsequent row.
I've been racking my brain, trying to figure out if I need to (and if so how to) dynamically change the div id that the event binds to and the div that it affects. Is this the solution? If so, could someone please demonstrate how I'd achieve this?
The HTML form is
<form action="assets.php" method="post">
<button type="button" id="add">Add Row</button>
<button type="button" id="delete">Remove Row</button>
<table id="myassettable">
<tbody>
<tr>
<th>Asset Type</th>
<th>Manufacturer</th>
<th>Serial #</th>
<th>MAC Address</th>
<th>Description</th>
<th>Site</th>
<th>Location</th>
</tr>
<tr class="removable">
<!--<td><input type="text" placeholder="First Name" name="contact[0][contact_first]"></td>
<td><input type="text" placeholder="Surname" name="contact[0][contact_surname]"></td>-->
<td><select name="asset[0][type]">
<option><?php echo $typeoption ?></option>
</select></td>
<td><select class="manuf_name" name="asset[0][manuf]">
<option><?php echo $manufoption ?></option>
</select></td>
<td><input type="text" placeholder="Serial #" name="asset[0][serial_num]"></td>
<td><input type="text" placeholder="Mac Address" name="asset[0][mac_address]"></td>
<td><input type="text" placeholder="Name or Description" name="asset[0][description]"></td>
<td><select id="site" name="asset[0][site]">
<option><?php echo $siteoption ?></option>
</select></td>
<td><input type="text" placeholder="e.g Level 3 Utility Room" name="asset[0][location]"></td>
<td><select id="new_select" name="asset[0][contact]"></select></td>
<!--<td><input type="email" placeholder="Email" name="contact[0][email]"></td>
<td><input type="phone" placeholder="Phone No." name="contact[0][phone]"></td>
<td><input type="text" placeholder="Extension" name="contact[0][extension]"></td>
<td><input type="phone" placeholder="Mobile" name="contact[0][mobile]"></td>-->
</tr>
</tbody>
</table>
<input type="submit" value="Submit">
<input type="hidden" name="submitted" value="TRUE" />
</form>
The script I have is
<script type="text/javascript">
$(document).ready(function() {
$("#add").click(function() {
var newgroup = $('#myassettable tbody>tr:last');
newgroup
.clone(true)
.find("input").val("").end()
.insertAfter('#myassettable tbody>tr:last')
.find(':input')
.each(function(){
this.name = this.name.replace(/\[(\d+)\]/,
function(str,p1) {
return '[' + (parseInt(p1,10)+1)+ ']'
})
})
return false;
});
});
$(document).ready(function() {
$("#delete").click(function() {
var $last = $('#myassettable tbody').find('tr:last')
if ($last.is(':nth-child(2)')) {
alert('This is the only one')
} else {
$last.remove()
}
});
});
$(document).ready(function() {
$("#myassettable").on("change","#site",function(event) {
$.ajax ({
type : 'post',
url : 'assetprocess.php',
data: {
get_option : $(this).val()
},
success: function (response) {
document.getElementById("new_select").innerHTML=response;
}
})
});
});
</script>
and the assetprocess.php page is
<?php
if(isset($_POST['get_option'])) {
//Get the Site Contacts
$site = $_POST['get_option'];
$contact = "SELECT site_id, contact_id, AES_DECRYPT(contact_first,'" .$kresult."'),AES_DECRYPT(contact_surname,'" .$kresult."') FROM contact WHERE site_id = '$site' ORDER BY contact_surname ASC";
$contactq = mysqli_query($dbc,$contact) or trigger_error("Query: $contact\n<br />MySQL Error: " .mysqli_errno($dbc));
if ($contactq){
//$contactoption = '';
echo '<option>Select a Contact (Optional)</option>';
while ($contactrow = mysqli_fetch_assoc($contactq)) {
$contactid = $contactrow['contact_id'];
$contactfirst = $contactrow["AES_DECRYPT(contact_first,'" .$kresult."')"];
$contactsurname = $contactrow["AES_DECRYPT(contact_surname,'" .$kresult."')"];
$contactoption .= '<option value="'.$contactid.'">'.$contactsurname.', '.$contactfirst.'</option>';
echo $contactoption;
}
}
exit;
}
?>
The code is ugly as sin, but this is only a self-interest project at this stage.
Any assistance would be greatly appreciated.
Cheers,
J.
Working Example: https://jsfiddle.net/Twisty/1c98Ladh/3/
A few minor HTML changes:
<form action="assets.php" method="post">
<button type="button" id="add">Add Row</button>
<button type="button" id="delete">Remove Row</button>
<table id="myassettable">
<tbody>
<tr>
<th>Asset Type</th>
<th>Manufacturer</th>
<th>Serial #</th>
<th>MAC Address</th>
<th>Description</th>
<th>Site</th>
<th>Location</th>
</tr>
<tr class="removable">
<td>
<select name="asset[0][type]">
<option>---</option>
<option>Type Option</option>
</select>
</td>
<td>
<select class="manuf_name" name="asset[0][manuf]">
<option>---</option>
<option>
Manuf Option
</option>
</select>
</td>
<td>
<input type="text" placeholder="Serial #" name="asset[0][serial_num]">
</td>
<td>
<input type="text" placeholder="Mac Address" name="asset[0][mac_address]">
</td>
<td>
<input type="text" placeholder="Name or Description" name="asset[0][description]">
</td>
<td>
<select id="site-0" class="chooseSite" name="asset[0][site]">
<option>---</option>
<option>
Site Option
</option>
</select>
</td>
<td>
<input type="text" placeholder="e.g Level 3 Utility Room" name="asset[0][location]">
</td>
<td>
<select id="new-site-0" name="asset[0][contact]">
</select>
</td>
</tr>
</tbody>
</table>
<input type="submit" value="Submit">
<input type="hidden" name="submitted" value="TRUE" />
</form>
This prepares the id to be incrementd as we add on new elements. Making use of the class, we can bind a .change() to each of them.
$(document).ready(function() {
$("#add").click(function() {
var newgroup = $('#myassettable tbody>tr:last');
newgroup
.clone(true)
.find("input").val("").end()
.insertAfter('#myassettable tbody>tr:last')
.find(':input')
.each(function() {
this.name = this.name.replace(/\[(\d+)\]/,
function(str, p1) {
return '[' + (parseInt(p1, 10) + 1) + ']';
});
});
var lastId = parseInt(newgroup.find(".chooseSite").attr("id").substring(5), 10);
newId = lastId + 1;
$("#myassettable tbody>tr:last .chooseSite").attr("id", "site-" + newId);
$("#myassettable tbody>tr:last select[id='new-site-" + lastId + "']").attr("id", "new-site-" + newId);
return false;
});
$("#delete").click(function() {
var $last = $('#myassettable tbody').find('tr:last');
if ($last.is(':nth-child(2)')) {
alert('This is the only one');
} else {
$last.remove();
}
});
$(".chooseSite").change(function(event) {
console.log($(this).attr("id") + " changed to " + $(this).val());
var target = "new-" + $(this).attr('id');
/*$.ajax({
type: 'post',
url: 'assetprocess.php',
data: {
get_option: $(this).val()
},
success: function(response) {
$("#" + target).html(response);
}
});*/
var response = "<option>New</option>";
$("#" + target).html(response);
});
});
Can save some time by setting a counter in global space for the number of Rows, something like var trCount = 1; and use that to set array indexes and IDs. Cloning is fast and easy, but it also means we have to go back and append various attributes. Could also make a function to draw up the HTML for you. Like: https://jsfiddle.net/Twisty/1c98Ladh/10/
function cloneRow(n) {
if (n - 1 < 0) return false;
var html = "";
html += "<tr class='removable' data-row=" + n + ">";
html += "<td><select name='asset[" + n + "][type]' id='type-" + n + "'>";
html += $("#type-" + (n - 1)).html();
html += "<select></td>";
html += "<td><select name='asset[" + n + "][manuf]' id='manuf-" + n + "'>";
html += $("#manuf-" + (n - 1)).html();
html += "<select></td>";
html += "<td><input type='text' placeholder='Serial #' name='asset[" + n + "][serial_num]' id='serial-" + n + "' /></td>";
html += "<td><input type='text' placeholder='MAC Address' name='asset[" + n + "][mac_address]' id='mac-" + n + "' /></td>";
html += "<td><input type='text' placeholder='Name or Desc.' name='asset[" + n + "][description]' id='desc-" + n + "' /></td>";
html += "<td><select name='asset[" + n + "][site]' class='chooseSite' id='site-" + n + "'>";
html += $("#site-" + (n - 1)).html();
html += "<select></td>";
html += "<td><input type='text' placeholder='E.G. Level 3 Utility Room' name='asset[" + n + "][location]' id='loc-" + n + "' /></td>";
html += "<td><select name='asset[" + n + "][contact]' id='contact-" + n + "'><select></td>";
html += "</tr>";
return html;
}
It's more work up front, yet offers a lot more control of each part. And much easier to use later.

Categories

Resources