I have a running code snippet that dynamically adds input boxes to a form that is working so fine, however, am trying to get totals of the values from the input boxes but nothing seem to be working. The total area is only showing 0 but not giving me correct results.
Here is my code:
JAVASCRIPT TO DISPLAY THE TABLE WITH FORM
$(document).ready(function(){
$(document).on('click', '.add', function(){
var html = '';
html += '<tr>';
html += '<td><input type="text" name="item_name[]" class="form-control item_name" /></td>';
html += '<td><input class="qty" type="text" value="0" data-cubics="500"/></td>';
html += '<td><select name="item_unit[]" class="form-control item_unit"><option value="">Select Unit</option><?php echo fill_unit_select_box($connect); ?></select></td>';
html += '<td width="33%"><span class="cubics"></span>';
html += '<td><button type="button" name="remove" class="btn btn-danger btn-sm remove"><span class="glyphicon glyphicon-minus"></span></button></td></tr>';
$('#item_table').append(html);
});
JAVASCRIPT TO DO THE MATH
<script>
function total() {
var total1 = 0;
$('span.cubics').each(function () {
var n = parseFloat($(this).text());
total1 += isNaN(n) ? 0 : n;
});
$('.totalcubics').text(total1.toFixed(2));
}
$('input.qty').keyup(function () {
var val = parseFloat($(this).val());
val = (val ? val * $(this).data('cubics') : '');
$(this).closest('td').next().find('span.cubics').text(val);
total();
});
var $form = $('#insert_form'),
$summands = $form.find('input.qty'),
$sumDisplay = $('span#totalquantity');
$form.keyup(function () {
var sum = 0;
$summands.each(function () {
var value = Number($(this).val());
if (!isNaN(value)) sum += value;
});
$sumDisplay.text(sum);
});
$('input').on({
focus: function () {
if (this.value == '0') this.value = '';
},
blur: function () {
if (this.value === '') this.value = '0';
}
});
</script>
HTML CODE TO DISPLAY TOTALS
<tr class="bg">
<td width="33%">TOTAL</td>
<td width="33%"><span id="totalquantity"></span>
</td>
<td width="33%"><span class="totalcubics"></span>
</td>
</tr>
Any assistance to my problem is highly appreciated
I think your problem in
$(this).closest('td').next().find('span.cubics').text(val);
this mean go to the next td and find the span and there is no span in the next td .. you can use
$(this).closest('tr').find('span.cubics').text(val);
or
$(this).closest('td').next().next().find('span.cubics').text(val);
and while you append the row dynamically you need to use
$(document).on('keyup' , 'input.qty' , function () {
instead of
$('input.qty').keyup(function () {
You need to recreate $summands each time you add a row to the table. Insert the line to do so after adding the row.
$(document).ready(function() {
$(document).on('click', '.add', function() {
var html = '';
html += '<tr>';
html += '<td><input type="text" name="item_name[]" class="form-control item_name" /></td>';
html += '<td><input class="qty" type="text" value="0" data-cubics="500"/></td>';
html += '<td><select name="item_unit[]" class="form-control item_unit"><option value="">Select Unit</option><?php echo fill_unit_select_box($connect); ?></select></td>';
html += '<td width="33%"><span class="cubics"></span>';
html += '<td><button type="button" name="remove" class="btn btn-danger btn-sm remove"><span class="glyphicon glyphicon-minus"></span></button></td></tr>';
$('#item_table').append(html);
$summands = $form.find('input.qty'); //*************** add this line
});
function total() {
var total1 = 0;
$('span.cubics').each(function () {
var n = parseFloat($(this).text());
total1 += isNaN(n) ? 0 : n;
});
$('.totalcubics').text(total1.toFixed(2));
}
$('input.qty').keyup(function () {
var val = parseFloat($(this).val());
val = (val ? val * $(this).data('cubics') : '');
$(this).closest('td').next().find('span.cubics').text(val);
total();
});
var $form = $('#insert_form'),
$summands = $form.find('input.qty'),
$sumDisplay = $('span#totalquantity');
$form.keyup(function () {
var sum = 0;
$summands.each(function () {
var value = Number($(this).val());
if (!isNaN(value)) sum += value;
});
$sumDisplay.text(sum);
});
$('input').on(
{
focus: function () {
if (this.value == '0') this.value = '';
},
blur: function () {
if (this.value === '') this.value = '0';
}
});
}); // end of document ready
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="insert_form" onsubmit="return false">
<table>
<tr class="bg">
<td width="33%">TOTAL</td>
<td width="33%"><span id="totalquantity"></span></td>
<td width="33%"><span class="totalcubics"></span></td>
</tr>
</table>
<button type="button" class="add">add</button>
<table id="item_table">
</table>
</form>
At the moment you are creating summands collection with no elements, before any rows have been added.
With the help of #tracktor53, i managed to get a fix for my problem, below is my updated code;
$(document).on('click', '.add', function(){
var html = '';
html += '<tr>';
html += '<td><input type="text" name="item_name[]" class="form-control item_name" /></td>';
html += '<td><select name="item_unit[]" class="form-control item_unit"><option value="">Select Unit</option><?php echo fill_unit_select_box($connect); ?></select></td>';
html += '<td><input class="qty" type="text" value="0"/></td>';
html += '<td width="33%"><span class="cubics"></span>';
html += '<td><button type="button" name="remove" class="btn btn-danger btn-sm remove"><span class="glyphicon glyphicon-minus"></span></button></td></tr>';
$('#item_table').append(html);
$summands = $form.find('input.qty'); //*************** added this line
});
And with #mohamed's help, this line $(this).closest('td').next().find('span.cubics').text(val); was looking for the next <td> which in actual sense, the next <td> was an input field but not the one with <span id='cubics'></span> so, i had to adjust that to this;
html += '<td><input class="qty" type="text" value="0"/></td>';
html += '<td width="33%"><span class="cubics"></span>';
Then after i had to use
$(document).on('keyup' , 'input.qty' , function () {
instead of
$('input.qty').keyup(function () {
Now everything is working fine only that i want to multiply select option values with qty input from this line;
html += '<td><select name="item_unit[]" class="form-control item_unit"><option value="">Select Unit</option><?php echo fill_unit_select_box($connect); ?></select></td>'
Any further assistance about this is highly welcome
Related
Autocomplete jQuery UI only works the first row of table.
I'm working on a pharmacy search engine form with the Autocomplete jQuery UI on Bootstrap, the problem is that the autocomplete only works the first row. When i click add button it create a new row but in new row it do not work.
My jQuery syntax is as:
$("#itemSearch").autocomplete({
source: "{{ route('autoCompSearch') }}",
minLength:3,
select: function(key, value){
console.log(key, value);
},
});
My addRow() is as following;
$('#journalRows').on('keydown', '#addRow',function(event){
// alert('you are here...');
count++;
dynamic_field(count);
return true;
}
and my dynamic_filed(count) function is as;
function dynamic_field(number)
{
// New Function to add New Row in Journal
var html = '';
html += '<tr class="options" name="line_items">'
html += '<td width="5%"><input type="text" id="checkbox. $user->id ." name="id[]" class="form-control" value="" disabled=""></td>'
html += '<td width="15%"><input type="text" name="barcode_id[]" id="barcodeSearch" class="form-control"></td>'
html += '<td width="30%"><input type="text" name="item_id[]" id="itemSearch" class="form-control select-product"></td>'
html += '<td width="5%"><input type="text" name="qty[]" value="1" class="form-control calc" onkeyup="InvoiceCalculation()"></td>'
html += '<td width="10%"><input type="text" id="sal_price" value="1" name="sal_price[]" class="form-control calc" onkeyup="InvoiceCalculation()"></td>'
html += '<td width="5%"><input type="text" name="discPer[]" class="form-control" value="0" placeholder="Discount percentage..." onkeyup="InvoiceCalculation()"></td>'
html += '<td width="15%"><input type="text" id="totUnitAmount" name="totUnitAmount[]" class="form-control form-control-sm" value="0"></td>'
html += '<td><input type="button" id="addRow" name="addRow[]" class="form-control btn btn-success" value="+"></td>'
html += '<td><input type="button" id="removeRow" name="removeRow[]" class="form-control btn btn-danger" value="-"></td>';
html += '</tr>';
$('#journalRows').append(html);
};
This is works but only autocomplete option is not working in second and onward rows.....
For new row you need to change the Id of the autocomplete field. Each autocomplete field should have a unique id:
$("#itemSearch").autocomplete({
source: "{{ route('autoCompSearch') }}",
minLength:3,
select: function(key, value){
console.log(key, value);
},
});
$("#itemSearch1").autocomplete({
source: "{{ route('autoCompSearch') }}",
minLength:3,
select: function(key, value){
console.log(key, value);
},
});
Also you need to initialise autocomplete module on the field after it's created, otherwise it won't be in the DOM and jQuery won't work for the field
UPDATE:
change your dynamic_field function as follows:
function dynamic_field(number)
{
// New Function to add New Row in Journal
var html = '';
html += '<tr class="options" name="line_items">'
html += '<td width="5%"><input type="text" id="checkbox. $user->id ." name="id[]" class="form-control" value="" disabled=""></td>'
html += '<td width="15%"><input type="text" name="barcode_id[]" id="barcodeSearch" class="form-control"></td>'
html += '<td width="30%"><input type="text" name="item_id[]" id="itemSearch-'+number+'" class="form-control select-product"></td>'
html += '<td width="5%"><input type="text" name="qty[]" value="1" class="form-control calc" onkeyup="InvoiceCalculation()"></td>'
html += '<td width="10%"><input type="text" id="sal_price" value="1" name="sal_price[]" class="form-control calc" onkeyup="InvoiceCalculation()"></td>'
html += '<td width="5%"><input type="text" name="discPer[]" class="form-control" value="0" placeholder="Discount percentage..." onkeyup="InvoiceCalculation()"></td>'
html += '<td width="15%"><input type="text" id="totUnitAmount" name="totUnitAmount[]" class="form-control form-control-sm" value="0"></td>'
html += '<td><input type="button" id="addRow" name="addRow[]" class="form-control btn btn-success" value="+"></td>'
html += '<td><input type="button" id="removeRow" name="removeRow[]" class="form-control btn btn-danger" value="-"></td>';
html += '</tr>';
$('#journalRows').append(html);
$("#itemSearch-"+number).autocomplete({
source: "{{ route('autoCompSearch') }}",
minLength:3,
select: function(key, value){
console.log(key, value);
},
});
};
This is actually for a shop receipt but i need to regenerate it into a school receipt. ie, i need the tax1 value auto generate as 5% and tax2 auto genetrate as 6% and calculate it
and also no quantity needed.
<script>
$(document).ready(function(){
var final_total_amt = $('#final_total_amt').text();
var count = 1;
$(document).on('click', '#add_row', function(){
count++;
$('#total_item').val(count);
var html_code = '';
html_code += '<tr id="row_id_'+count+'">';
html_code += '<td><span id="sr_no">'+count+'</span></td>';
html_code += '<td><input type="text" name="item_name[]" id="item_name'+count+'" class="form-control input-sm" /></td>';
html_code += '<td><input type="text" name="order_item_quantity[]" id="order_item_quantity'+count+'" data-srno="'+count+'" class="form-control input-sm number_only order_item_quantity" /></td>';
html_code += '<td><input type="text" name="order_item_price[]" id="order_item_price'+count+'" data-srno="'+count+'" class="form-control input-sm number_only order_item_price" /></td>';
html_code += '<td><input type="text" name="order_item_actual_amount[]" id="order_item_actual_amount'+count+'" data-srno="'+count+'" class="form-control input-sm order_item_actual_amount" readonly /></td>';
html_code += '<td><input type="text" name="order_item_tax1_rate[]" id="order_item_tax1_rate'+count+'" data-srno="'+count+'" class="form-control input-sm number_only order_item_tax1_rate" /></td>';
html_code += '<td><input type="text" name="order_item_tax1_amount[]" id="order_item_tax1_amount'+count+'" data-srno="'+count+'" readonly class="form-control input-sm order_item_tax1_amount" /></td>';
html_code += '<td><input type="text" name="order_item_tax2_rate[]" id="order_item_tax2_rate'+count+'" data-srno="'+count+'" class="form-control input-sm number_only order_item_tax2_rate" /></td>';
html_code += '<td><input type="text" name="order_item_tax2_amount[]" id="order_item_tax2_amount'+count+'" data-srno="'+count+'" readonly class="form-control input-sm order_item_tax2_amount" /></td>';
html_code += '<td><input type="text" name="order_item_tax3_rate[]" id="order_item_tax3_rate'+count+'" data-srno="'+count+'" class="form-control input-sm number_only order_item_tax3_rate" /></td>';
html_code += '<td><input type="text" name="order_item_tax3_amount[]" id="order_item_tax3_amount'+count+'" data-srno="'+count+'" readonly class="form-control input-sm order_item_tax3_amount" /></td>';
html_code += '<td><input type="text" name="order_item_final_amount[]" id="order_item_final_amount'+count+'" data-srno="'+count+'" readonly class="form-control input-sm order_item_final_amount" /></td>';
html_code += '<td><button type="button" name="remove_row" id="'+count+'" class="btn btn-danger btn-xs remove_row">X</button></td>';
html_code += '</tr>';
$('#invoice-item-table').append(html_code);
});
$(document).on('click', '.remove_row', function(){
var row_id = $(this).attr("id");
var total_item_amount = $('#order_item_final_amount'+row_id).val();
var final_amount = $('#final_total_amt').text();
var result_amount = parseFloat(final_amount) - parseFloat(total_item_amount);
$('#final_total_amt').text(result_amount);
$('#row_id_'+row_id).remove();
count--;
$('#total_item').val(count);
});
function cal_final_total(count)
{
var final_item_total = 0;
for(j=1; j<=count; j++)
{
var quantity = 0;
var price = 0;
var actual_amount = 0;
var tax1_rate = 0;
var tax1_amount = 0;
var tax2_rate = 0;
var tax2_amount = 0;
var tax3_rate = 0;
var tax3_amount = 0;
var item_total = 0;
quantity = $('#order_item_quantity'+j).val();
if(quantity > 0)
{
price = $('#order_item_price'+j).val();
if(price > 0)
{
actual_amount = parseFloat(quantity) * parseFloat(price);
$('#order_item_actual_amount'+j).val(actual_amount);
tax1_rate = $('#order_item_tax1_rate'+j).val();
if(tax1_rate > 0)
{
tax1_amount = parseFloat(actual_amount)*parseFloat(tax1_rate)/100;
$('#order_item_tax1_amount'+j).val(tax1_amount);
}
tax2_rate = $('#order_item_tax2_rate'+j).val();
if(tax2_rate > 0)
{
tax2_amount = parseFloat(actual_amount)*parseFloat(tax2_rate)/100;
$('#order_item_tax2_amount'+j).val(tax2_amount);
}
tax3_rate = $('#order_item_tax3_rate'+j).val();
if(tax3_rate > 0)
{
tax3_amount = parseFloat(actual_amount)*parseFloat(tax3_rate)/100;
$('#order_item_tax3_amount'+j).val(tax3_amount);
}
item_total = parseFloat(actual_amount) + parseFloat(tax1_amount) + parseFloat(tax2_amount) + parseFloat(tax3_amount);
final_item_total = parseFloat(final_item_total) + parseFloat(item_total);
$('#order_item_final_amount'+j).val(item_total);
}
}
}
$('#final_total_amt').text(final_item_total);
}
$(document).on('blur', '.order_item_price', function(){
cal_final_total(count);
});
$(document).on('blur', '.order_item_tax1_rate', function(){
cal_final_total(count);
});
$(document).on('blur', '.order_item_tax2_rate', function(){
cal_final_total(count);
});
$(document).on('blur', '.order_item_tax3_rate', function(){
cal_final_total(count);
});
$('#create_invoice').click(function(){
if($.trim($('#order_receiver_name').val()).length == 0)
{
alert("Please Enter Reciever Name");
return false;
}
if($.trim($('#order_no').val()).length == 0)
{
alert("Please Enter Invoice Number");
return false;
}
if($.trim($('#order_date').val()).length == 0)
{
alert("Please Select Invoice Date");
return false;
}
for(var no=1; no<=count; no++)
{
if($.trim($('#item_name'+no).val()).length == 0)
{
alert("Please Enter Item Name");
$('#item_name'+no).focus();
return false;
}
if($.trim($('#order_item_quantity'+no).val()).length == 0)
{
alert("Please Enter Quantity");
$('#order_item_quantity'+no).focus();
return false;
}
if($.trim($('#order_item_price'+no).val()).length == 0)
{
alert("Please Enter Price");
$('#order_item_price'+no).focus();
return false;
}
}
$('#invoice_form').submit();
});
});
</script>
I dont know how to recode this to a school receipt. please any can recode this with this same values like no quanitity required , tax1 should be having default value as 5% and tax2 with value 6% and calculate it
I have a problem with selected option value for different row. I succeed to get value for first row. What i want to do is different row item have different price.
My previous question about "JQuery Get Selected Option Value for Add Row" has been solved : Here
Now, i come out with another issues which is to get different value for different row. The picture sample is like below
My problem sample screenshot
Here's the code for my JS :
var i=$('table tr').length;
$(".tambah_sofa").on('click',function(){
/* add new row function start here */
html = '<tr id="row_'+i+'">';
html += '<td><button type="button" id="delete-button" data-row-delete="row_'+i+'">X</button></td>';
html += '<td><select id="sofa_'+i+'"><option value="10">hai</option><option value="20">20</option> <option value="50">50</option></select></td>';
html += '<td>X</td>';
html += '<td><input type="number" name="quantity[]" id="quantity_'+i+'" value="1" disabled="disabled"></td>';
html += '</tr>';
sidebar = '<tr id="row_'+i+'">';
sidebar += '<td><input style="width:50%;" name="sofa'+i+'" type="text" id="price_sofa'+i+'" value="" disabled="disabled"></td>';
sidebar += '</tr>';
$('#table_item').append(html);
$('#table_sidebar').append(sidebar);
/* Get selected option value start here */
$('body').on('change', '#sofa_'+i+'', function () {
$('#price_sofa'+i+'').val($(this).find('option:selected').val());
});
/* Get selected option value end here */
i++;
});
var i = $('table tr').length;
$(".tambah_sofa").on('click', function() {
/* add new row function start here */
html = '<tr id="row_' + i + '">';
html += '<td><button type="button" id="delete-button" data-row-delete="row_' + i + '">X</button></td>';
html += '<td><select id="sofa_' + i + '"><option value="10">hai</option><option value="20">20</option> <option value="50">50</option></select></td>';
html += '<td>X</td>';
html += '<td><input type="number" name="quantity[]" id="quantity_' + i + '" value="1" disabled="disabled"></td>';
html += '</tr>';
sidebar = '<tr id="row_' + i + '">';
sidebar += '<td><input style="width:50%;" name="sofa' + i + '" type="text" id="price_sofa' + i + '" value="" disabled="disabled"></td>';
sidebar += '</tr>';
$('#table_item').append(html);
$('#table_sidebar').append(sidebar);
/* Get selected option value start here */
(function(index){
$('#sofa_' + index).on('change', function () {
$('#price_sofa' + index).val($(this).val());
});
})(i);
/* Get selected option value end here */
i++;
});
HTML :
<table>
<tr>
<td>
<input type="text" name="name[]" value=" echo $ail">
<label >Address</label>
<input type="text" name="countryname[]" id='countryname_1' />
<button type="button" class='btn btn-danger delete'>- Delete</button>
<button type="button" class='btn btn-success addmore'>+ Add More</button>
</td>
</tr>
</table>
Js :
<script>
$(".delete").on('click', function() {
$('.case:checkbox:checked').parents("tr").remove();
$('.check_all').prop("checked", false); check();
});
var i = $('table tr').length;
$(".addmore").on('click', function(){
count = $('table tr').length;
var data = "<tr><td><input type='checkbox' class='case'/></td><td><span id='snum" + i + "'>" + count + ".</span></td>"; data += "<td><input class='form-control' type='text' id='countryname_" + i + "' name='countryname[]' required/></td> </tr>"; $('table').append(data); row = i;
});
</script>
I am getting multiple values in <? echo $ail;?>.
How to give add more button in front of every $ail value to give a row of a input box?
Because I have multiple values of $ail when I click on one value of Add button I get incremented on every field of $ail.
you can use this example for your problem.
js code :
$(document).ready(function() {
var max_fields = 10; //maximum input boxes allowed
var wrapper = $(".input_fields_wrap"); //Fields wrapper
var add_button = $(".add_field_button"); //Add button ID
var x = 1; //initlal text box count
$(add_button).click(function(e){ //on add input button click
e.preventDefault();
if(x < max_fields){ //max input box allowed
x++; //text box increment
$(wrapper).append('<div><input type="text" name="mytext[]"/>Remove</div>'); //add input box
}
});
$(wrapper).on("click",".remove_field", function(e){ //user click on remove text
e.preventDefault(); $(this).parent('div').remove(); x--;
})
});
Html code:
<div class="input_fields_wrap">
<button class="add_field_button">Add More Fields</button>
<div><input type="text" name="mytext[]"></div>
</div>
The question isn't very clear but presumably <? echo $ail;?> is displaying the content of a PHP array but you want to loop through the array and achieve something similar the functionality presented in the image.
PHP code:
<?php
// $options starts life as an empty string
$options = "";
// $options becomes a list of options for a <select> control
// it is populated with the values from the $ail array
foreach ($ail as $value) {
$options = "<option value='".$value."'>".$value."</option>";
}
?>
HTML code:
<table>
<tr>
<td>
Ailment:
<select id="ail_select" name="ail_select">
<option value="">--- Select ---</option>
<?php echo $options; ?>
</select>
<button type="button" class='btn btn-success addmore'>Add More</button>
</td>
</tr>
</table>
JS code:
$(document).ready(function(){
$(".delete").on("click", function() {
$(".case:checkbox:checked").parents("tr").remove();
$(".check_all").prop("checked", false);
check();
});
var counter = $("table tr").length - 1;
$(".addmore").on("click", function(){
// get the selected ailment
var ail = $("#ail_select").val();
// ail must have a value
if (ail.length > 0) {
counter++;
var data = "<tr><td><input type='checkbox' class='case'/></td><td><span id='snum" + counter + "'>" + ail + ".</span></td>";
data += "<td><input class='form-control' type='text' id='countryname_" + counter + "' name='countryname[]' required/></td>";
data += "</tr>";
$("table").append(data);
}
});
});
See JSFiddle for example in action.
I am trying to calculate the total of a list of dynamic form option items, example :
product name
product description
quantity
price
total
I have a script that automatically adds item rows :
$(".addmore").on('click',function(){
html = '<tr>';
html += '<td><input class="case" type="checkbox"/></td>';
html += '<td><input type="text" data-type="productCode" name="data[Invoice][itemNo][]" id="itemNo_'+i+'" class="form-control autocomplete_txt" autocomplete="off"></td>';
html += '<td><input type="text" data-type="productName" name="data[Invoice][itemName][]" id="itemName_'+i+'" class="form-control" autocomplete="off"></td>';
html += '<td><input type="text" name="data[Invoice][price][]" id="price_'+i+'" class="form-control changesNo" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>';
html += '<td><input type="text" name="data[Invoice][quantity][]" id="quantity_'+i+'" class="form-control changesNo" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>';
html += '<td><input type="text" name="data[Invoice][total][]" id="total_'+i+'" class="form-control totalLinePrice" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>';
html += '<td><input class="case" type="checkbox" name="data[Invoice][staged][]" id="itemStaged_'+i+'"></td>';
html += '</tr>';
$('table').append(html);
i++;
});
and the script that does the totalling :
$(document).on('change keyup blur','#tax',function(){
calculateTotal();
});
//total price calculation
function calculateTotal(){
subTotal = 0 ; total = 0;
$('.totalLinePrice').each(function(){
if($(this).val() != '' )subTotal += parseFloat( $(this).val() );
});
$('#subTotal').val( subTotal.toFixed(2) );
tax = $('#tax').val();
if(tax != '' && typeof(tax) != "undefined" ){
taxAmount = subTotal * ( parseFloat(tax) /100 );
$('#taxAmount').val(taxAmount.toFixed(2));
total = subTotal + taxAmount;
}else{
$('#taxAmount').val(0);
total = subTotal;
}
$('#totalAftertax').val( total.toFixed(2) );
calculateAmountDue();
}
So what happens now, you tab or press enter to cycle through the fields, and after you update the qty and tab through, it updates the total for that item, as well as the overall total.
The PROBLEM is that if you COPY and PASTE form fields using the following script :
//copies the selected table rows to new ones
$(".copy").on('click', function() {
var origs=$('.case:checkbox:checked');
for(var a=0; a<origs.length; a++) {
addNewRow();
var arr = origs.closest('tr')[a].id.split('_');
var id = arr[arr.length-1];
var dat = getValues(id);
setValues(i-1, dat);
}
$('#check_all').add(origs).prop("checked", false);
// Tried adding calculateTotal(); in this line to no avail...
});
The copied rows are not updated on the overall total. This is driving me insane, does anyone have a solution or tutorial on how to do this?
Requests : (show addNewRow function)
var addNewRow = function(id){
html = '<tr id="tr_'+i+'">';
html += '<input type="hidden" id="stock_'+i+'"/>';
html += '<input type="hidden" id="stockMaintainer_'+i+'" name="data[InvoiceDetail]['+i+'][stockMaintainer]" />';
html += '<input type="hidden" id="previousQuantity_'+i+'"/>';
html += '<input type="hidden" id="invoiceDetailId_'+i+'"/>';
html += '<td><input class="case" id="caseNo_'+i+'" type="checkbox" onkeyup="return tabE(this,event);"/></td>';
html += '<td class="prod_c"><input type="text" data-type="productCode" name="data[InvoiceDetail]['+i+'][product_id]" id="itemNo_'+i+'" class="form-control autocomplete_txt" autocomplete="off" onkeyup="return tabE(this,event);">';
html +='<span class="add_icon" id="add_icon_'+i+'"> <i class="fa fa-plus-circle"></i></span>';
html +='<span class="subtract_icon" id="subtract_icon_'+i+'"><i class="fa fa-minus-circle"></i></span>';
html +='</td>';
html += '<td><input type="text" data-type="productName" name="data[InvoiceDetail]['+i+'][productName]" id="itemName_'+i+'" class="form-control" autocomplete="off" onkeyup="return tabE(this,event);"></td>';
html += '<td><input type="text" name="data[InvoiceDetail]['+i+'][price]" id="price_'+i+'" class="form-control changesNo" autocomplete="off" onkeypress="return IsNumeric(event);" onkeyup="return tabE(this,event);" ondrop="return false;" onpaste="return false;"></td>';
html += '<td><input type="text" name="data[InvoiceDetail]['+i+'][quantity]" id="quantity_'+i+'" class="form-control changesNo quanyityChange" autocomplete="off" onkeypress="return IsNumeric(event);" onkeyup="return tabE(this,event);" ondrop="return false;" onpaste="return false;">';
html += '</td>';
html += '<td><input type="text" id="total_'+i+'" class="form-control totalLinePrice addNewRow" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>';
html += '<td><input type="checkbox" name="data[InvoiceDetail]['+i+'][staged]" id="staged_1'+i+'" class="form-control autocomplete_txt" autocomplete="off"></td>';
html += '<td><input type="checkbox" name="data[InvoiceDetail]['+i+'][added]" id="added_1'+i+'" class="form-control autocomplete_txt" autocomplete="off"></td>';
html += '<td><select name="data[InvoiceDetail]['+i+'][location]" id="location_1'+i+'" class="form-control autocomplete_txt" autocomplete="off">';
html += '<option value="Used">Used</option>';
html += '<option value="RTS">RTS</option>';
html += '<option value="LAJ">LAJ</option>';
html += '</select></td>';
html += '</tr>';
if( typeof id !== "undefined"){
$('#tr_'+id).after(html);
}else{
$('table').append(html);
}
$('#caseNo_'+i).focus();
i++;
}
(getValues) Code :
var getValues=function(id){
var inputs=$('#tr_'+id).find('select,input,textarea').filter('[name]');
var values={};
for(var i=0; i<inputs.length;i++){
var cur=inputs[i];
values[cur.name.match(/\[\w+]$/)||cur.name] = $(cur).is(':checkbox, :radio') ? cur.checked : cur.value;
}
return values;
};
(setValues) :
var setValues=function(id,values){
var inputs=$('#tr_'+id);
for(var i in values){
var cur=inputs.find('[name$="'+i+'"]');
if(cur.is(':checkbox, :radio')) {
cur.prop('checked', values[i]);
} else {
cur.val(values[i]);
}
}
};
The addNewRow function is not setting a name attribute on the total textbox.
However, your getValues and setValues functions are using the [name] attribute selector to get and set values in the cloned rows. Because addNewRow did not set the name attribute, the total value fails to populate in the cloned row, and therefore the total does not change because calculateTotal interprets this value as 0.
Problem code is here:
html += '<td><input type="text" id="total_' + i + '" class="form-control totalLinePrice addNewRow" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>';
Here is the fixed line of code: (and also remember to call calculateTotal in your copy handler)
html += '<td><input type="text" name="data[InvoiceDetail][' + i + '][total]" id="total_' + i + '" class="form-control totalLinePrice addNewRow" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>';
See working (but slightly simplified) snippet below: (or see the fiddle)
$(document).on('change keyup blur', '#tax', function() {
calculateTotal();
});
IsNumeric = tabE = function() {
return true
}
var i = 0;
var addNewRow = function(id) {
var html = '<tr id="tr_' + i + '">';
html += '<input type="hidden" id="stock_' + i + '"/>';
html += '<input type="hidden" id="stockMaintainer_' + i + '" name="data[InvoiceDetail][' + i + '][stockMaintainer]" />';
html += '<input type="hidden" id="previousQuantity_' + i + '"/>';
html += '<input type="hidden" id="invoiceDetailId_' + i + '"/>';
html += '<td><input class="case" id="caseNo_' + i + '" type="checkbox" onkeyup="return tabE(this,event);"/></td>';
html += '<td class="prod_c"><input type="text" data-type="productCode" name="data[InvoiceDetail][' + i + '][product_id]" id="itemNo_' + i + '" class="form-control autocomplete_txt" autocomplete="off" onkeyup="return tabE(this,event);">';
html += '<span class="add_icon" id="add_icon_' + i + '"> <i class="fa fa-plus-circle"></i></span>';
html += '<span class="subtract_icon" id="subtract_icon_' + i + '"><i class="fa fa-minus-circle"></i></span>';
html += '</td>';
html += '<td><input type="text" data-type="productName" name="data[InvoiceDetail][' + i + '][productName]" id="itemName_' + i + '" class="form-control" autocomplete="off" onkeyup="return tabE(this,event);"></td>';
html += '<td><input type="text" name="data[InvoiceDetail][' + i + '][price]" id="price_' + i + '" class="form-control changesNo" autocomplete="off" onkeypress="return IsNumeric(event);" onkeyup="return tabE(this,event);" ondrop="return false;" onpaste="return false;"></td>';
html += '<td><input type="text" name="data[InvoiceDetail][' + i + '][quantity]" id="quantity_' + i + '" class="form-control changesNo quanyityChange" autocomplete="off" onkeypress="return IsNumeric(event);" onkeyup="return tabE(this,event);" ondrop="return false;" onpaste="return false;">';
html += '</td>';
html += '<td><input type="text" name="data[InvoiceDetail][' + i + '][total]" id="total_' + i + '" class="form-control totalLinePrice addNewRow" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>';
html += '<td><input type="checkbox" name="data[InvoiceDetail][' + i + '][staged]" id="staged_1' + i + '" class="form-control autocomplete_txt" autocomplete="off"></td>';
html += '<td><input type="checkbox" name="data[InvoiceDetail][' + i + '][added]" id="added_1' + i + '" class="form-control autocomplete_txt" autocomplete="off"></td>';
html += '<td><select name="data[InvoiceDetail][' + i + '][location]" id="location_1' + i + '" class="form-control autocomplete_txt" autocomplete="off">';
html += '<option value="Used">Used</option>';
html += '<option value="RTS">RTS</option>';
html += '<option value="LAJ">LAJ</option>';
html += '</select></td>';
html += '</tr>';
if (typeof id !== "undefined") {
$('#tr_' + id).after(html);
} else {
$('table').append(html);
}
$('#caseNo_' + i).focus();
i++;
}
$(".addmore").on('click', function() {
html = '<tr>';
html += '<td><input class="case" type="checkbox"/></td>';
html += '<td><input type="text" data-type="productCode" name="data[Invoice][itemNo][]" id="itemNo_' + i + '" class="form-control autocomplete_txt" autocomplete="off"></td>';
html += '<td><input type="text" data-type="productName" name="data[Invoice][itemName][]" id="itemName_' + i + '" class="form-control" autocomplete="off"></td>';
html += '<td><input type="text" name="data[Invoice][price][]" id="price_' + i + '" class="form-control changesNo" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>';
html += '<td><input type="text" name="data[Invoice][quantity][]" id="quantity_' + i + '" class="form-control changesNo" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>';
html += '<td><input type="text" name="data[Invoice][total][]" id="total_' + i + '" class="form-control totalLinePrice" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>';
html += '<td><input class="case" type="checkbox" name="data[Invoice][staged][]" id="itemStaged_' + i + '"></td>';
html += '</tr>';
$('table').append(html);
i++;
});
//copies the selected table rows to new ones
$(".copy").on('click', function() {
var origs = $('.case:checkbox:checked');
for (var a = 0; a < origs.length; a++) {
addNewRow();
var arr = origs.closest('tr')[a].id.split('_');
var id = arr[arr.length - 1];
var dat = getValues(id);
setValues(i - 1, dat);
}
$('#check_all').add(origs).prop("checked", false);
calculateTotal();
});
//total price calculation
function calculateTotal() {
subTotal = 0;
total = 0;
$('.totalLinePrice').each(function() {
if ($(this).val() != '') subTotal += parseFloat($(this).val());
});
$('#subTotal').val(subTotal.toFixed(2));
tax = $('#tax').val();
if (tax != '' && typeof(tax) != "undefined") {
taxAmount = subTotal * (parseFloat(tax) / 100);
$('#taxAmount').val(taxAmount.toFixed(2));
total = subTotal + taxAmount;
} else {
$('#taxAmount').val(0);
total = subTotal;
}
$('#totalAftertax').val(total.toFixed(2));
//calculateAmountDue();
}
var getValues = function(id) {
var inputs = $('#tr_' + id).find('select,input,textarea').filter('[name]');
var values = {};
for (var i = 0; i < inputs.length; i++) {
var cur = inputs[i];
values[cur.name.match(/\[\w+]$/) || cur.name] = $(cur).is(':checkbox, :radio') ? cur.checked : cur.value;
}
return values;
};
var setValues = function(id, values) {
var inputs = $('#tr_' + id);
for (var i in values) {
var cur = inputs.find('[name$="' + i + '"]');
if (cur.is(':checkbox, :radio')) {
cur.prop('checked', values[i]);
} else {
cur.val(values[i]);
}
}
};
addNewRow()
addNewRow()
input {
width: 60px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
Tax rate
<input type="text" id="tax" value="8.7">
</div>
<div>
Tax amt
<input type="text" id="taxAmount" value="0">
</div>
<div>
Total
<input type="text" id="totalAftertax" value="0">
</div>
COPY CHECKED ROWS (check some rows first)
<table>
<thead>
<tr>
<th>copy</th>
<th>product code</th>
<th>product name</th>
<th>price</th>
<th>qty</th>
<th>total</th>
<th>staged</th>
<th>added</th>
<th>location</th>
</tr>
</thead>
</table>
Here you are calling calculateTotal(); function on change keyup and blur
events.this works as long as you interact with form elements.
but when you copy the row.you wont be interacting with textboxes.so those change,blur and keyup events wont get fired and as a result calculateTotal()
will not be executed.as a result you cant see any update on total value.
to overcome this you have to call calculateTotal() in copy function.