Add value Y to value X each time a button is clicked - javascript

I might be missing the elephant in the room here, but I can't figure this out.
What I want to do, add Y amount to variable X each time a button is clicked. Y is passed through the onClick function.
addStat: function(button, amount, price) {
var curPrice = price;
var priceHtml = $(button).closest("tr").find('.price');
curPrice += price;
$(priceHtml).text(curPrice);
},
This is what I have, but I have a feeling that I'd Need to set a value to current price, outside the function maybe? I tried but then It'd always reset on each button press.
Any idea/suggestion is welcome. I'm kinda of new to JS. Just learning.
One method I know would work, if I'd get the value of the price HTML element. But the issue with that, is that it can be edited with chrome inspect.

You just need to get the current price value using priceHtml.text() and assign it to your curPrice variable.
Try this:
var priceHtml = $(button).closest("tr").find('.price');
var curPrice = parseFloat(priceHtml.text())||0;
curPrice += price;
priceHtml.text(curPrice);

I tried to reduce what you're trying to do to just a minimum example. From your question, it sounds like you're trying to do four things on a click:
take in the text value of an element
coerce that value to a number
double the number
write the new value to the element
You don't have to move the curPrice var outside of the function. It doesn't matter that you redeclare it on each click, because you're immediately doubling it against itself. And you'll want to parse the incoming text to a number with parseInt, otherwise javascript will assume you're trying to do string concatenation:
function addStat(event) {
var curPrice = parseInt(event.target.textContent, 10);
curPrice += curPrice;
$(event.target).text(curPrice);
}
$('.price').click(addStat)
.price {
background-color: #ace;
height: 25px;
margin: 10px 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="price">1</div>
<div class="price">3</div>

You have to set your let curPrice = 0; outside the function, on top of your code. Then you can simply use curPrice += parseFloat(price); inside the function. That prevent the wrong overwriting value of curPrice.
EDIT -> Example:
let curPrice = 0;
function updatePrice(button, amount, price) {
if(!isNaN(price)) {
curPrice += price;
return $(button).find('.price').text(curPrice.toFixed(2));
}
return false;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onclick="updatePrice(this, 10.00, 10.00)">
<span class="price">0.00</span>
</button>
<button onclick="updatePrice(this, 10.00, 'isNaN')">
<span class="price">Not working!</span>
</button>
And use let variable; instead of var variable;
Another example:
function updatePrice(button, amount, price) {
//Find the .price inside the clicked button
let $price = $(button).find('.price');
//Test if price is numeric
if(!isNaN(price)) {
//If is numeric retrive the current price and add the price
let newPrice = parseFloat($price.text()) + parseFloat(price);
//Return the new price and print it on .price inside the button
return $price.text(newPrice.toFixed(2)); // .toFixed(2) return 2 decimal.
}
//If price is not numeric return false
return false;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- price is numeric so it works -->
<button onclick="updatePrice(this, 10.00, 10.00)">
<span class="price">10.00</span>
</button>
<!-- price is not numeric so the function return false -->
<button onclick="updatePrice(this, 10.00, 'not numeric')">
<span class="price">10.00 (not working)</span>
</button>
Good luck!

Related

Subtract amount on form submit JavaScript / JQuery

I have a checkout page, where I would like to implement a new feature: subtract from total cart value a certain amount, introduced in an input.
Example: There is 1 item in cart, with value of 10.00$. If user typed 100 in that input, then he would have a discount of 1$ (100 pts = 1$ in this example) and the final value of the cart would be 9.00$. Since I'm using some integrated apps for getting/calculating item value, total cart value, etc. I would like to get some generic code, which I would eventually adjust, to link with my existing code, functions, etc.
The function I have should have these features:
create form
get input value
subtract used points from user's total amount (for example totalPts = 1000)
subtract from cart total value used points, converted into $ (100pts = 1$)
For now, my function looks like this:
function appendRefferalPoints() {
const totalPts = 1000;
// creating form - ok
$form = $('<form id="refForm" class="coupon-form" action></form>');
$form.append(
'<input type="text" id="refValue" name="refInput" class="coupon-value input-small" >'
);
$form.append('<button type="submit" class="btn">Aplica</button>');
$("body").append($form);
// get input value - not ok
$("#refForm").submit(function () {
let value = 0;
$.each($("#refForm").serializeArray(), function (i, field) {
value[field.name] = field.value;
});
});
// subtraction from totalPts logic - not ok
let rez = totalPts - value;
console.log("Final Rez: " + rez);
// subtraction converted pts from cart value logic
}
Now when I submit the form I only url changes from /checkout#/cart to /checkout/?refInput=512#/cart
function appendRefferalPoints() {
const totalPts = 1000;
let cartValue=10;
let discount=0;
let inputValue = 0;
// creating form - ok
$form = $('<form id="refForm" class="refForm coupon-form" ></form>');
$form.append(
'<input type="text" id="refValue" name="refInput" class="coupon-value input-small" value="100" >'
);
$form.append('<button id="btnClick" class="btn">Aplica</button>');
$("body").append($form);
$(document).on("submit", "#refForm", function(e){
//getting input value while submitting form
inputValue=$("#refValue").val();
//converting 100 pts to 1 dallor
discount=inputValue/100;
//calculating balance pts
let balancePts = totalPts - parseInt(inputValue);
//calculating final amount
let finalCartValue=cartValue-discount;
alert("finalCartValue"+finalCartValue);
});
}
appendRefferalPoints();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

How To make the input add values every time the button is clicked in jquery?

I got buttons to click , and when its clicked i want the value to be incremented by the same value that is being clicked;
here is my html
<div id="setTimer">
<div class="spans">
<span class="timeSet" >1</span>
<span class="timeSet">2</span>
<span class="timeSet">3</span>
<span class="timeSet">4</span>
</div>
<div class="spans">
<span class="timeSet">5</span>
<span class="timeSet">6</span>
<span class="timeSet">7</span>
<span class="timeSet">8</span>
</div>
<div class="spans">
<span class="timeSet">9</span>
<span class="timeSet">0</span>
<span class="timeSet">+30s</span>
</div>
</div>
javascript
$(document).ready(function(){
var count = 0
var btnCountOutput = $('#btnCountOutput');
var txt = $(this);
$('.timeSet').click(function(txt){
count++;
if(count > 3){
console.log('that cant be done!');
return false;
}
var output = txt.currentTarget.innerHTML;
output++;
var num = parseFloat(output);
var inputOut = btnCountOutput.val(num);
console.log(num);
console.log(count);
});
});
Html for the output
<div class="timeCount">
<input type="text" placeholder="Buttonclick Counter" class="col"
id="btnCountOutput">
CSS if needed
#setTimer .spans{
margin-bottom: 10px;
}
#setTimer span{
width: 15px;
height: 10px;
border-radius:50%;
background: white;
text-align: center;
padding: 4px;
cursor: pointer;
}
well , just like Java Script where i could just write;
btnCountOutput.value += num;
That every time the button is clicked , just add on the output any value that is clicked
You need to grab the value of the text box then add it to the number you pass in. After the addition happens, you can then set the value of the text box again. I added a variable called currentCount as an example:
https://jsfiddle.net/mswilson4040/487eaopt/
$(document).ready(function() {
var count = 0
var btnCountOutput = $('#btnCountOutput');
var txt = $(this);
$('.timeSet').click(function(txt) {
count++;
if (count > 3) {
console.log('that cant be done!');
return false;
}
var output = txt.currentTarget.innerHTML;
output++;
var num = parseFloat(output);
var currentCount = btnCountOutput.val(); // Grab the current value
var inputOut = btnCountOutput.val(+num + +currentCount); // Add the two values together and set the text box (make sure to convert string to number)
console.log(num);
console.log(count);
});
});
You also don't need your parseFloat function. You do need some function to make sure you're string gets converted to a number, but you want either Number, parseInt, or +. parseFloat isn't needed unless you'll be working with decimal values.

Why is JavaScript correctly calculating my variable yet displays it as undefined in the HTML?

And how do I get it to display the number, not undefined?
It's a tipping app. The user inputs the price of whatever it is they bought (pizza, haircut, etc.) in #price, then calcTip() calculates the tip, sends it over to calcTotal() which calculates the total, and sends it over to displayAmounts().
I don't know exactly what happens, but something messes up with the variable tip. calcTip() works correctly and calculates the tip amount successfully. I know this because the JavaScript console displays the amount when I input tip;. However, on the page, #tipSpan displays the tip as undefined.
What baffles me most is that the variable total works perfectly fine.
Does anyone know what might be going on or how I can fix it?
Here is the HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Tipping App</title>
<style>
<!-- Temporary -->
#error {
display: none;
}
</style>
</head>
<body>
<div id="wrapper">
<header>
<h1>Tipping App</h1>
</header>
<section>
<div class="price">
<h2>Price Information</h2>
<label for="priceInput">Enter the price below!</label><input id="priceInput" type="text"><button id="calcButton">Calculate the Tip</button>
<p id="error">Error: You need to enter the cost!<br><br>Use only numbers and decimal points, no currency symbols or letters.</p>
</div>
<div id="tipContainer" class="tip">
<h2>Tip Information</h2>
<p id="tipPara">Your tip should be... <span>$<span id="tipSpan"></span></span></p>
</div>
<div id="totalContainer" class="total">
<h2>Total Information</h2>
<p id="totalPara">Your total is... <span>$<span id="totalSpan"></span></span></p>
</div>
</section>
</div>
<script src="js/app.js"></script>
</body>
</html>
Here is the JavaScript:
///// VARIABLES
//////////////////////////////
var priceInput = document.getElementById("priceInput");
var calcButton = document.getElementById("calcButton");
var error = document.getElementById("error");
var tipContainer = document.getElementById("tipContainer");
var tipPara = document.getElementById("tipPara");
var tipSpan = document.getElementById("tipSpan");
var totalContainer = document.getElementById("totalContainer");
var totalPara = document.getElementById("totalPara");
var totalSpan = document.getElementById("totalSpan");
var tip;
var total;
///// FUNCTIONS
//////////////////////////////
function calcTip() {
var price = priceInput.value; // This is the price the user inputs
var minTip = (Math.ceil(price * .15)); // Calculates a 15% tip rounded up to the nearest dollar
var maxTip = (price * .2); // Calculates a 20% tip
if (isNaN(price) || price === "") {
// If the user doesn't enter a number
// Or doesn't enter anything,
// Then display the error message
error.style.display = "block";
return;
} else {
error.style.display = "none";
if (maxTip < minTip) {
// If the 20% tip is less than the 15% rounded tip,
// Then let's go with that 20% tip
calcTotal(price, maxTip);
tip = maxTip;
} else {
// Otherwise, let's just do the 15%
calcTotal(price, minTip);
tip = minTip;
};
};
};
function calcTotal(price, tip) {
// Add the price and the tip together to yield the total
price = parseInt(price);
tip = parseInt(tip);
total = (price + tip);
displayAmounts();
}
function displayAmounts() {
// Update the page to display the tip and the total to the user
tipContainer.style.display = "block";
totalContainer.style.display = "block";
tipSpan.innerText = tip;
totalSpan.innerText = total;
}
///// EVENTS
//////////////////////////////
calcButton.addEventListener("click", calcTip);
Also, unrelated, but does my JavaScript look good? Is it clean code? I hope to find a web development job in the near future, and I know I need to be good at JavaScript.
WORKING DEMO
Update the function arguments
function calcTotal(price, maxTip) {
// Add the price and the tip together to yield the total
price = parseInt(price);
tip = parseInt(maxTip);
total = (price + tip);
displayAmounts();
}
Here the argument tip is overriding the global variable. Replace it to maxTip as you call.
1) In function displayAmounts, pass parameters tip & total
2) Instead of
tipSpan.innerText = tip,
TRY WITH
tipSpan.innerHTML = tip;
and same for total ,
use totalSpan.innerHTML = total
instead of
totalSpan.innerText ;
Then it should work
Try changing your method definition so it passes the values in:
displayAmounts(); should become displayAmounts(tip, total);
See the fiddle here.
Also you should use parseFloat rather than parseInt assuming you'll want to be more accurate than whole numbers.
Just a small mistake!
Instead of:
calcTotal(price, minTip);
tip = minTip;
Do:
tip = minTip;
calcTotal(price, minTip);
This way tip is calculated before displayAmounts is run.
Abut your code:
This is fine with just getting started. I recommend going through w3school's tutorials on javascript. The more you use javascript, the better you will get.
If you want a learning path I would recommend taking, let me know.
innerText works only on IE. textContent is W3C-compliant, but if you want your code to be standards compliant and cross-browser safe you should use this:
while( tipSpan.firstChild ) {
tipSpan.removeChild( tipSpan.firstChild );
}
tipSpan.appendChild( document.createTextNode(tip) );
Do this for totalSpan also.

Need Help in adding div elements which have integer values

I have three DIV whose content are integer values and are updated frequently from another source. My main idea here was to take the content of the three divs parse it into float or integer , add them and display the total in another div. I am looking forward to handle the content in div using a onchange() function, because the the content in them will be changing frequently. Below is my code, its currently not working, i will really appreciate it if you give me a hand of help with this.
The content in this divs will be frequently updated using a text input, you can create a text inout that manipulates the first div then displays the whole sum
Thanks in advance.
<script>
function total() {
var value1 = parseFloat($('#div1').innerHTML ()) || 0;
var value2 = parseFloat($('#div2').innerHTML ()) || 0;
var value3 = parseFloat($('#div1').innerHTML ()) || 0;
var total;
total=value1 + value2 + value3;
$('#total').html(total);
}
</script>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body >
<div id="mywraper">
<div id="div1" onchange="total()">
4
</div>
<div id="div2" onchange="total()">
5
</div>
<div id="div2" onchange="total()">
6
</div>
</div>
<div id="total_div">
Total $<span id="total"></span>
</div>
</body>
</html>
Use this html()
<script>
function total() {
var value1 = parseFloat($('#div1').html()) || 0;
var value2 = parseFloat($('#div2').html()) || 0;
var value3 = parseFloat($('#div1').html()) || 0;
var total;
total=value1 + value2 + value3;
$('#total').html(total);
}
</script>
Try this:
function total() {
// fetch text using 'text' method and then convert string into number using '+' operator
var value1 = +$('#div1').text() || 0;
var value2 = +$('#div1').text() || 0;
var value3 = +$('#div1').text() || 0;
var total = value1 + value2 + value3;
$('#total').html(total);
}
http://jsfiddle.net/uxajjk1b/2/
Use text() instead of innerHTML, like so:
<script>
function total() {
var value1 = parseFloat($('#div1').text()) || 0;
var value2 = parseFloat($('#div2').text()) || 0;
var value3 = parseFloat($('#div1').text()) || 0;
var total;
total=value1 + value2 + value3;
$('#total').html(total);
}
</script>
I didn't really want to answer, as this might be difficult to solve due to the fact that we have no idea how the values are updated in the first place. However, I ended up doing relatively extensive example, so here we are.
So as mentioned before, onChange requires user input or action to detect any change. So that means your total() would only trigger once when the page is loaded ( assuming it's placed right before </body> ).
The best method would be to also stick the total() inside the original function that changes the values inside the html elements. This way total() is also triggered each time.
I couldn't resist making the total() more dynamic. This way, if you add or remove those child divs, the javascript won't need to be updated.
Here's a link to the original jsfiddle
var parentContainer = $('#mywraper');
function total() {
var values = {}; // Optional****
var total = 0;
// Loops through parent containers children ( in this case div elements ).
parentContainer.children().text(function( i, val ) {
var value = parseInt( val );
// Creates a variable where the variable name is based on the current elements index and value is based on the text inside the element.
values[ 'child_' + (i+1) ] = value; // Optional****
// Sums up all the values
total += value;
});
// The optional lines enable you independently check each value, for example:
// console.log( values.child_1 )
// Push total into the #total element.
$('#total').html( total );
}
total();
Here's an example where the values are updated with a click event. So what you do is just add the total() inside the click event as well.
function total() {
var parentContainer = $('#mywraper'),
total = 0;
parentContainer.children().text(function( i, val ) {
total += parseInt( val );
});
$('#total').html( total );
}
total();
$('#updateBtn').on("click", function() {
$('#mywraper').children().text(function( i, val ) {
return parseInt( val ) + 1;
});
total();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="mywraper">
<div>4</div>
<div>5</div>
<div>6</div>
</div>
<div id="total_div">
Total $<span id="total"></span>
</div>
<button id="updateBtn">Update values</button>

Calculating sum of order with changing price values in Javascript

I am trying to use Javascript to calculate sum of order in one big form. Each product has its own price, however, there are more prices tied with some products. Each product has it's own price, but if a customer orders bigger quantity of this product, the price will drop to a value that is specified in a database table.
To simplify, the shopping form for one item looks something like this.
<input name="id" value="'.$id.'" type="hidden">
<input name="price_'.$id.'" value="'.$price.'" type="hidden">
<input name="quantity_'.$id.'" type="text" onchange="calculateTotal()">
I have a table with the discounts: itemId, minimumQuantity, priceAfterDiscount. There can be more than one discounts connected with one item. The MySQL query works with LEFT JOIN of Items and Discounts tables.
calculateTotal() calculates the total of order after every input change.
What I would like to do, is to check if the quantity of certain product is greater than the value needed for the discounts and if so, I would like to change the value of the input with price from item's regular price to the discounted one. Then, calculateTotal() will use that price and update the total.
To do so, I think I can do something like adding more hidden inputs with values of all discounts. The function would check if there is a discount linked to every item and if so, it will check if the quantity is greater than requiredQuantity and if this condition is met, it will update the value of price hidden input. Please keep in mind that there can be multiple discounts connected to one item - the function should find the lowest price that meets requiredQuantity.
I am trying to do this - create the hidden inputs and somehow parse them in javascript, but I am just not able to figure this out. I tried my best to explain the problem, however, if my explanation is not sufficient, I will try to answer your questions regarding my issue.
I hope you are able and willing to help me. Thanks for help in advance.
Perhaps something like this example.
CSS
.itemLabel, .currentPrice, .subTotal {
display: inline-block;
width: 40px;
}
#myTotal {
border:2px solid red;
}
HTML
<fieldset id="myInputs"></fieldset>
<div id="myTotal"></div>
Javascript
var myInputs = document.getElementById('myInputs'),
myTotal = document.getElementById('myTotal'),
order = {
total: 0
},
items = {
foo: {
1: 0.5,
100: 0.25
},
bar: {
1: 1,
100: 0.5
}
},
totalNode;
function calculateTotal() {
var newTotalNode;
Object.keys(order).filter(function (key) {
return key !== 'total';
}).reduce(function (acc, key) {
order.total = acc + order[key].subTotal;
return order.total;
}, 0);
newTotalNode = document.createTextNode(order.total.toFixed(2));
if (totalNode) {
myTotal.replaceChild(newTotalNode, totalNode);
totalNode = newTotalNode;
} else {
totalNode = myTotal.appendChild(newTotalNode);
}
console.log(JSON.stringify(order));
}
calculateTotal();
Object.keys(items).forEach(function (key) {
var div = document.createElement('div'),
label = document.createElement('label'),
price = document.createElement('span'),
input = document.createElement('input'),
subtotal = document.createElement('span'),
priceNode,
subTotalNode;
order[key] = {
quantity: 0,
subTotal: 0,
price: items[key]['1']
};
priceNode = document.createTextNode(order[key].price.toFixed(2));
subTotalNode = document.createTextNode(order[key].subTotal.toFixed(2));
label.className = 'itemLabel';
label.setAttribute("for", key);
label.appendChild(document.createTextNode(key));
price.className = 'currentPrice';
price.id = key + 'CurrentPrice';
price.appendChild(priceNode);
input.id = key;
input.name = 'myFormGroup';
input.type = 'text';
input.addEventListener('change', (function (key, order, priceNode, subTotalNode) {
return function () {
var value = +(this.value),
newPriceNode,
newSubTotalNode;
Object.keys(items[key]).sort(function (a, b) {
return b - a;
}).some(function (quantity) {
if (value >= quantity) {
order.price = items[key][quantity];
newPriceNode = document.createTextNode(order.price.toFixed(2));
priceNode.parentNode.replaceChild(newPriceNode, priceNode);
priceNode = newPriceNode;
return true;
}
return false;
});
order.subTotal = order.price * value;
newSubTotalNode = document.createTextNode(order.subTotal.toFixed(2));
subTotalNode.parentNode.replaceChild(newSubTotalNode, subTotalNode);
subTotalNode = newSubTotalNode;
calculateTotal();
};
}(key, order[key], priceNode, subTotalNode)), false);
subtotal.className = 'subTotal';
subtotal.id = key + 'SubTotal';
subtotal.appendChild(subTotalNode);
div.appendChild(label);
div.appendChild(price);
div.appendChild(input);
div.appendChild(subtotal);
myInputs.appendChild(div);
});
On jsFiddle

Categories

Resources