Jquery: sum input text fields - javascript

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/

Related

Getting text values from dynamic HTML table

I am trying to get the values from an html table.
I have tried row.cells[j].innerHTML which returns <input name="ctl00$ctl00$ctl00$MainContent$Nav$SiteContent$Text2" type="text" id="MainContent_Nav_SiteContent_Text2" maxlength="5">
I have also tried row.cells[j].innerHTML.text, row.cells[j].innerHTML.value, and row.cells[j].outterHTML which all return undefined. Any ideas?
An overview of what I want happening: user enter values in the dynamic table, adding / deleting rows as needed. Once table is filled, user clicks save which calls GetTableValues() which loops through the table adding each fields value to a string. Each value is separated by % and each row is separated by #. I then assign that string to a hidden field which I can access in my VB.Net code which then parses the data to save to a database.
It is looping through table but (as seen in the logs below), it does not get the values from the table
Here is the javascript and html of the table and looping through the table.
function GetTableValues() {
var s = "";
console.log("enter function");
//Reference the Table.
var table = document.getElementById("dataTable");
//Loop through Table Rows.
for (var i = 1; i < table.rows.length; i++) {
//Reference the Table Row.
var row = table.rows[i];
console.log("outside nest " + s);
for (var j = 1; j < 6; j++) {
console.log("i= " + i + " j= " + j);
//Copy values from Table Cell to JSON object.
console.log("inside nest " + row.cells[j].innerHTML +"%");
s = s + row.cells[j].innerHTML +"%";
}
console.log("outside again " + s);
s = s + "#";
}
document.getElementsByName("drawingsHidden").value = s
console.log(document.getElementsByName("drawingsHidden").value);
}
<table id="dataTable" style="width:100%">
<tr>
<th>Check Box</th>
<th>CAGE</th>
<th>Dwg #</th>
<th>Dwg Rev</th>
<th>Prop Rev</th>
<th>Issued Rev</th>
<th>Status</th>
</tr>
<tr>
<td><input type="checkbox" id="chkbox" /></td>
<td><input type="text" id="Text2" maxlength="5" runat="server" text=""/></td>
<td><input type="text" id="DRAWINGNUM" maxlength="20" runat="server" text=""/></td>
<td><input type="text" id="DRAWINGREV" maxlength="2" runat="server" text=""/></td>
<td><input type="text" id="PROPREV" maxlength="2" runat="server" text=""/></td>
<!--tie these fields to the drawing tracking form-->
<td><input type="text" id="ISSUEDREV" maxlength="2" runat="server" text=""/></td>
<td><input type="text" id="Text3" maxlength="20" runat="server" text=""></td>
</tr>
</table>
enter function
outside nest
i= 1 j= 1
inside nest <input name="ctl00$ctl00$ctl00$MainContent$Nav$SiteContent$Text2" type="text" id="MainContent_Nav_SiteContent_Text2" maxlength="5" text="">%
i= 1 j= 2
inside nest <input name="ctl00$ctl00$ctl00$MainContent$Nav$SiteContent$DRAWINGNUM" type="text" id="MainContent_Nav_SiteContent_DRAWINGNUM" maxlength="20" text="">%
i= 1 j= 3
inside nest <input name="ctl00$ctl00$ctl00$MainContent$Nav$SiteContent$DRAWINGREV" type="text" id="MainContent_Nav_SiteContent_DRAWINGREV" maxlength="2" text="">%
i= 1 j= 4
inside nest <input name="ctl00$ctl00$ctl00$MainContent$Nav$SiteContent$PROPREV" type="text" id="MainContent_Nav_SiteContent_PROPREV" maxlength="2" text="">%
i= 1 j= 5
inside nest <input name="ctl00$ctl00$ctl00$MainContent$Nav$SiteContent$ISSUEDREV" type="text" id="MainContent_Nav_SiteContent_ISSUEDREV" maxlength="2" text="">%
outside again <input name="ctl00$ctl00$ctl00$MainContent$Nav$SiteContent$Text2" type="text" id="MainContent_Nav_SiteContent_Text2" maxlength="5" text="">%<input name="ctl00$ctl00$ctl00$MainContent$Nav$SiteContent$DRAWINGNUM" type="text" id="MainContent_Nav_SiteContent_DRAWINGNUM" maxlength="20" text="">%<input name="ctl00$ctl00$ctl00$MainContent$Nav$SiteContent$DRAWINGREV" type="text" id="MainContent_Nav_SiteContent_DRAWINGREV" maxlength="2" text="">%<input name="ctl00$ctl00$ctl00$MainContent$Nav$SiteContent$PROPREV" type="text" id="MainContent_Nav_SiteContent_PROPREV" maxlength="2" text="">%<input name="ctl00$ctl00$ctl00$MainContent$Nav$SiteContent$ISSUEDREV" type="text" id="MainContent_Nav_SiteContent_ISSUEDREV" maxlength="2" text="">%
Picture of the table
row.cells[j] is a TD Element, not an Input element.
By doing console.log(row.cells[j]) it's the easiest way to detect what is actually hold by some property. Then, having that element all it takes is to query for a child element Input. const EL_input = row.cells[j].querySelector("input"). Now that you have your input Element: const value = EL_input.value
Don't overuse ID selectors. Specially not in a table. It makes no sense for columns to contain elements with IDs, you might either run into a duplicated IDs issue or actually you don't necessarily need a Table.
Use NodeList.prototype.forEach(). It's simpler and easier than using daunting for loops.
You could also create some nifty DOM helpers to ease on your self Querying the DOM for elements
Use .console.log() or debugger to test your code.
// DOM helpers:
const EL = (sel, par) => (par || document).querySelector(sel);
const ELS = (sel, par) => (par || document).querySelectorAll(sel);
// Task:
const getTableValues = () => {
let str = "";
ELS("#dataTable tbody tr").forEach(EL_tr => {
ELS("td", EL_tr).forEach(EL_td => {
str += EL("input", EL_td).value + "%";
});
str += "#";
});
EL("#drawingsHidden").value = str
};
EL("#test").addEventListener("click", getTableValues);
#dataTable {
width: 100%;
}
<table id=dataTable>
<thead>
<tr>
<th>Check Box</th>
<th>CAGE</th>
<th>Dwg #</th>
<th>Dwg Rev</th>
<th>Prop Rev</th>
<th>Issued Rev</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type=checkbox></td>
<td><input type=text maxlength=5></td>
<td><input type=text maxlength=20></td>
<td><input type=text maxlength=2></td>
<td><input type=text maxlength=2></td>
<td><input type=text maxlength=2></td>
<td><input type=text maxlength=20></td>
</tr>
</tbody>
</table>
<button id=test type=button>CLICK TO TEST</button><br>
<input id=drawingsHidden type=text>
var table = document.getElementsByTagName('table')[0]
var td = table.getElementsByTagName('td')[0]
var input = td.getElementsByTagName('input')[0]
console.log(input.value)
<table>
<tr>
<td><input value=7><td>
</tr>
</table>

Dynamically change the variables

Since I have couple of entries that needs to be divided with the number i provide (num1 variable), I find the difficulties to complete the task.
I want the loop to divide me and store value from each variable called listX with 34. There are 9 lists (each has different number) and i want each list to be divided with the number i provide, but to be divided first with 2, then with 3, then with 4, 5 ... up to the number i provide.
I figured out that it could be done best with objects, but I can't find the solution, since I'm not so experienced with this stuff. The ideal would be to get the objects like:
List1: 1st division: xxx
List1: 2nd division: xxx
List1: 34th division: xxx
...
List 8: 22nd division: xxx
...
List 9: 33rd divison: xxx
List 9: 34th division: xxx
"xth division" should be linked with the number i provided in the num1 variable
What I'm trying to get is something like this:
It asks me how many times i want my values to be divided, i type in 5. Then it asks me what are the values of my 9 inputs.
I declare to the first input 100. The result what I want should be:
100/1 = 1
100/2 = 50
100/3 = 33,33
100/4 = 25
100/5 = 20
Then I declare to the second input number 200. The result should be:
200/1 = 200
200/2 = 100
200/3 = 66,66
200/4 = 50
200/5 = 40
It goes all the way up until my last input...
What I'm trying to develop is D'Hondt method for seat allocations in the parliament that is being used for some countries.
Here is what I've got so far, but ofc, it is not working.
var array1 = [];
var list = "list";
function someFunction() {
var num1 = 34;
for (var i = 1; i <= num1; ++i) {
for (var j = 1; j <= 9; j++) {
array1[j] += document.getElementById(list + j).value / i;
array1[j] += "<br/>";
}
}
document.getElementById("demo1").innerHTML = list + j;
}
<tr>
<td><input type="text" id="list1" style="width:50px" onkeyup="someFunction()"></input></td>
<td><input type="text" id="list2" style="width:50px" onkeyup="someFunction()"></input></td>
<td><input type="text" id="list3" style="width:50px" onkeyup="someFunction()"></input></td>
<td><input type="text" id="list4" style="width:50px" onkeyup="someFunction()"></input></td>
<td><input type="text" id="list5" style="width:50px" onkeyup="someFunction()"></input></td>
<td><input type="text" id="list6" style="width:50px" onkeyup="someFunction()"></input></td>
<td><input type="text" id="list7" style="width:50px" onkeyup="someFunction()"></input></td>
<td><input type="text" id="list8" style="width:50px" onkeyup="someFunction()"></input></td>
<td><input type="text" id="list9" style="width:50px" onkeyup="someFunction()"></input></td>
</tr>
I think this is what you are looking for, but a couple of notes.
A couple of notes:
The input element does not have a closing tag.
type="text is the default for input elements, so you don't need
to write it.
Don't Repeat Yourself (DRY). Since all of your input elements need
the same styling, just set up a single CSS rule to style them all the
same way.
Don't use inline HTML event handlers. Separate your JavaScript from
your HTML and follow modern standards.
See the comments below for details.
// Get the number to divide by (You can get this anyway you want. A prompt is show here.):
var num = +prompt("How many calculations per input would you like?");
// Get all the table inputs into an array
var inputs = Array.prototype.slice.call(document.querySelectorAll("td > input[id^='input']"));
// Loop over the input array...
inputs.forEach(function(input){
// Set up an event handler for the input
input.addEventListener("input", someFunction);
});
function someFunction(){
var resultString = "";
for(var i = 0; i < num; i++){
// Do the math and build up the string
resultString += (this.value / (i + 1)) + "<br>";
}
// Update the output cell that corresponds to the input element with the results
document.querySelector("#" + this.id.replace("input", "output")).innerHTML = resultString;
}
td > input { width:50%; }
<table id="inout">
<tr>
<td><input id="input1"></td>
<td><input id="input2"></td>
<td><input id="input3"></td>
<td><input id="input4"></td>
<td><input id="input5"></td>
<td><input id="input6"><td>
<td><input id="input7"></td>
<td><input id="input8"></td>
<td><input id="input9"></td>
</tr>
<tr>
<td id="output1"></td>
<td id="output2"></td>
<td id="output3"></td>
<td id="output4"></td>
<td id="output5"></td>
<td id="output6"><td>
<td id="output7"></td>
<td id="output8"></td>
<td id="output9"></td>
</tr>
</table>
<div id="output"></div>

JavaScript multiple auto count for cashier apps?

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>

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;
}

jquery multiply and divide at the same time

Here are my text fields
<tr>
<td>Price:</td>
<td><input type="text" name="price" id="form_textfield" class="price" autocomplete="off" /></td>
</tr>
<tr>
<td>Liters:</td>
<td><input type="text" name="liters" id="form_textfield" class="liters" autocomplete="off" /></td>
</tr>
<tr>
<td>Amount:</td>
<td><input type="text" name="jqueryamount" id="form_textfield" class="jqueryamount" autocomplete="off" /></td>
</tr>
Currently when you input price and liters, it multiplies them and outputs the answer to jqueryamount textfield it works well. What i want to do is when i type in the amount and the price it will divide the jqueryamount field with the price field and output it to liters field.
UPDATE FIXED
// JavaScript Document
$(document).ready(function(){
$('.price').keyup(calculate);
$('.liters').keyup(calculate);
});
function calculate(e)
{
$('.jqueryamount').val($('.price').val() * $('.liters').val());
}
// JavaScript Document
$(document).ready(function(){
$('.jqueryamount').keyup(calculate1);
$('.price').keyup(calculate1);
});
function calculate1(e)
{
$('.liters').val($('.jqueryamount').val() / $('.price').val());
}
JUST ADDED A NEW NAME FOR THE DIVIDE FUNCTION... silly me thanks for the help guys
Here are my javascript
// JavaScript Document
$(document).ready(function(){
$('.price').keyup(calculate);
$('.liters').keyup(calculate);
});
function calculate(e)
{
$('.jqueryamount').val($('.price').val() * $('.liters').val());
}
// JavaScript Document
$(document).ready(function(){
$('.jqueryamount').keyup(calculate);
$('.price').keyup(calculate);
});
function calculate(e)
{
$('.liters').val($('.jqueryamount').val() / $('.price').val());
}
My problem is when adding the divide function the multiplication part will no longer work, i can no longer type inside the liters textfield it gives me NaN error.
Use parseFloat() function after the get the value from input, which converts string to number.
When you put the value price and amount the liters would show like this.
$('.price').keyup(calculateLiters, calculateAmount);
$('.jqueryamount').keyup(calculateLiters);
$('.liters').keyup(calculateAmount);
function calculateLiters(e) {
price = parseFloat($('.price').val());
amount = parseFloat($('.jqueryamount').val());
if(!isNaN(price) && !isNaN(amount)){
$('.liters').val(amount / price);
}
}
function calculateAmount(e) {
price = parseFloat($('.price').val());
liters = parseFloat($('.liters').val());
if(!isNaN(price) && !isNaN(liters)){
$('.jqueryamount').val(price * liters);
}
}
Demo
I swapped some class names and id's to make code more efficient.
HTML
<tr>
<td>Price:</td>
<td><input type="text" name="price" id="price" class="form_textfield" autocomplete="off" /></td>
</tr>
<tr>
<td>Liters:</td>
<td><input type="text" name="liters" id="liters" class="form_textfield" autocomplete="off" /></td>
</tr>
<tr>
<td>Amount:</td>
<td><input type="text" name="jqueryamount" id="jqueryamount" class="form_textfield" autocomplete="off" /></td>
</tr>
Javascript
// JavaScript Document
$(document).ready(function(){
$('.form_textfield').keyup(calculate);
});
function calculate()
{
$('#jqueryamount').val($('#price').val() * $('#liters').val());
$('#liters').val($('#jqueryamount').val() / $('#price').val());
}
Here is a working demo. http://jsfiddle.net/vnaDK/

Categories