I have 2 <p> tags and an input field, wrapped in a while loop
<p id="price"></p>
<input id="quantity" oninput="calculate(<?php echo $cprice; ?>)" type="text" name="quantity">
<p id="total"></p>
I want to use JavaScript to perform arithmetic.
I want to multiply price and quantity and display the result in total. Without the while loop, it works but with the while loop, it only updates the first field.
function calculate(price) {
var quantity = document.getElementById('quantity').value;
var result = document.getElementById('total');
var myResult = price * quantity;
document.getElementById('total').innerHTML = myResult;
}
I don't know how to dynamically update the total tag with js
You need to change your IDs to class since IDs must be unique.
See example which is assuming price is alway there
I choose to not use nextElement since you can easily add other stuff to the html without it
I also made the code unobtrusive instead of having inline handlers
document.querySelectorAll(".quantity").forEach(function() {
this.oninput = function() {
var q = document.querySelectorAll(".quantity"),
p = document.querySelectorAll(".price"),
total = 0;
q.forEach(function(qt, index) {
var price = +p[index].innerText,
quantity = +qt.value;
if (!isNaN(quantity)) total += price * quantity;
})
document.getElementById('total').innerHTML = total;
}
})
<p class="price">1</p>
<input class="quantity" type="text" name="quantity">
<p class="price">2</p>
<input class="quantity" type="text" name="quantity">
<p class="price">3</p>
<input class="quantity" type="text" name="quantity"><br/>
Total:<p id="total"></p>
IDs need to be unique. If there are duplicates, document.getElementById will return the first one.
Instead of using IDs, use DOM navigation methods. You can pass in this to get a reference to the input element, then find the output element after it.
function calculate(price, input) {
var quantity = input.value;
var result = input.nextElementSibling;
var myResult = price * quantity;
result.innerHTML = myResult;
}
<p class="price">Price = 30</p>
<input class="quantity" oninput="calculate(30, this)" type="text" name="quantity">
<p class="total"></p>
<p class="price">Price = 45</p>
<input class="quantity" oninput="calculate(45, this)" type="text" name="quantity">
<p class="total"></p>
Related
I've been working on a calculator in Jquery. It's composed of a few initial calcultions that display totals in the frontend.
It calculates the measurements the user inputs and multiplies this with the base product(woocommerce) price to give an initial total.
It allows users to select various addons such as 'cut outs' and calculates the quantity to come up with a total value for the 'add ons'.
It allows users to select a few extras such as 'delivery' via input checkboxes which once again calculates them to provide a total cost for the extra touches.
This leaves me with 3 total figures for the calculator so far in their own fields/divs. I've given these each a class of 'sumthree'.
I'm then wanting to add these totals up to make an overall total for the calculator.
I've tried variations such as trying to pull the data using text, value and HTML. They're not all inputs so value didn't seem correct to me. Ive also tried using parseFloat instead of parseInt but no luck so far.
It always pulls NaN, but from what I can tell I correctly declared 'finalquote' in the code at the end. I'm under the understanding this could've been the issue.
<div class="form-section quote">
<input id="works-result" value="12" readonly>
</div>
<div class="splashback-calc">
<h4>Splashback/s</h4>
<div class="splashback-row">
<div class="form-section form-half-section quote">
<span class="quote-label">Width</span>
<span class="input-wrap currency"><input id="splash-width" type="number" value="0"></span></div>
<div class="form-section form-half-section quote">
<span class="quote-label">Length </span>
<span class="input-wrap currency"><input id="splash-length" type="number" value="0"></span>
</div>
</div>
<div class="additional-splashback"></div>
<a class="clonebutton" href="" >Add More</a>
<div class="form-section quote">
<input id="splash-result" value="0" readonly>
</div>
</div>
<div class="worktop-calc">
<span class="quote-label">Integrity Sink</span>
<div class="input-wrap currency extraproduct" data-price="600.00">
<input type="number" class="extraQuantity" value="0" min="0" max="20" />
<span class="productTotal"></span>
</div>
<span class="quote-label">Pop Up Socket Cut Out</span>
<div class="input-wrap currency extraproduct" data-price="50.00">
<input type="number" class="extraQuantity" value="0" min="0" max="20" />
<span class="productTotal"></span>
</div>
/** 1ST Total I'm Trying to Add **/
<div id="total" readonly="readonly">Total: £<span id="sum" class="sumthree">0.00</span> </div>
</div>
<div class="fitting-calc">
<div class="form-section quote">
<span class="quote-label">Templating</span>
<span class="input-wrap checkbox-wrap"><input type="checkbox" value="120.00"></span>
<br>
<span class="quote-label">Delivery</span>
<span class="input-wrap checkbox-wrap"><input type="checkbox" value="250.00"></span>
</div>
/** 2nd Total I'm trying to add **/
<input id="fittingprice" class="sumthree" type="text" readonly="readonly"/>
</div>
/** 3rd Total I'm trying to add, grabs product price and measurements to calculate the sum **/
<span class="input-wrap total-cost">£<input id="total-cost" class="sumthree" readonly type="number" min="0" step="0.01" data-number-to-fixed="2" data-number-stepfactor="100"></span>
/** The Total of the 3 other Totals I'm trying to solve **/
<span class="input-wrap">£<input id="quotefinal" readonly type="number" min="0" step="0.01" data-number-to-fixed="2" data-number-stepfactor="100"></span>
(function($){
$('.worktop-calc input').change(function() {
var area = $('#works-width').val() * $('#works-length').val()
$('#works-result').val(area)
})
$('.splashback-calc input').change(function() {
var area = $('#splash-width').val() * $('#splash-length').val()
$('#splash-result').val(area)
})
$('.clonebutton').first().click(function(event) {
event.preventDefault();
$( ".splashback-row" ).clone().appendTo( ".splashback-row" );
});
$( '.variations_form' ).each( function() {
jQuery(this).on( 'found_variation', function( event, variation ) {
console.log(variation);//all details here
var price = variation.display_price;//selectedprice
console.log(price);
var totalcost = (price) * $('#works-result').val()
$('#total-cost').val(totalcost)
});
var updateTotal = function() {
var sumtotal;
var sum = 0;
//Add each product price to total
$(".extraproduct").each(function() {
var extra_price = $(this).data('price');
var quantity = $('.extraQuantity', this).val();
//Total for one product
var subtotal = extra_price*quantity;
//Round to 2 decimal places.
subtotal = subtotal.toFixed(2);
//Display subtotal in HTML element
$('.productTotal', this).html(subtotal);
});
// total
$('.productTotal').each(function() {
sum += Number($(this).html());
});
$('#sum').html(sum.toFixed(2));
};
//Update total when quantity changes
$(".extraQuantity").bind("keyup change", function() {
updateTotal();
});
//Update totals when page first loads
updateTotal();
// set this from local
$('span.productTotal').each(function() {
$(this).before("£")
});
// unit price
$('.extraproduct span').each(function() {
var $price = $(this).parents("div").data('price');
$(this).before($price);
});
$('input[type="checkbox"]').change(function(){
var totalprice = 0;
$('input[type="checkbox"]:checked').each(function(){
totalprice= totalprice + parseInt($(this).val());
});
$('#fittingprice').val(totalprice);
});
// THE BIT THAT SHOULD OUTPUT THE SUM OF THE 3 TOTALS
$("span, .sumthree").change(function(){
var finalquote = 0;
$(".sumthree").each(function() {
finalquote = finalquote + parseInt($(this).html());
});
$('#quotefinal').val(finalquote);
console.log(finalquote);
});
});
})(jQuery)
I've cut down the HTML so it's a bit more understandable. I've included a JSFiddle to see the full code if needed. https://jsfiddle.net/DigitalAdam/c2jpawy4/2/
If you think I need to cut the JS down more, please let me know and I'll see what I can do. I'm new to doing calculators in Jquery and due to the nature of the calculator the above code all seemed relevant to me.
Regards
From what I remember JQuery's val() function returns a string. Try passing your values to parseInt() to get integers so you can do calculations.
parseInt($('#works-width').val()) etc...
Update: $('.variations_form').each block wraps most of your code. close it before you declare updateTotal to fix most functionality. Still working on the final though.
I have a site generated mainly in PHP. On one page PHP generates a number of dropdowns, the number of which is depending on items in my DB.
The number of dropdowns can change but I want to be able to count them and get the values for each of them in JS/jQuery.
At the moment the dropdowns all have the same class name but I think I'm going to have to try give them all individual IDs.
I know I could the amount of items like this:
var ammount = $(".myclass").length;
I just need some way of looping through these to get the individual values like this, without just picking up the first value of that class each time:
var input =$(".myclass").value;
I think I'm going to have to go with individual IDs being generated by the PHP but was just wondering if there was another way to do it.
$(".myclass").each(function(i,e) {
console.log(e); //e gives you current item in loop
});
or
$(".myclass").each(function() {
console.log($(this).value);
});
You can get the values in an array, by iterating over all these elements and pushing their values to the array:
var vals = [];
$(".myclass").each(function() {
vals.push($(this).val());
});
If you want to get the sum of all these inputs :
var sum = vals.reduce((a,b) => (+a + +b));
Demo:
var vals = [];
$(".myclass").each(function() {
vals.push($(this).val());
});
console.log(vals);
//Calculating sum of values
var sum = vals.reduce((a,b) => (+a + +b));
console.log(sum);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" class="myclass" value="10" />
<br/>
<input type="text" class="myclass" value="20" />
<br/>
<input type="text" class="myclass" value="30" />
<br/>
<input type="text" class="myclass" value="40" />
<br/>
<input type="text" class="myclass" value="50" />
<br/>
I'm trying to get the value of each input in a row and multiply them together but the result is a weird number:
ejs file:
<td><input type="number" id="nolabour" name="nolabour"></td>
<td><input type="number" id="labhrperdsy" name="labhrperdsy"></td>
<td><input type="number" id="labnodays" name="labnodays"></td>
<td><input type="number" id="labhrrate" name="labhrrate"
oninput="labourSum()"></td>
<td><input type="text" id="labrate" name="labrate"></td>
javascript code:
function labourSum(){
var aValue = document.getElementById("nolabour").value;
var bValue = document.getElementById("nolabour").value;
var cValue = document.getElementById("nolabour").value;
var dValue = document.getElementById("nolabour").value;
var result = document.getElementById("labrate");
result.value = parseFloat(aValue) * parseFloat(bValue) * parseFloat(cValue) * parseFloat(dValue);
}
result
The value of elements is always a string. Convert the values to numbers first before adding them together. The other problem is that you probably copy-pasted the line, and are selecting #nolabour over and over again.
Try something like this instead:
const totalPay = ['nolabour', 'labhrperdsy', 'labnodays', 'lahbrrate']
.reduce((subtotal, id) => {
return subtotal + Number(document.getElementById(id));
}, 0);
function onChange() {
let aValue = document.getElementById('a').value;
let bValue = document.getElementById('b').value;
let cValue = document.getElementById('c').value;
const result = document.getElementById('result')
result.innerHTML = parseFloat(aValue) * parseFloat(bValue) * parseFloat(cValue)
}
onChange()
<div>
<input id="a" value="1" onkeyup="onChange()">
<input id="b" value="2" onkeyup="onChange()">
<input id="c" value="3" onkeyup="onChange()">
<br>
<br>
Result: <span id="result" style="font-size: 24px"></span>
</div>
A very minimal way is to wrap the <input>s into a <form> and use On-event Attribute Event Handler on it.
<form oninput=...
oninput is an on-event that occurs when the user types in an <input>, <textarea>, etc. and the value of the keystrokes are immediately captured for the event handler to process. The values that all form controls deal with are strings not numbers, so the values must be converted before anything mathematical can be applied. The most common way:
<input id="input" value="10">
var string = document.getElementById('input').value;
var number = parseFloat(string); /*OR*/ parseInt(string, 10); /*OR*/ Number(string);
parseFloat(string);
parseInt(string, 10);
Number(string);
I prefer to convert earlier by using type="number" on <input> and the .valueAsNumber property. Like this:
<input id="input" type="number" value="10">
var number = document.getElementById('input').valueAsNumber;
I added an <output> tag as well and added a for attribute to it with the value of a space delimited list of <input> #ids. Having done that links the <output> to those <input>s so now the values of all the <input>s calculated results will be the value of the <output>.
Demo
input,
output {
display: block;
font: 400 16px/1.2 Consolas;
text-align: right;
padding: 0 2px;
}
output {
display: table;
text-align: right;
min-width: 20ch;
}
<form id='ABCD' oninput="D.value = A.valueAsNumber * B.valueAsNumber * C.valueAsNumber">
<input id="A" type="number" value='1'>
<input id="B" type="number" value='1'>
<input id="C" type="number" value='1'>
<output id="D" for="A B C">0</output>
</form>
this is my first time posting on this site. i have a webpage that outlines one of my products that I intent to sell
here is my dilemma. I have this code that asks the user to press + and - buttons for the quantity of the item that they want. Now what i am trying to work out is if the user presses + or - any number of times I need to be able to to take into account the number of clicks and calculate the total price for the order on a separate line. Im very new to javascript all help is appreciated thanks
<form>
<br> Item Price: $463.50
<br> Please Select Quantity
<input type='button' name='subtract' onclick='javascript: document.getElementById("qty").value--;' value='-'/>
<input type='button' name='add' onclick='javascript: document.getElementById("qty").value++;' value='+'/>
<input type='text' name='qty' id='qty' />
</form>
<form>
<br> Item Price: $<span id='price'>463.50</span>
var unitprice = (document.getElementById('price').innerText || document.getElementById('price').textContent);
var price = parseFloat(unitprice);
var count = parseInt(document.getElementById("qty").value, 10)
var total = price * count;
alert(total); // or do whatever you want
I would separate out the Javascript code into its own <script> element, and do something like:
<form>
<br/> Item Price: $<span id="price">463.50</span>
<br/> Please Select Quantity
<input type="button" name="subtract" id="subtract" value="-"></input>
<input type="button" name="add" id="add" value="+"></input>
<input type="text" name="qty" id="qty" value="0"></input>
<br/> Total
<input type="text" name="total" id="total" value="0"></input>
</form>
The Javascript would look like:
$(function() {
var price = parseFloat($('#price').text());
$('#subtract').on("click",function() {
var $qty = $('#qty');
var current = parseInt($qty.val());
if ( current > 0 ) {
$qty.val(current-1);
$('#total').val(price*(current-1));
} else {
$('#total').val(0);
}
});
$('#add').on("click",function() {
var $qty = $('#qty');
var current = parseInt($qty.val());
$qty.val(current+1);
$('#total').val(price*(current+1));
});
});
You can see it in action.
This is all do-able without jQuery, but it makes life a lot easier!
Since you mentioned you're new to this, a word of WARNING: In the real app only use the quantity from the page, and re-calculate out how much to charge them on the back end. It would be very easy for someone to modify either the price or total in the DOM; if you were to use the price or total from the DOM then a malicious user could buy it for any price they wanted! Always assume input is malicious or incorrect.
var value = parseInt(document.getElementById("qty").value, 10)
item_price = item_price * value;
document.getElementById("someid").innertHTML = item_price;
How do I go on about selecting elements which has the same attribute values in jquery. And then comparing which of those 2 has a greater value.
Here is what I have so far. The problem that I'm having with this is that I don't really get any output if the first number in the pair is the larger one.
<script>
$(function(){
var j = [];
$('.loo').each(function(index){
var grp = $(this).attr('data-x');
var num = $(this).val();
var id = $(this).attr('id');
var pair_val = pair_value(grp);
var pair_id = pair_identity(id);
console.log(get_max(num, pair_val, id, pair_id));
});
function get_max(num1, num2, id1, id2){
var decide = 0;
if(num1 > num2){
decide = id1;
}else{
decide = id2;
}
return decide;
}
function pair_value(conn){
var pair = $("input[data-x="+ conn +"]").val(); //my problem is here
return pair;
}
function pair_identity(conn){
var pair_id = $("input[data-x="+ conn +"]").attr('id'); //my problem is here
return pair_id;
}
});
</script>
Html:
<p>
<input type="text" id="e" name="e" class="loo" value="1" data-x="a">
</p>
<p>
<input type="text" id="f" name="f" class="loo" value="10" data-x="a">
</p>
<p>
<input type="text" id="g" name="g" class="loo" value="37" data-x="b">
</p>
<p>
<input type="text" id="h" name="h" class="loo" value="25" data-x="b">
</p>
<p>
<input type="text" id="i" name="i" class="loo" value="11" data-x="c">
</p>
<p>
<input type="text" id="j" name="j" class="loo" value="12" data-x="c">
</p>
var highest = new Array();
$('.loo').each(function(){
if(!highest[$(this).data('x')] || parseInt($(this).val()) > highest[$(this).data('x')] )
highest[$(this).data('x')] = parseInt($(this).val());
});
This will loop through all instances of .loo and checks if there is no entry yet or if the current saved value is lower than the current elements value, in that case it will update the array entry.
This will leave you with an array containing all max values for all possible values of data-x
EDIT
excuse me, some syntax errors were present.
EDIT 2
shorter version
http://jsfiddle.net/kkbkb/1/
The problem you're no doubt having is that you are comparing character strings (obtained with .val()), not numbers. This has a very different behviour - effectively deciding which one is alphabetically before another.
Change this line:
if(num1 > num2){
to
if(parseInt(num1,10) > parseInt(num2,10)){