JavaScript multiple auto count for cashier apps? - javascript

I have a page like this:
[http://jsfiddle.net/ph75fggo/]
[http://jsfiddle.net/ph75fggo/5/]//more reliable sample
And I tried to make a simple cashier apps, with help of JavaScript make an auto count on both rows and columns.
This is the result I want to get:
http://jsfiddle.net/wrz8bc10/
My Final Trying: jsfiddle.net

Your Question is not drawing the clear picture of your requirement. As far as I understand, you need to have a gross amount after deducting the discount for each row and the total discounted and net amounts at the end.
First thing that you should do is to assign a common class to each of the child of every tr. It makes your JS code a lot simpler. Otherwise you need write some extra LOC to select specific element.
<tr>
<td><input type='text' class="amount" id='harga2' value='250000' /></td>
<td><input type='text' class="discount" id='diskon2' value='' /></td>
<td><input type='text' class="grossAmount" id='total2' value='' /></td>
</tr>
<tr>
<td><input type='text' class="amount" id='harga2' value='250000' /></td>
<td><input type='text' class="discount" id='diskon2' value='' /></td>
<td><input type='text' class="grossAmount" id='total2' value='' /></td>
</tr>
<tr>
<td><input type='text' class="amount" id='harga2' value='250000' /></td>
<td><input type='text' class="discount" id='diskon2' value='' /></td>
<td><input type='text' class="grossAmount" id='total2' value='' /></td>
</tr>
After that you can use the following function:
function myFunction(){
var amounts = document.getElementsByClassName("amount");
var discounts = document.getElementsByClassName("discount");
var gAmounts = document.getElementsByClassName("grossAmount");
var lv,rowSum,totDis=0,totAmount=0;
for(lv=0;lv>gAmounts.length;lv++){
rowSum += (parseInt(amounts[lv].value)-parseInt(discounts[lv].value));
totAmount += rowSum;
totDis += parseInt(discounts[lv].value);
gAmounts[lv].value = totAmount;
}
}
But if you don't want change your HTML, Then you can use the following code:
function myFunc(){
var lv,rowSum,totDis=0,totAmount=0;
var TRs = document.getElementsByTagName("table")[0].childNodes; //assuming that the table is the first one on your page.
var lv;
for(lv=1;lv<tab.length;lv++){ // starting the counter with 1 as the first child of the table contains headings
rowSum += (parseInt(TRs[lv][0].value)-parseInt(TRs[lv][1].value));
totAmount += rowSum;
totDis += parseInt(TRs[lv][1].value);
TRs[lv].value = rowSum;
}
}

You were getting the elements with ids 'id1' and 'id2' whereas there are no such elements present in your html with those ids, they should be 'harga1' and 'diskon1'. Also, when you write your JS in a function, make sure to call it at the end, but you don't need to write it in a function in this specific case, so here is your solution:
var rows = document.getElementById("myTable").getElementsByTagName("tr").length;
for(var i=1; i<rows; i++){
var harga = parseInt(document.getElementById('harga'+i).value);
var diskon = parseInt(document.getElementById('diskon'+i).value);
var total = harga - diskon;
document.getElementById('total'+i).value = total;
}
Get the number of rows, then keep getting the harga and diskon values one by one.. harga1, harga2, harga3.. ('harga'+i) subtract their values and put them in total1, total2 and total 3.. this will work if you add more rows as well..
See the DEMO here

I have updated the JSFiddle here:
[http://jsfiddle.net/ph75fggo/4/]
This is just one approach at what you are trying to do, where I changed your code as little as possible, and still uses hard coded variable names (instead of the above answer that automatically iterates over all rows). You can use my answer to help simply extend your cashier application.

do you mean like this link?
you can change use the parameters if you want
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<table>
<tr>
<td>Total Harga</td>
<td>Total Diskon</td>
<td>Total Bayar</td>
</tr>
<tr>
<td><input type='text' id='harga1' onchange="dynamic()" value='250000' /></td>
<td><input type='text' id='diskon1' value='50' /></td>
<td><input type='text' id='total1' value='' /></td>
</tr>
<tr>
<td><input type='text' id='harga2' value='250000' /></td>
<td><input type='text' id='diskon2' value='0' /></td>
<td><input type='text' id='total2' value='0' /></td>
</tr>
<tr>
<td><input type='text' id='harga3' value='250000' /></td>
<td><input type='text' id='diskon3' value='0' /></td>
<td><input type='text' id='total3' value='0' /></td>
</tr>
</table>
</body>
<script>
function dynamic(){
var harga1 = document.getElementById('harga1').value;
var diskon1 = document.getElementById('diskon1').value/100;
var totalharga = harga1 - (harga1 * diskon1);
document.getElementById("total1").value = totalharga;
}
</script>
</html>

Related

when checkbox is checked not able to fetch data that are against that checkbox

I have data that is displayed in the form of a table and each row has a checkbox.
I am trying to fetch the data of each row when the checkbox is clicked against that row.
<tr>
<td><input type="text" name="child_name"></td>
<td><input type="text" name="child_age"></td>
<td><input type="checkbox" ></td>
</tr>
<tr>
<td><input type="text" name="child_name"></td>
<td><input type="text" name="child_age"></td>
<td><input type="checkbox" ></td>
</tr>
These will get generated dynamically, so the naming needs to same for the input box, however when i am fetching the value typed by the user,it fetches the value of only first row, and the values is getting repeated multiple times
$(document).ready(function(){
$('input[type="checkbox"]').click(function(){
if($(this).prop("checked") == true){
$tr = $(this).closest('tr');
var arr = [];
var data = $tr.children("td").map(function(){
var one = $("[name='child_name']").val();
var two = $("[name='child_age']").val();
arr.push(one)
arr.push(two)
return arr;
}).get();
console.log(data);
$('#post-result').append(data);
}
else if($(this).prop("checked") == false){
console.log("Checkbox is unchecked.");
}
});
});
Can anyone please tell how to resolve the issue
The name attribute in this case could complicate things a little bit. What I would do is use data-attributes to have specific identifiers for each row. Something like this:
UPDATED
I changed the behavior to work with dynamically added rows.
Using $(document).on("click"... you can affect future elements of the same type while $("[type='checkbox']").click() works only for currently existing elements.
I also took some liberty in expanding the example.
var children = [];
$(document).on("click", ".child-selector", function() {
var id = $(this).data("id");
if($(this).is(":checked")) {
var info = [];
info.push($(".child-name[data-id='"+ id +"']").val());
info.push($(".child-age[data-id='"+ id +"']").val());
console.log(info);
// An example of using objects to give some structure to the data
// and then store it to an array with all the checked rows
var child = {};
child.id = id;
child.name = $(".child-name[data-id='"+ id +"']").val();
child.age = $(".child-age[data-id='"+ id +"']").val();
children.push(child);
console.log(children);
} else {
console.log("Checkbox is unchecked.");
// An example of removing the specific children from the array
children.forEach(function(child, index) {
if(child.id == id) {
children.splice(index, 1);
}
});
console.log(children);
}
});
var clickCounter = 0;
var dataCounter = 13;
$("#add-child").click(function() {
var html = '<tr>'+
'<td><input type="text" class="child-name" data-id="'+ dataCounter +'" value="Child '+ clickCounter +'"></td>'+
'<td><input type="text" class="child-age" data-id="'+ dataCounter +'" value="'+ clickCounter +'"></td>'+
'<td><input class="child-selector" type="checkbox" data-id="'+ dataCounter +'"></td>'+
'</tr>';
$("table").append(html);
clickCounter++;
dataCounter++;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td><input type="text" class="child-name" data-id="9" value="John Connor"></td>
<td><input type="text" class="child-age" data-id="9" value="12"></td>
<td><input class="child-selector" type="checkbox" data-id="9"></td>
</tr>
<tr>
<td><input type="text" class="child-name" data-id="10" value="Jane Connor"></td>
<td><input type="text" class="child-age" data-id="10" value="12"></td>
<td><input class="child-selector" type="checkbox" data-id="10"></td>
</tr>
<tr>
<td><input type="text" class="child-name" data-id="11" value="Tom Connor"></td>
<td><input type="text" class="child-age" data-id="11" value="13"></td>
<td><input class="child-selector" type="checkbox" data-id="11"></td>
</tr>
<tr>
<td><input type="text" class="child-name" data-id="12" value="T800"></td>
<td><input type="text" class="child-age" data-id="12" value="1"></td>
<td><input class="child-selector" type="checkbox" data-id="12"></td>
</tr>
</table>
<button type="button" id="add-child">Add Child</button>
Now, if you need to send the data via post you should review your usage of name because as it currently is it would only send one value.
You can use the context parameter of $(selector [, context]) to only search inside the current <tr>:
$(document).ready(function() {
$('input[type="checkbox"]').click(function() {
if ($(this).prop("checked") == true) {
$tr = $(this).closest('tr');
var arr = [];
var one = $("[name='child_name']", $tr).val();
var two = $("[name='child_age']", $tr).val();
arr.push(one)
arr.push(two);
console.log(arr);
$('#post-result').append(arr);
} else if ($(this).prop("checked") == false) {
console.log("Checkbox is unchecked.");
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td><input type="text" name="child_name" value="A Name"></td>
<td><input type="text" name="child_age" value="A Age"></td>
<td><input type="checkbox"></td>
</tr>
<tr>
<td><input type="text" name="child_name" value="B Name"></td>
<td><input type="text" name="child_age" value="B Age"></td>
<td><input type="checkbox"></td>
</tr>
</table>
<pre id="post-result"></pre>

Calculation for input array in every row Jquery

I am new into JQuery, My code is only working for the first row, it doesn't calculate for other rows. I have two button, one for adding another row and one for deleting it. What I try to do it to calculate price+vat*quantity and put it in total field in every row.
here if the code for my html
<table border='1' id="mytable" dir="rtl" style='border-collapse: collapse;'>
<thead>
<tr>
<th> partnumber </th>
<th>name</th>
<th>price </th>
<th>vat</th>
<th>quantity</th>
<th> price + vat</th>
<th> total quantity*(price+vat) </th>
<th> </th>
</tr>
</thead>
<tbody>
<tr class='tr_input'>
<td><input type='text' name="partnumber[]" class='username' id='partnumber_1' placeholder='پارت نه‌مبه‌ر '></td>
<td><input type='text' class='name' name="name[]" id='name_1' ></td>
<td><input type='text' class='price' name="price[]" id='price_1' ></td>
<td><input type='text' class='vat' name="vat[]" id='vat_1' ></td>
<td><input type='text' class='quantity' name="quantity[]" id='quantity_1' ></td>
<td><input type='text' class='amount' name="amount[]" id='amount_1' ></td>
<td><input type='text' class='total' name="total[]" id='total_1' ></td>
</tr>
</tbody>
</table>
<br>
<input type='button' value='Add fields' id='addmore' class="btn btn-success">
<input type='button' value='remove' id='remove' class="btn btn-danger">
Here is the screenshot for the interface.
And this is JS code for adding new row
$('#addmore').click(function(){
var lastname_id = $('.tr_input input[type=text]:nth-child(1)').last().attr('id');
var split_id = lastname_id.split('_');
var index = Number(split_id[1]) + 1;
var html = "<tr class='tr_input'><td><input type='text' name='partnumber[]' class='username' id='username_"+index+"' placeholder='بگه‌ری بۆ پارت نه‌مبه‌ر '></td><td><input type='text' class='name' name='name[]' id='name_"+index+"'></td><td><input type='text' class='price' name='price[]' id='price_"+index+"' ></td><td><input type='text' class='vat' name='vat[]' id='vat"+index+"'></td><td><input type='text' class='quantity' name='quantity[]' id='quantity_"+index+"' ></td><td><input type='text' class='amount' name='amount[]' id='amount_"+index+"' ></td><td><input type='text' class='total' name='total[]' id='total_"+index+"' ></td><td align='center'><input type='checkbox' name='record'></td></tr>";
// Append data
$('tbody').append(html);
});
and finally this is code for calculation the total, only working for the first row.
$('.total').each(function() {
$(this).on('click',function (ev) {
// var total=0;
var quantity=$(this).attr('id');
var splitid = quantity.split('_');
var index = splitid[1];
var price= parseFloat($('#price_'+index).val());
var vat=parseFloat($('#vat_'+index).val());
var quan=parseFloat($('#quantity_'+index).val());
var amount=$('#amount_'+index).val();
amount=price+vat;
$('#amount_'+index).val(amount);
alert(amount);
//alert(price);
var total=amount*quan;
//var qunatity_num=parseInt(quantity.val());
$('#total_'+index).val(total);
//alert(total);
// $('#total_'+index).val(total);
});
});
please, could you tell me what's is wrong with my code, it's been a week I am trying to solve this. Thank you.
Some issues:
There is an underscore missing in the HTML that you add for a new row: vat should be vat_
Don't use $('.total').each(function() {: it is not necessary to loop. The click handler will work on all matching elements, if you take the next point into account:
Use event delegation to make sure your click handler also gets called for future cells that have the total class:
$(document).on('click', '.total', function (ev) {
With that it works.
However it would be better not to use dynamic id attributes all and use CSS classes only. With jQuery methods you can easily find out which is the "current" row that was clicked on (.closest("tr")) and then to .find() the element you need in your formula.

Multiple onchange and addition

I'm working on creating a page in which someone could calculate their Net Worth by entering various values. The input text will show a .00 afterwards if no decimal point is added in. I'm having troubles in getting a sum of all of the values.
Java:
<script type="text/javascript"><!--
function updatesum() {
document.form.TotalAssets.value = (document.form.CashOnHand.value -0) + (document.form.CashInChecking.value -0);
}
//-->
</script>
HTML:
<input type="text" onblur="if(this.value.indexOf('.')==-1)this.value=this.value+'.00'" onchange="format(this); updatesum()" onkeyup="format(this)" maxlength="11" value="0" name="CashOnHand" /></td>
</tr>
<tr>
<td><strong>Cash in Checking</strong></td>
<td>$
<input type="text"
onblur="if(this.value.indexOf('.')==-1)this.value=this.value+'.00'" onchange="format(this); updatesum()" onkeyup="format(this)" maxlength="11" value="0" name="CashInChecking" /></td>
</tr>
<tr>
<td align="right"><strong>Total Assets</strong></td>
<td>$<input name="TotalAssets" readonly ></td>
</tr>
It's not giving me a sum of the the values that I'm adding.
I think this is because document.form is undefined, but this one works:
function updatesum() {
var hand = parseFloat(document.forms[0].CashOnHand.value);
var checking = parseFloat(document.forms[0].CashInChecking.value);
document.forms[0].TotalAssets.value = hand - checking;
}

Dynamically Added Rows and Calculation Function Error After First Row

I'm working a project, it is almost done but I got a problem to finish it. I tried a lot of things and searched on the web, but unfortunately I could not succeed it.
The problem is about dynamically added rows at the table. Auto-calculating script is just working on the first row of the table, at 2nd, 3rd, ... rows of the table it does not work.
jsFiddle for below the code:
<script type='text/javascript'>//<![CDATA[
$(window).load(function(){
$("#AddLine").click(function () {
//var row = "<tr><td><input type=text /></td><td><input type=text /></td><td><input type=text /></td><td><button>X</button></td></tr>";
var row = "<tr><td><input type=\"text\" style=\"width:100%;\" name=\"stokkodu[]\"></td><td><input type=\"text\" style=\"width:100%;\" name=\"stokadi[]\"></td><td><input type=\"text\" style=\"width:100%;\" id=\"miktar\" class=\"miktar\" name=\"miktar[]\"></td><td><input type=\"text\" style=\"width:100%;\" name=\"birim[]\"></td><td><input type=\"text\" style=\"width:100%;\" id=\"birimfiyat\" class=\"birimfiyat\" name=\"birimfiyat[]\"></td><td><input type=\"text\" style=\"width:100%;\" readonly id=\"tutar\" class=\"tutar\" name=\"tutar[]\"></td><td><input type=\"text\" style=\"width:100%;\" class=\"indirim\" name=\"indirim[]\"></td><td><input type=\"text\" style=\"width:100%;\" readonly class=\"indirimtutar\" name=\"indirimtutari[]\"></td><td><input type=\"text\" style=\"width:100%;\" class=\"kdv\" name=\"kdv[]\"></td><td><input type=\"text\" style=\"width:100%;\" readonly class=\"satirtoplami\" name=\"satirtoplami[]\"></td><td><button>X</button></td></tr>";
$("#table").append(row);
});
$("#table").on("click", "button", function() {
$(this).closest("tr").remove();
});
});
$(document).ready(function() {
$('input[id=miktar],input[id=birimfiyat],input[id=indirim],input[id=kdv], input[id=satirtoplami]').change(function(e) {
var total_mnozi = 0;
//var $row = $(this).parent();
var $row = $(this).closest("tr"); //this is the closest common root of the input elements
var miktar = parseFloat( $row.find('input[id=miktar]').val() );
var birimfiyat = parseFloat( $row.find('input[id=birimfiyat]').val() );
var indirim = parseFloat( $row.find('input[id=indirim]').val() );
var kdv = parseFloat( $row.find('input[id=kdv]').val() );
//total_mnozi = ((dep + minpre + adjpre) * procombase * profcomper) || 0; //calculate traditionally; display zero until result is meaningful
tutar = (miktar * birimfiyat) || 0; // tutar hesaplama. miktar x birim fiyat = tutar
indirimtutar= (tutar * indirim / 100) || 0; // indirim tutarı hesaplama input'a girilen %'ye göre hesaplar.
satirtoplami= ((tutar - indirimtutar) * ((kdv / 100) + 1 )) || 0;
$row.find('input[id=tutar]').val(tutar.toFixed(2)); // tutar'ın id="tutar"'a virgülden sonra 2 hane alacak şekilde yazdrılması.
$row.find('input[id=indirimtutar]').val(indirimtutar.toFixed(2));
$row.find('input[id=satirtoplami]').val(satirtoplami.toFixed(2));
});
});
//]]>
</script>
<input type="button" id="AddLine" value="add"/>
<table id="table">
<tr>
</tr>
<tr>
<td scope="col">Stok Kodu</th>
<td scope="col">Stok Adı</th>
<td scope="col">Miktar</th>
<td scope="col">Birim</th>
<td scope="col">Birim Fiyat</th>
<td scope="col">Tutar</th>
<td scope="col">İndirim (%)</th>
<td scope="col">İndirim Tutarı</th>
<td scope="col">KDV (%)</th>
<td scope="col">Satır Toplamı</th>
<td scope="col"></th>
</tr>
<tr>
<td><input type="text" style="width:100%;" name="stokkodu[]"></td>
<td><input type="text" style="width:100%;" name="stokadi[]"></td>
<td><input type="text" style="width:100%;" id="miktar" class="miktar" name="miktar[]"></td>
<td><input type="text" style="width:100%;" name="birim[]"></td>
<td><input type="text" style="width:100%;" id="birimfiyat" class="birimfiyat" name="birimfiyat[]"></td>
<td><input type="text" style="width:100%;" readonly id="tutar" class="tutar" name="tutar[]"></td>
<td><input type="text" style="width:100%;" id="indirim" class="indirim" name="indirim[]"></td>
<td><input type="text" style="width:100%;" readonly id="indirimtutar" class="indirimtutar" name="indirimtutari[]"></td>
<td><input type="text" style="width:100%;" id="kdv" class="kdv" name="kdv[]"></td>
<td><input type="text" style="width:100%;" readonly id="satirtoplami" class="satirtoplami" name="satirtoplami[]"></td>
<td><button>X</button></td>
</tr>
</table>​
How can I do this?
Your problem is with duplicate Ids.
You should not add two or more elements with the same Id. So, to solve the problem, your dynamically added elements should not have id attributes, then you use the class attribute to target the elements in each row.
Working sample: http://jsfiddle.net/3W48W/2/ (incorporating #Barmar 's answer)
HTM
There are two problems with your code:
First, you're using the same IDs in each row that you add dynamically. IDs are required to be unique.
Second, the .change() binding only applies to elements that are in the DOM at the time the page is loaded. To handle elements added dynamically, you need to use .on() to bind to a permanent element and delegate to the dynamic elements, or bind the event handler to the new row's elements after you append it to the DOM.

Jquery: sum input text fields

I have a table including input text fields with the basic structure below. I am having trouble building a function to iterate all rows in the table and sum all the values of input fields beginning with BFObel where the value of the field beginning with BFOkto are the same. So for the basic example below the sum for value 1111 would be 2000 and the sum for value 1112 would be 3000. Each sum would then be written to an inputfield with the id field1111, field1112 etc...
<table>
<tr id="BFOrow1">
<td><input type="text" id="BFOtxt1" value="text"/></td>
<td><input type="text" id="BFOkto1" value="1111" /></td>
<td><input type="text" id="BFObel1" value="1000" /></td>
</tr>
<tr id="BFOrow2">
<td><input type="text" id="BFOtxt2" value="text"/></td>
<td><input type="text" id="BFOkto2" value="1111" /></td>
<td><input type="text" id="BFObel2" value="1000" /></td>
</tr>
<tr id="BFOrow3">
<td><input type="text" id="BFOtxt3" value="text"/></td>
<td><input type="text" id="BFOkto3" value="1112" /></td>
<td><input type="text" id="BFObel3" value="1000" /></td>
</tr>
<tr id="BFOrow4">
<td><input type="text" id="BFOtxt4" value="text"/></td>
<td><input type="text" id="BFOkto4" value="1112" /></td>
<td><input type="text" id="BFObel4" value="1000" /></td>
</tr>
<tr id="BFOrow5">
<td><input type="text" id="BFOtxt5" value="text"/></td>
<td><input type="text" id="BFOkto5" value="1112" /></td>
<td><input type="text" id="BFObel5" value="1000" /></td>
</tr>
</table>
You'll want to use an object literal to track your results and an "attribute starts with" selector to find the text inputs:
var accumulator = { };
$('table input[id^=BFOkto]').each(function() {
var sum_id = this.id.replace(/^BFOkto/, 'BFObel');
if(!accumulator[this.value])
accumulator[this.value] = 0;
accumulator[this.value] += parseInt($('#' + sum_id).val(), 10);
});
// accumulator now has your results.
Don't forget the second argument to parseInt() so that you don't get tripped up by values with leading zeros (which look like octal without a specified radix).
For example: http://jsfiddle.net/ambiguous/QAqsQ/ (you'll need to run this in a browser with an open JavaScript console to see the resulting accumulator).
var sum1111 = 0;
$('input[value="1111"]').each(function() {
var ordinal = $(this).attr('id').replace('BFOkto', '');
sum1111 += parseInt($('#BFObel' + ordinal).val());
});
At the end, sum1111 should equal 2000.
For reuse, wrap the logic in a function:
function getSum(BFOkto) {
var sum = 0;
var ordinal = null;
$('input[value="' + BFOkto + '"]').each(function() {
ordinal = $(this).attr('id').replace('BFOkto', '');
sum += parseInt($('#BFObel' + ordinal).val());
});
return sum;
}
And then call:
getSum('1111');
getSum('1112');
A different approach: find all input fields with prefix BFOkto, for each, find the input with prefix BFObel sharing same parent and accumulate its value
ref = $("table td input[id^=BFOkto]");
var sums = new Object();
ref.each(function(){
val = parseInt($(this).closest('tr').find("td input[id^=BFObel]").val(), 10);
property = 'i'+ this.value;
sums[property] = (sums[property] || 0 ) + val;
});
alert(sums['i1111']);
alert(sums['i1112']);
sums will be an object with properties
i1111 = 2000
i1112 = 3000
Despite javascript allows it, it is better not to use pure numeric properties for objects (associative arrays), hence the i prefix
The running example is here:
http://jsfiddle.net/TbSau/1/

Categories