Adding multiple array values - javascript

Here is my form
<form method="post" action="collect_vals.php">
<div id="input_fields">
<div><input type="text" placeholder="unit" name="unit[]"> <input type="text" placeholder="price" name="price[]"><input type="text" placeholder="total" name="total[]"> <span class="fa fa-plus-circle" id="add_field"></span></div>
</div>
<input type="submit" value="submit">
</form>
https://jsfiddle.net/d9bhsL4o/1/
Here is my script:
<script type="text/javascript">
$(document).ready(function() {
$("input[name=unit]").keyup(function() {
var unit = new Array();
var qty = new Array();
$("input[name=unit]").each(function() {
unit.push($(this).val());
});
$("input[name=qty]").each(function() {
qty.push($(this).val());
});
var total = new Array();
for (var i = 0; i <unit.length; i++) {
var inp=unit[i]*qty[i];
("total["+i+"].value="+inp.value);
}
});
});
</script>
Trying to multiply two values and keep on third. Does not working. What the wrong with the code

Am attached class definition inside html both rendered and appended element. I tweak around your html code and use this to total up all values respectively :
HTML
<input type="text" placeholder="unit" name="unit[]" class="a">
<input type="text" placeholder="price" name="price[]" class="a">
<input type="text" placeholder="total" name="total[]" class="total">
JS
......
......
$("#input_fields").append('<input type="text" placeholder="unit" name="unit[]" class="a">
<input type="text" placeholder="price" name="price[]" class="a">
<input type="text" placeholder="total" name="total[]" class="total">
<span id="remove" class="fa fa-minus-circle"></span</div>');
......
......
// capture both unit AND price keyup
$("#input_fields").on('keyup', '.a', function () {
// add current keyup textbox also into stack
var all = $(this).siblings('input.a').addBack();
var sum = 1;
// loop over those element
all.each(function(i,e){
// sum both values
sum *= $(e).val();
});
// finally filtered textbox with total class
// and assign the output
$(this).nextAll('.total').val(sum);
});
DEMO

You should traverse the DOM, there are multiple ways to travese DOM. Here I have used .siblings() to get total and qty
$("#input_fields").on('keyup', "input[name='unit[]']", function () {
var unit = $(this).val();
var price = $(this).siblings("input[name='price[]']").val();
$(this).siblings("input[name='total[]']").val(unit * price);
});

Related

Calculate the sum of dynamic cloned forms for Profit and Loss in javascript Jquery

I am trying to build a Simple Profit and Loss page for my sales. The goal is:
One row equals One client.
Add a dynamic row based on number of clients.
For each row I need to input the sale amount and cost amount, then calculate the profit for that row(client).
Calculate the sum of all rows profit.
The issue: When I add a row, the button calculates only the first DOM row and not the result of the cloned ones as well.
$(document).ready(function() {
$("#addForm").click(function() {
$("#pnl").clone().appendTo(".originalPnlDiv");
});
});
function calculate() {
var salesPnl = document.getElementsbyClassName('sale').value;
var costPnl = document.getElementsbyClassName('cost').value;
var sum = document.getElementById('total').value = salesPnl - costPnl;
}
function totalProfit() {
var totalSalesPnl = document.getElementsbyClassName('sale').value;
var totalCostPnl = document.getElementsbyClassName('cost').value;
var totalSum = document.getElementById('grandTotal').value = totalSalesPnl - totalCostPnl;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1>PNL</h1>
<div class="originalPnlDiv">
<form action="" id="pnl">
<select>
<option value="customerZ">customerZ</option>
<option value="customerX">customerX</option>
</select>
<input class="sale" type="number" placeholder="sale S$">
<input class="cost" type="number" placeholder="cost S$">
<input placeholder="invoice#">
<input type="date">
<input id="total"/>
</form>
</div>
<button id="addForm">Clone</button>
<button onclick="calculate()">calculate</button>
<br>
<br>
<button onclick="totalProfit()">Total Profit</button>
<p>The totalprofit is <span id="grandTotal"></span></p>
Thanks a lot for your help, I am only two months old regarding coding.
Have a nice day
don't use id when it's not going to be unique across the page.
re-organize your logic by moving the calculate button for each line
use document.querySelector and document.querySelectorAll
$(document).ready(function() {
$("#addForm").click(function() {
$("#pnl").clone().appendTo(".originalPnlDiv");
});
});
function calculate(button) {
var form = button.closest("form");
var salesPnl = form.querySelector('.sale').value;
var costPnl = form.querySelector('.cost').value;
var sum = salesPnl - costPnl;
form.querySelector('#total').value = sum;
return sum;
}
function totalProfit() {
var parent = document.querySelector(".originalPnlDiv");
var panels = parent.querySelectorAll("#pnl")
var grand = 0;
panels.forEach(function(panel) {
grand += calculate(panel);
})
document.querySelector("#grandTotal").innerText = grand;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1>PNL</h1>
<div class="originalPnlDiv">
<form action="" id="pnl">
<select>
<option value="customerZ">customerZ</option>
<option value="customerX">customerX</option>
</select>
<input class="sale" type="number" placeholder="sale S$">
<input class="cost" type="number" placeholder="cost S$">
<input placeholder="invoice#">
<input type="date">
<input id="total" />
<button onclick="calculate(this); return false">calculate</button>
</form>
</div>
<button id="addForm">Clone</button>
<br>
<br>
<button onclick="totalProfit()">Total Profit</button>
<p>The totalprofit is <span id="grandTotal"></span></p>

Computing using functions and arrays / Output error: Not a Number

Background: I'm practicing arrays and functions and am having trouble computing the sum of array items. I'm pretty sure there is something wrong with the function I'm writing but I'm not sure what. Using 8 input fields I'm pulling data into a array one item at a time and converted to floating numbers(for now...I'll try to fix that later). I've created a function that will compute the total of this list but it only outputs NaN.
Any suggestions are highly appreciated!
function myfunction() {
list = [];
list[0] = parseFloat(document.getElementById('number1').value);
list[1] = parseFloat(document.getElementById('number2').value);
list[2] = parseFloat(document.getElementById('number3').value);
list[3] = parseFloat(document.getElementById('number4').value);
list[4] = parseFloat(document.getElementById('number5').value);
list[5] = parseFloat(document.getElementById('number6').value);
list[6] = parseFloat(document.getElementById('number7').value);
list[7] = parseFloat(document.getElementById('number8').value);
function total(myvals) {
let total = 0;
for (let i = 0; i <= myvals.length; i++) {
total += myvals[i];
}
return total;
}
document.getElementById('results').innerHTML = total(list);
}
<form>
<input type="text" name="number1" id="number1"><br>
<input type="text" name="number2" id="number2"><br>
<input type="text" name="number3" id="number3"><br>
<input type="text" name="number4" id="number4"><br>
<input type="text" name="number5" id="number5"><br>
<input type="text" name="number6" id="number6"><br>
<input type="text" name="number7" id="number7"><br>
<input type="text" name="number8" id="number8"><br>
<input type="submit" value="Compute Score" onclick="javascript:myfunction()">
</form>
<div id="results"></div>
Here is a simple example using a for loop with querySelectorAll.
Additionally, I cleaned up your code a bit. Run the snippet below:
EDIT: Included some comments to show what's happening.
function myfunction() {
let total = 0;
//get the value for each element being called by querySelectorAll
//add values to total to get a sum
document.querySelectorAll('input').forEach(el => total += +el.value);
//append the new value to the results div
document.querySelector('#results').innerHTML = total;
}
<form>
<input type="text" name="number1" id="number1"><br>
<input type="text" name="number2" id="number2"><br>
<input type="text" name="number3" id="number3"><br>
<input type="text" name="number4" id="number4"><br>
<input type="text" name="number5" id="number5"><br>
<input type="text" name="number6" id="number6"><br>
<input type="text" name="number7" id="number7"><br>
<input type="text" name="number8" id="number8"><br>
</form>
<br/><br/>
<button type="submit" onclick="myfunction()">Compute Score</button>
<br/><br/>
<div id="results"></div>
This is resolved. I was able to fix my source code by removing
"<=" in the for loop and adding "<" in its place. Thanks everyone, I will look over everything else for extra practice!
1 - in HTML forms and their elements use names.
2 - each element of a form can be accessed by name with the form as parent
3 - if several elements have the same name (with the same type of preference) then they form an object collection
PS: I have used here [... myForm.numX] to transform the myForm.numX collection to array, so that it can accept the arry.map () method
this way:
const myForm = document.forms['my-form']
, res = document.getElementById('results')
;
myForm.onsubmit = evt =>
{
evt.preventDefault() // disable submit
let list = [...myForm.numX].map(inp => parseFloat(inp.value))
res.textContent = list.reduce((t,v)=>t+v,0)
// control...
console.clear()
console.log( myForm.numX.length, JSON.stringify(list) )
}
<form name="my-form">
<input type="text" name="numX" placeholder="num 1"><br>
<input type="text" name="numX" placeholder="num 2"><br>
<input type="text" name="numX" placeholder="num 3"><br>
<input type="text" name="numX" placeholder="num 4"><br>
<input type="text" name="numX" placeholder="num 5"><br>
<input type="text" name="numX" placeholder="num 6"><br>
<input type="text" name="numX" placeholder="num 7"><br>
<input type="text" name="numX" placeholder="num 8"><br>
<button type="submit">Compute Score</button>
</form>
<div id="results">..</div>

jQuery/Javascript complex iterate over elements

We have a form and need to iterate over some elements to get the final sum to put in a "total" element.
E.g., here is a working starter script. It doesn't NOT iterate over the other ones. It does NOT consider the elements "item*", below, yet but should. Keep reading.
<script>
$( document ).ready(function() {
$('#taxsptotal').keyup(calcgrand);
$('#shiptotal').keyup(calcgrand);
$('#disctotal').keyup(calcgrand);
function calcgrand() {
var grandtot = parseFloat($('#subtotal').val(), 10)
+ parseFloat($("#taxsptotal").val(), 10)
+ parseFloat($("#shiptotal").val(), 10)
- parseFloat($("#disctotal").val(), 10)
$('#ordertotal').val(grandtot);
}
});
</script>
We are adding more to this. Think of having many items in a cart and each one has the same elements for the following where "i" is a number designating an individual item.
<!-- ordertotal = sum of #subtotal, #taxptotal, #shiptotal and #disctotal -->
<input type="text" id="ordertotal" name="ordertotal" value="106.49">
<input type="text" id="taxsptotal" name="taxsptotal" value="6.72">
<input type="text" id="shiptotal" name="shiptotal" value="15.83">
<input type="text" id="disctotal" name="disctotal" value="0.00">
<!-- sum of the cart "itemtotal[i]" -->
<input type="text" id="subtotal" name="subtotal" value="83.94">
<!-- cart items
User can change any itemprice[i] and/or itemquantity[i]
itemtotal[i] = sum(itemquantity[i] * itemprice[i])
-->
<input type="text" name="itemtotal[1]" value="8.97" />
<input type="text" name="itemquantity[1]" value="3" />
<input type="text" name="itemprice[1]" value="2.99" />
<input type="text" name="itemtotal[2]" value="4.59" />
<input type="text" name="itemquantity[2]" value="1" />
<input type="text" name="itemprice[2]" value="4.59" />
<input type="text" name="itemtotal[3]" value="0.99" />
<input type="text" name="itemquantity[3]" value="10" />
<input type="text" name="itemprice[3]" value="9.90" />
(1) User can change any itemprice[i] and/or itemquantity[i], so each needs a keyup. I can do that in php as it iterates over the items.
(2) These elements will have a $('.itemtotal[i]').keyup(calcgrand); (Or function other than calcgrand, if needed) statement, too. That keyup can be added by the php code as it evaluates the items in the cart.
(3) When an element is changed, then the script should automatically (a) calculate the $('[name="itemtotal[i]"]').val() and (b) replace the value for $('[name="itemtotal[i]"]').val().
(4) Then, the script above will use the $('[name="itemtotal[i]"]').val() to (a) replace the #subtotal value and (b) use that value in the equation.
Can someone help me with this? I am stuck on how to iterate over the [i] elements.
p.s. Any corrections/enhancements to the above code is appreciated, too.
Add a custom class to the desired inputs to sum:
HTML:
<input type="text" class="customclass" name=itemtotal[1] value="8.97" />
<input type="text" class="customclass" name=itemquantity[1] value="3" />
<input type="text" class="customclass" name=itemprice[1] value="2.99" />
JS:
var sum = 0;
$.each('.customclass',function(i, item){
sum = sum + Number($(this).val());
})
alert(sum);
if you for example group your inputs by giving them a class, or have each group in a div like so:
<!-- ordertotal = sum of #subtotal, #taxptotal, #shiptotal and #disctotal -->
<input type="text" id="ordertotal" name="ordertotal" value="106.49">
<input type="text" id="taxsptotal" name="taxsptotal" value="6.72">
<input type="text" id="shiptotal" name="shiptotal" value="15.83">
<input type="text" id="disctotal" name="disctotal" value="0.00">
<!-- sum of the cart "itemtotal[i]" -->
<input type="text" id="subtotal" name="subtotal" value="83.94">
<!-- cart items
User can change any itemprice[i] and/or itemquantity[i]
itemtotal[i] = sum(itemquantity[i] * itemprice[i])
-->
<div class="group">
<input type="text" name="itemtotal[1]" value="8.97" />
<input type="text" name="itemquantity[1]" value="3" />
<input type="text" name="itemprice[1]" value="2.99" />
</div>
<div class="group">
<input type="text" name="itemtotal[2]" value="4.59" />
<input type="text" name="itemquantity[2]" value="1" />
<input type="text" name="itemprice[2]" value="4.59" />
</div>
<div class="group">
<input type="text" name="itemtotal[3]" value="0.99" />
<input type="text" name="itemquantity[3]" value="10" />
<input type="text" name="itemprice[3]" value="9.90" />
</div>
Then you could do the following in javascript:
function calcSubTotal() {
$('[name^="itemtotal"]').each(function(i){
var sum = 0;
$('[name^="itemtotal"]').each(function(i){
sum += $(this).val();
});
$('#subtotal').val(sum);
});
}
$('.group').each(function(i) {
var total = $(this).find('[name^="itemtotal"]');
var qnt = $(this).find('[name^="itemquantity"]');
var price = $(this).find('[name^="itemprice"]');
total.keyup(function(e){
price.val(total.val() * qnt.val());
calcSubTotal();
});
qnt.keyup(function(e){
price.val(total.val() * qnt.val());
calcSubTotal();
});
});
$("[name^='itemprice'], [name^='itemquantity']").keyup(function(){
var input_name = $(this).attr('name');
var temp_name_split = input_name.split(/[\[\]]+/);
var temp_total = parseInt($('[name="itemquantity['+temp_name_split[1] +']"]').val()) * parseFloat($('[name="itemprice['+temp_name_split[1] +']"]').val());
$('[name="itemtotal['+temp_name_split[1]+']"]').val(temp_total.toFixed(2));
var total = 0;
$("[name^='itemtotal']").each(function() {
total += parseFloat($(this).val());
});
$('#subtotal').val(total.toFixed(2));
});

Array.foreach only gets val() from the last input id with keyup

Please help me figure out why only the last input id gets its value added to the input id= #attr3 with keyup.
I need both inputs in the div to have their values put into the input outside the div separated with a comma(,). i made a fiddle https://jsfiddle.net/dc6v6gjd/1/. Thanks
<div id ="candy">
<input type="text" id="attr1" name="emailAddress" value="">
<input type="text" id="attr2" name="emailAddress" value="">
</div>
<input type="text" id="attr3" name="username" value="">
$(document).ready(function () {
var text = $("#candy :input").map(function () {
return this.id;
}).get();
var attr = [];
for (i=0; i<text.length; i++) {
attr.push('#'+ text[i]);
}
var mat = attr.join(", ");
$(mat).keyup(function(){
update();
function update() {
attr.forEach(function(index, i){
// alert(i);
$("#attr3").val( $(attr[i]).val() + "," );
});
}
});
});
The reason is you're overriding the value of attr3 on each iteration of forEach. You could instead use join to get the value.
e.g.
function update() {
var val = attr
.map(function(a) {
return $(a).val();
})
.join(",");
$("#attr3").val(val);
}
That being said I'd probably go with a simpler solution like this.
// set the keyup event handler and add all inputs to an array.
var inputs = $("#candy :input").keyup(function() {
update();
}).get();
// read all input values into comma separated string and update attr3
function update() {
var val = inputs.map(function(i) {
return $(i).val();
}).join(",");
$("#attr3").val(val);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="candy">
<input type="text" id="attr1" name="emailAddress" value="">
<input type="text" id="attr2" name="emailAddress" value="">
</div>
<input type="text" id="attr3" name="username" value="">
Update: Support dynamically added inputs.
$(document).on("keyup", "#candy :input", function() {
update();
});
function update() {
var val = $("#candy :input").get().map(function(i) {
return $(i).val();
}).join(",");
$("#attrFinal").val(val);
}
var count = 3;
$("#add").click(function() {
$("#candy").append("<input type='text' id='attr" + count++ + "' name='emailAddress' />");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="candy">
<input type="text" id="attr1" name="emailAddress" value="">
<input type="text" id="attr2" name="emailAddress" value="">
</div>
<input type="text" id="attrFinal" name="username" value="">
<button id="add">Add New</button>

Need basic loop for js to sum two fields, since they're multiple groups

I need a basic loop to sum two fields. I just get it to work for one group, but the others remain the same. I know I need some kind of array to solve this, but I can't work it out. (Notice, they are 50 groups in the original project, but I just added 2) Here is the code:
HTML
<label>Value 1:</label><input type="text" name="value1[]" id="txtval1"><br>
<label>Value 2:</label><input type="text" name="value2[]" id="txtval2"><br>
<label>Total:</label><input type="text" name="total[]" id="txttotal"><br><br>
<label>Value 1:</label><input type="text" name="value1[]" id="txtval1"><br>
<label>Value 2:</label><input type="text" name="value2[]" id="txtval2"><br>
<label>Total:</label><input type="text" name="total[]" id="txttotal">
<br><br>
<button type="button" onclick="myFunction(); return false;">Get Total</button>
Javascript
<script type="text/javascript">
function myFunction()
{
var val1 = document.getElementById('txtval1').value;
var val2 = document.getElementById('txtval2').value;
var total = document.getElementById('txttotal');
var sum = parseInt(val1) + parseInt(val2);
if (val1.value!='' && val2.value!=''){
total.value='';
total.value = total.value + sum;
}
}
</script>
I don't know why this doen't work on my fiddle, but does in my local machine. Here is the Fiddle
I think that giving the same ID to two elements It is mistake.
You have to give a different ID for each element and pass them on for.
Look at this fiddle:
http://jsfiddle.net/83m6e/
EDIT: I changed the fiddle for option2:
http://jsfiddle.net/83m6e/3/
You also can put each segment into a div and then do not change the names.
You can not add up to arrays in order to add up their elements. You must do it one by one. Try this code:
<html>
<head>
<script type="text/javascript">
function myFunction()
{
var count = 3;
var val1, val2, sum;
for (var i = 0; i < count; i++)
{
val1 = document.getElementById('txtval1_' + i).value;
val2 = document.getElementById('txtval2_' + i).value;
sum = parseInt(val1) + parseInt(val2);
document.getElementById('txttotal_' + i).value = sum;
}
}
</script>
</head>
<body>
<label>Value 1:</label><input type="text" id="txtval1_0"><br>
<label>Value 2:</label><input type="text" id="txtval2_0"><br>
<label>Total:</label><input type="text" id="txttotal_0"><br><br>
<label>Value 1:</label><input type="text" id="txtval1_1"><br>
<label>Value 2:</label><input type="text" id="txtval2_1"><br>
<label>Total:</label><input type="text" id="txttotal_1"><br><br>
<label>Value 1:</label><input type="text" id="txtval1_2"><br>
<label>Value 2:</label><input type="text" id="txtval2_2"><br>
<label>Total:</label><input type="text" id="txttotal_2"><br><br>
<button type="button" onclick="myFunction(); return false;">Get Total</button>
</body>
</html>

Categories