if inside if inside if statements - is it possible? - javascript

I'm trying to display a calculation of two radio groups, in real time, before users click submit button.
<div class="container-5">
<div class="choices1">
<h1 class>Regular<br>Regular Choice</h1>
<input type="radio" id="thirteen" name="style" value="13.00">
</div>
<div class="choices2">
<h1>Popular<br>Popular Choice</h1>
<input type="radio" id="fifteen" name="style" value="15.00">
</div>
<div class="choices3">
<h1>Fancy<br>Fancy Choice<br>Literally.</h1>
<input type="radio" id="twenty" name="style" value="20.00">
</div>
</div>
<div class="container-8">
<div class="gratuity1">
<h1 class>15%<br>Good.</h1>
<input type="radio" id="15" name="tip" value=".15">
</div>
<div class="gratuity2">
<h1>20%<br>Excellent Service.</h1>
<input type="radio" id="20" name="tip" value=".20">
</div>
<div class="gratuity3">
<h1>25%<br>Beyond Excellent</h1>
<input type="radio" id="25" name="tip" value=".25">
</div>
</div>
I'm using pure javascript.
Each of these categories is suppose to represent the value of the selected radio button. Once I've defined the variables I created if statements to test if both buttons were selected and event would occur
var styleVal1= 3.0;
var styleVal2 = 5.0;
var styleVal3 = 10.0;
var tipVal1 = 0.1;
var tipVal2 = 0.15;
var tipVal3 = 0.2;
var total = 0.00;
if (document.getElementById("thirteen").selected) {
document.getElementById("thirteen").addEventListener("click", function() {
total = styleVal1;
document.getElementById("total").innerHTML = "Total:$ " + total;
if (document.getElementById("15").selected) {
total += total * tipVal1;
document.getElementById("total").innerHTML = "Total:$ " + total;
} else if (document.getElementById("20").selected) {
total += total * tipVal2;
document.getElementById("total").innerHTML = "Total:$ " + total;
} else (document.getElementById("25").selected) {
total += total * tipVal3;
document.getElementById("total").innerHTML = "Total:$ " + total;
}
});
}
I also created if statements for document.getElementById("fifteen").selected) {} and if (document.getElementById("twenty").selected {}
Am I not putting this in the right order or am I missing something? Is it even possible to do else if statements inside if statements?

As I see your JS code is wrong logically.
First of all click event is not yet binded because this condition if (document.getElementById("thirteen").selected) will always return false and event will not binded to radio element.
else cannot have a condition. else (document.getElementById("25").selected) this is wrong.
I've corrected your code but you neeed to correct the rest,
document.getElementById("thirteen").addEventListener("click", function() {
total = styleVal1;
document.getElementById("total").innerHTML = "Total:$ " + total;
if (document.getElementById("15").selected) {
total += total * tipVal1;
document.getElementById("total").innerHTML = "Total:$ " + total;
} else if (document.getElementById("20").selected) {
total += total * tipVal2;
document.getElementById("total").innerHTML = "Total:$ " + total;
} else if (document.getElementById("25").selected) { //changed this to else-if
total += total * tipVal3;
document.getElementById("total").innerHTML = "Total:$ " + total;
}
});

Related

What is the better way to counting number on different event?

I already solve it,
Here is my HTML code 👇
<strong>Product Price = $20</strong><br>
<strong>Bag Price = $10</strong><br>
<hr>
<label>Quantity of products</label>
<br>
<input type="number" id="quantity">
<br>
<input type="checkbox" id="with_bag">
<label>With a bag</label>
<br>
<p>Total Price 👇</p>
<input type="text" id="total_price" readonly>
And here is my jQuery code 👇
// Calculate total price (On Keyup)
$(document).on("keyup", "#quantity", function() {
var quantity = $('#quantity').val();
var content_price = $("#with_bag").is(':checked') ? 10 : 0;
var total_price = (20 * quantity) + content_price;
$('#total_price').val('$' + total_price.toFixed(2));
});
// Calculate total price (On Click)
$(document).on('click', '#with_bag', function(){
var quantity = $('#quantity').val();
var total_price = 20 * quantity;
if(this.checked){
total_price = (20 * quantity) + 10;
}
$('#total_price').val('$' + total_price.toFixed(2));
});
I just want to know, how to get these two different events (on keyup & on click) at the same function?
You can make a function and track your event conditionally if this is exactly what you want.
function myFunction(event){
var quantity = $('#quantity').val();
if(event.type == "keyup"){
var content_price = $("#with_bag").is(':checked') ? 10 : 0;
var total_price = (20 * quantity) + content_price;
$('#total_price').val('$' + total_price.toFixed(2));
}
else{
var total_price = 20 * quantity;
if($('#with_bag').is(":checked")){
total_price = (20 * quantity) + 10;
}
$('#total_price').val('$' + total_price.toFixed(2));
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<strong>Product Price = $20</strong><br>
<strong>Bag Price = $10</strong><br>
<hr>
<label>Quantity of products</label>
<br>
<input type="number" onkeyup="myFunction(event);" id="quantity">
<br>
<input type="checkbox" onclick="myFunction(event);" id="with_bag">
<label>With a bag</label>
<br>
<p>Total Price 👇</p>
<input type="text" id="total_price" readonly>

Computer Guess A Number JavaScript

I am trying to create a simple "guess the number game" in a web page where a user is the one thinking of the number and the computer is to guess the number(in range 1-100) that the user is thinking (no user input required). I've created four buttons for user to respond to the computer's guess: Start, Guess Higher, Guess Lower, Bingo. I have a problems with this range. If user click button 'Lover' it should became the biggest number (For example, 60 is too high, then computer guess between 1-60)(same with 'Higher'), but can't connect it together. Here is my code:
let computerGuess = 0,
numberOfGuesses = 0;
function writeMessage(elementId, message, appendMessage) {
let elemToUpdate = document.getElementById(elementId);
if (appendMessage) {
elemToUpdate.innerHTML = elemToUpdate.innerHTML + message;
} else {
elemToUpdate.innerHTML = message;
}
};
function newGame() {
computerGuess = 0;
numberOfGuesses = 1;
writeMessage('historyList', '');
document.getElementById('buttonLover').disabled = true;
document.getElementById('buttonHigher').disabled = true;
document.getElementById('buttonBingo').disabled = true;
}
function randomNumber(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}
function computerGuessed() {
let compGuess = document.getElementById('compGuess'),
butLover = document.getElementById('buttonLover'),
butHigher = document.getElementById('buttonHigher'),
butBingo = document.getElementById('buttonBingo'),
statusArea = document.getElementById('statusArea'),
historyList = document.getElementById('historyList');
document.getElementById('buttonArea').disabled = true;
butLover.disabled = false;
butHigher.disabled = false;
butBingo.disabled = false;
let a = 1, b = 100;
computerGuess = randomNumber(a, b);
writeMessage('compGuess', '<p>' + computerGuess + '</p>', true);
writeMessage('statusArea', '<p>Choose a number between 1-100 and click the button.</p>');
butLover.addEventListener("click", function () {
writeMessage('historyList', '<li>' + computerGuess + ' (too high)</li>', true);
writeMessage('compGuess', '<p>' + '' + '</p>', false);
computerGuess = randomNumber(a, computerGuess);
writeMessage('compGuess', '<p>' + computerGuess + '</p>', true);
numberOfGuesses++;
});
butHigher.addEventListener("click", function () {
writeMessage('historyList', '<li>' + computerGuess + ' (too low)</li>', true);
writeMessage('compGuess', '<p>' + '' + '</p>', false);
computerGuess = randomNumber(computerGuess, b);
writeMessage('compGuess', '<p>' + computerGuess + '</p>', true);
numberOfGuesses++;
});
butBingo.addEventListener("click", function () {
writeMessage('statusArea', '<p>You got me in ' + numberOfGuesses + ' guesses, I was thinking ' + computerGuess + '. Let\'s go again...</p>');
writeMessage('compGuess', '<p>' + '' + '</p>', false);
document.getElementById('buttonArea').disabled = false;
newGame();
});
}
window.onload = function () {
newGame();
document.getElementById('buttonArea').addEventListener('click', computerGuessed);
};
<div id="game">
<h1>Computer Guessing Game</h1>
<div id="statusArea">
<p>Choose a number between 1-100 and click the button.</p>
</div>
<div id="compGuess">
</div>
<div class="buttons">
<input type="button" value="Start" class="button" id="buttonArea"/>
<input type="button" value="Lover" class="button" id="buttonLover"/>
<input type="button" value="Higher" class="button" id="buttonHigher"/>
<input type="button" value="Bingo" class="button" id="buttonBingo"/>
</div>
<div id="historyArea">
<h2>Computer Previous Guesses</h2>
<ol id="historyList">
</ol>
</div>
</div>
Each time you call computerGuessed() you reset a & b to 1 and 100. Try setting them as global vars (since you're already using global vars), and set them to 1 and 100 on the start of each game.
let computerGuess = 0,
numberOfGuesses = 0,
a=0,
b=100;
function writeMessage(elementId, message, appendMessage) {
let elemToUpdate = document.getElementById(elementId);
if (appendMessage) {
elemToUpdate.innerHTML = elemToUpdate.innerHTML + message;
} else {
elemToUpdate.innerHTML = message;
}
};
function newGame() {
computerGuess = 0;
numberOfGuesses = 1;
a = 0;
b = 100;
writeMessage('historyList', '');
document.getElementById('buttonLower').disabled = true;
document.getElementById('buttonHigher').disabled = true;
document.getElementById('buttonBingo').disabled = true;
}
function randomNumber(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}
function computerGuessed() {
let compGuess = document.getElementById('compGuess'),
butLower = document.getElementById('buttonLower'),
butHigher = document.getElementById('buttonHigher'),
butBingo = document.getElementById('buttonBingo'),
statusArea = document.getElementById('statusArea'),
historyList = document.getElementById('historyList');
document.getElementById('buttonArea').disabled = true;
butLower.disabled = false;
butHigher.disabled = false;
butBingo.disabled = false;
computerGuess = randomNumber(a, b);
writeMessage('compGuess', '<p>' + computerGuess + '</p>', true);
writeMessage('statusArea', '<p>Choose a number between 1-100 and click the button.</p>');
}
window.onload = function () {
newGame();
document.getElementById('buttonArea').addEventListener('click', computerGuessed);
let butLower = document.getElementById('buttonLower'),
butHigher = document.getElementById('buttonHigher'),
butBingo = document.getElementById('buttonBingo');
butLower.addEventListener("click", function () {
writeMessage('historyList', '<li>' + computerGuess + ' (too high)</li>', true);
writeMessage('compGuess', '<p>' + '' + '</p>', false);
b = computerGuess;
computerGuessed();
writeMessage('compGuess', '<p>' + computerGuess + '</p>', true);
numberOfGuesses++;
});
butHigher.addEventListener("click", function () {
writeMessage('historyList', '<li>' + computerGuess + ' (too low)</li>', true);
writeMessage('compGuess', '<p>' + '' + '</p>', false);
a = computerGuess;
computerGuessed();
writeMessage('compGuess', '<p>' + computerGuess + '</p>', true);
numberOfGuesses++;
});
butBingo.addEventListener("click", function () {
writeMessage('statusArea', '<p>You got me in ' + numberOfGuesses + ' guesses, I was thinking ' + computerGuess + '. Let\'s go again...</p>');
writeMessage('compGuess', '<p>' + '' + '</p>', false);
document.getElementById('buttonArea').disabled = false;
newGame();
});
};
<div id="game">
<h1>Computer Guessing Game</h1>
<div id="statusArea">
<p>Choose a number between 1-100 and click the button.</p>
</div>
<div id="compGuess">
</div>
<div class="buttons">
<input type="button" value="Start" class="button" id="buttonArea"/>
<input type="button" value="Lower" class="button" id="buttonLower"/>
<input type="button" value="Higher" class="button" id="buttonHigher"/>
<input type="button" value="Bingo" class="button" id="buttonBingo"/>
</div>
<div id="historyArea">
<h2>Computer Previous Guesses</h2>
<ol id="historyList">
</ol>
</div>
</div>
This version disables lower/higher buttons if we've already ruled out those possibilities, and it detects bingo automatically if there is no other option left.
//initialize global variables to keep track of stuff between functions
var min = 1;
var max = 100;
var currentGuess = -1;
function start() {
//reset everything
min = 1;
max = 100;
document.getElementById("historyList").innerHTML = "";
disable("startButton");
enable("lowerButton");
enable("higherButton");
enable("bingoButton");
//and guess
guess();
}
function guess() {
//generate a guess between min and max
currentGuess = rando(min, max);
//disable higher/lower buttons if we've ruled out those possibilities
currentGuess == min ? disable("lowerButton") : enable("lowerButton");
currentGuess == max ? disable("higherButton") : enable("higherButton");
//tell the user the guess
document.getElementById("compGuess").innerHTML = currentGuess;
}
function lower() {
//our guess was too high, so our new max is one lower than that guess
max = currentGuess - 1;
//automatically detect bingo if it's the only possible outcome left and don't bother executing the rest of the lower function
if (max == min) {
currentGuess = min;
return bingo();
}
//record that the guess was too high
document.getElementById("historyList").innerHTML += "<li>" + currentGuess + " (too high)</li>";
guess();
}
function higher() {
//our guess was too low, so our new min is one higher than that guess
min = currentGuess + 1;
//automatically detect bingo if it's the only possible outcome left and don't bother executing the rest of the higher function
if (max == min) {
currentGuess = min;
return bingo();
}
//record that the guess was too low
document.getElementById("historyList").innerHTML += "<li>" + currentGuess + " (too low)</li>";
guess();
}
function bingo() {
//record that the guess was a bingo
document.getElementById("historyList").innerHTML += "<li>" + currentGuess + " (BINGO)</li>";
//only allow start button
enable("startButton");
disable("lowerButton");
disable("higherButton");
disable("bingoButton");
//give the user a breakdown
document.getElementById("compGuess").innerHTML = "You got me in " + document.getElementsByTagName("li").length + " guesses. I was thinking " + currentGuess + ". Let's go again...";
}
//these two functions just make our code easier to read
function disable(id) {
document.getElementById(id).disabled = true;
}
function enable(id) {
document.getElementById(id).disabled = false;
}
<script src="https://randojs.com/1.0.0.js"></script>
<div id="game">
<h1>Computer Guessing Game</h1>
<div id="statusArea">
<p>Choose a number between 1-100 and click the button.</p>
</div>
<div id="compGuess"></div>
<div class="buttons">
<input type="button" value="Start" id="startButton" onclick="start();" />
<input type="button" value="Lower" id="lowerButton" onclick="lower();" disabled/>
<input type="button" value="Higher" id="higherButton" onclick="higher();" disabled/>
<input type="button" value="Bingo" id="bingoButton" onclick="bingo();" disabled/>
</div>
<div id="historyArea">
<h2>Computer Previous Guesses</h2>
<ol id="historyList"></ol>
</div>
</div>
It uses randojs.com to make the randomness easier to read, so if you use this code, make sure you have this in the head tag of your html document:
<script src="https://randojs.com/1.0.0.js"></script>
try the following ...
start.html
<!DOCTYPE html>
<html>
<head>
<script>
function StartGame()
{
aMaxValue = Number(theMaxValueText.value);
window.localStorage.setItem ("theMaxValueToGuess", aMaxValue);
aNumberToGuess = Math.floor ( Math.random() * aMaxValue + 1 );
window.localStorage.setItem ("theNumberToGuess", aNumberToGuess);
aMaxNumberOfTries = Math.floor ( Math.log2 (aMaxValue) + 1 );
window.localStorage.setItem ("theMaxNumberOfTries", aMaxNumberOfTries);
window.localStorage.setItem ("theUserTriesCount", 0);
aPrevGuessesString = "";
window.localStorage.setItem ("thePrevGuessesString", aPrevGuessesString);
document.location.href = "play.html";
}
</script>
</head>
<body>
<h1>Guess a Number</h1>
<div class="form">
<label for="theMaxValueText">Max Value to Guess:</label>
<input type="text" id="theMaxValueText">
<input type="submit" value="Play" id="ExecPlayBtn" onclick="StartGame()">
</div>
</body>
</html>
play.html
<!DOCTYPE html>
<html>
<head>
<script>
var theMaxNumberToGuess = Number ( window.localStorage.getItem ("theMaxValueToGuess") );
// let theMaxNumberOfTries = 0;
// let theNumberToGuess = 0;
// let theUserTriesCount = 0;
function getMaxNumberOfTries() {
return Number ( window.localStorage.getItem ("theMaxNumberOfTries") );
}
function getNumberToGuess() {
return Number ( window.localStorage.getItem ("theNumberToGuess") );
}
function getUserTriesCount() {
return Number ( window.localStorage.getItem ("theUserTriesCount") );
}
function incrUserTriesCount()
{
aUserTriesCount = getUserTriesCount();
++ aUserTriesCount;
window.localStorage.setItem ("theUserTriesCount", aUserTriesCount);
}
function getNumberOfTriesLeft()
{
aMaxNumberOfTries = getMaxNumberOfTries();
aUserTriesCount = getUserTriesCount();
aNumberOfTriesLeft = aMaxNumberOfTries - aUserTriesCount;
return aNumberOfTriesLeft;
}
function getPrevGuessesString() { return window.localStorage.getItem ("thePrevGuessesString"); }
function addToPrevGuessesString (aStr)
{
aPrevGuessesString = getPrevGuessesString();
aPrevGuessesString += (aStr + " ");
window.localStorage.setItem ("thePrevGuessesString", aPrevGuessesString);
}
function PageLoaded()
{
document.getElementById("theMaxNumberToGuessLabel").innerHTML = theMaxNumberToGuess;
// compute values ...
// theNumberToGuess = Math.floor ( Math.random() * theMaxNumberToGuess + 1 );
// theMaxNumberOfTries = Math.floor ( Math.log2 (theMaxNumberToGuess) + 1 );
// theUserTriesCount = 0;
DisplayGameStatus();
}
window.addEventListener ("load", PageLoaded);
function DisplayNumberOfTriesLeft()
{
aNumberOfTriesLeft = getNumberOfTriesLeft();
document.getElementById("theTriesLeftCountLabel").innerHTML = aNumberOfTriesLeft;
}
function DisplayPrevUserGuesses()
{
aPrevGuessesString = getPrevGuessesString();
document.getElementById("theUserPrevGuessesLabel").innerHTML = aPrevGuessesString;
}
function DisplayGameStatus()
{
DisplayNumberOfTriesLeft();
DisplayPrevUserGuesses();
}
function CheckUserGuess()
{
aNumberOfTriesLeft = getNumberOfTriesLeft();
if (aNumberOfTriesLeft <= 0) {
// go to the loose page
}
aNumberToGuess = getNumberToGuess();
aUserGuess = Number(theUserValueText.value);
addToPrevGuessesString ("" + aUserGuess);
if (aUserGuess < aNumberToGuess) {
// retry
document.getElementById("theUserHintMessageLabel").innerHTML =
"retry, the number to guess is > higher"
} else if (aUserGuess > aNumberToGuess) {
// retry
document.getElementById("theUserHintMessageLabel").innerHTML =
"retry, the number to guess is < lower"
} else {
// the user wins !!
document.getElementById("theUserHintMessageLabel").innerHTML =
"you win !! " + aUserGuess + " == " + aNumberToGuess + ""
alert ("you win !! " + aUserGuess + " == " + aNumberToGuess + "");
// go to the win page ...
document.location.href = "youwin.html";
}
// ++ theUserTriesCount;
incrUserTriesCount();
aNumberOfTriesLeft = getNumberOfTriesLeft();
if (aNumberOfTriesLeft <= 0) {
// go to the loose page
document.location.href = "youloose.html";
}
DisplayGameStatus();
}
</script>
</head>
<body>
<div>
<h1>
<label>Guess a Number in the Range ( 0 .. </label>
<label id="theMaxNumberToGuessLabel"></label>
<label>)</label>
</h1>
</div>
<div>
<label>you have </label>
<label id="theTriesLeftCountLabel"></label>
<label> tries left</label>
</div>
<p></p>
<div>
<label for="theUserValueText">Enter your Guess: </label>
<input type="text" id="theUserValueText">
<input type="submit" value="Guess" id="ExecUserGuessBtn" onclick="CheckUserGuess()">
</div>
<p></p>
<div>
<label>Prev Guesses: </label>
<label id="theUserPrevGuessesLabel"></label>
</div>
<p></p>
<div>
<label id="theUserHintMessageLabel"></label>
</div>
</body>
</html>
youloose.html
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div>
<h1>
<label>Sorry, You Loose !!</label>
<label>go to </label> Start
</h1>
</div>
</body>
</html>
youwin.html
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div>
<h1>
<label>Congrats, You Win !!</label>
<label>go to </label> Start
</h1>
</div>
</body>
</html>
that's all folks ...

How to create program to Calculate Resistors in Series using javascript?

i'm newbie in here. i want to create program to calculate resistors in series using HTML & javascript.
I have tried to make it with code below. there are 2 functions.
first, to create input fields automatically based on how many resistors you wants to input.
image 1.( i have created this function ).
and the second function is sum the total values of the input fields that have been created.
image 2. ( i'm not yet create this function )
how to create this ? could you complate the second function ? or any have other alternative ?
JAVASCRIPT :
< script >
function display() {
var y = document.getElementById("form1").angka1.value;
var x;
for (x = 1; x <= y; x++) {
var a = document.getElementById("container");
var newInput = document.createElement('div');
newInput.innerHTML = 'R ' + x + ': <input type="text" id="r_' + x + '" name="r_' + x + '"/>';
a.appendChild(newInput);
}
}
function count() {
//this function not yet created
}
</script>
HTML:
<form id="form1" name="form1" onsubmit="return false">
<label for="number">Input Qty of Resistors </label>
<input type="number" name="angka1">
<input type="submit" value="Display Input" onclick="display()">
<div id="container"></div>
<input type="submit" value="Count" onclick="count()">
</form>
Here is the working demo of what you want to achieve. Click Here
Note that here in demo I have use JQuery so please include jquery file.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="number">Input Qty of Resistors </label>
<input type="number" id="angka1" />
<input type="button" value="Display Input" onclick="display()" />
<div id="container"></div>
<input type="button" value="Count" onclick="count()" />
<label id="totalCount"></label>
function display() {
document.getElementById("container").innerHTML = "";
var y = document.getElementById("angka1").value;
var x;
for (x = 1; x <= y; x++) {
var a = document.getElementById("container");
var newInput = document.createElement('div');
newInput.innerHTML = 'R ' + x + ': <input type="number" id="r_' + x + '" name="r_' + x + '" />';
a.appendChild(newInput);
}
}
function count() {
console.log("Count function is called.");
var total = 0;
$("#container input").each(function () {
total += Number($(this).val().trim());
console.log(total);
});
document.getElementById("totalCount").innerHTML = total;
}
Hope that will work for you.

How to only add from one input field?

I want to be able to add just the article that you click on and not each. What can I use instead of .each for this to work?
These are the functions:
calculating sum total price:
var quantity, price, sum = 0;
function calculatePrice() {
//loop through product "blocks"
$('.articel').each(function() {
price = $(this).children('.price').val();
quantity = $(this).children('.quantity').val();
//Add price to sum if number
if (!isNaN(price) && !isNaN(quantity)) {
sum += price * quantity;
}
});
//Update Price
$('#totalprice').html('<h4>Total price: ' + sum + '$</h4>');
}
Add to shopping cart:
$(document).ready(function(){
$(".articel input[type='button']").click(function(){ //sätter klickfunktion på klassen artikels knapp
var price = $(this).siblings('.price').attr("value");
var quantity = $(this).siblings('.quantity').attr("value");
if(quantity % 1 != 0)
{
alert("You must add a whole number");
}
else if(quantity <= 0)
{
alert("You must att a whole number");
}
else
{
var name = $(this).siblings("input[name='prodname']").attr("value");
var ul = document.getElementById("buylist");
var totalprice = quantity * price;
var prod = name + " x " + quantity + "= " + totalprice + "$";
var el = document.createElement("li"); //skapar ett nytt element
el.innerHTML = prod; //variabeln prod läggs IN i nya elementet
ul.appendChild(el); //sätt IN el i ul
calculatePrice();
}
});
});
And this is my form:
<div id="moviescat_view" style="display:none">
<h2>Movies</h2>
<br><button onclick="backButton(moviescat_view);" class="btn">Go back</button><br>
<img border="0" id="img/hoverover.jpg" src="img/1_1.jpg" alt="The walking dead" onmouseover="mouseOverImage(this)" onmouseout="mouseOutImage(this)" onClick="addtoCart()">
</form>
<br><button onclick="showInfo(set1);" class="btn">Show info</button><br>
<h4>The walking dead</h4>
<p>Price : 30$</p>
<div id="set1" style="display:none">
<p>A serie about zombies</p>
</div>
<form class="articel">
Quantity: <input type="number" style="width:30px;" class="quantity"><br>
Add to cart: <input type="button" class="btn">
<input type="hidden" value="30" name="price" class="price">
<input type="hidden" value="The walking dead" name="prodname">
</form>
</div>
You should pass attributes to
calculatePrice();
Namely price and quantity, and then do the exact same within the function :
function calculatePrice(price, quantity) {
//Add price to sum if number
if (!isNaN(price) && !isNaN(quantity)) {
sum += price * quantity;
}
$('#totalprice').html('<h4>Total price: ' + sum + '$</h4>');
}
Like Jon said... pass in the attributes or objects that you need.
$(document).ready(function(){
$(".articel input[type='button']").click(function(){
//...
calculatePrice($(this)); //$(this) would be the clicked DOM element
});
});
function calculatePrice(element) {
price = element.children('.price').val();
quantity = element.children('.quantity').val();
//Add price to sum if number
if (!isNaN(price) && !isNaN(quantity)) {
sum += price * quantity;
}
//Update Price
$('#totalprice').html('<h4>Total price: ' + sum + '$</h4>');
}

JavaScript - numeric data vs NaN

I'm sure I'm contravening some deep dark law of javascript, but I'm not really a JS developer and this is driving me mad. This function is called on an orderform to read the quantity and price of items, row by row, and then provide the subtotal, delivery and total.
The problem is with line 10 - it keeps "forgetting" that the variable data throughout is numeric (floating point) and so returns lots of NaN. How can I force the variables throughout this function to behave as numbers rather than strings?
EDIT
Here's the revised code based on feedback so far (thank you!). It's still not working ;)
<script type="text/javascript">
function subTotal(rows) {
var i, subTotal, lineTotal, orderShip, orderTotal;
for (i = 1; i <= rows; ++i) {
//Grab values from form
var quantity = parseFloat($('#quantity' + i).val());
var uPrice = parseFloat($('#uPrice' + i).val());
//Error checking
alert('quantity = ' + quantity +' and uPrice = ' + uPrice);
if (isNaN(quantity)) alert('quantity = NaN');
if (isNaN(uPrice)) alert('uPrice = NaN');
if ((quantity == '') || (uPrice == '')) {
} else {
lineTotal = quantity * uPrice;
alert('lineTotal = ' + lineTotal);
subTotal += lineTotal;
alert('subTotal = ' + subTotal);
}
//If we've maxed out the number of rows, then subTotal should be calculated - push back to form.
if (i == rows) {
$('#orderSubTotal').val(subTotal );
orderShip = subTotal * 0.25;
$('#orderShip').val(orderShip.toFixed(2));
orderTotal = subTotal + orderShip;
$('#orderTotal').val(orderTotal.toFixed(2));
}
}
}
</script>
<form>
<table>
<tr>
<td><input type="text" id="item1" name="item1" value="Some description" readonly="readonly" /></td>
<td><input type="text" id="quantity1" name="quantity1" value="25" onchange="javascript:subTotal('2')" /></td>
<td><input type="text" id="uPrice1" name="uPrice1" value="1.50" readonly="readonly" /></td>
</tr>
<tr>
<td><input type="text" id="item2" name="item2" value="Some description" readonly="readonly" /></td>
<td><input type="text" id="quantity2" name="quantity2" value="25" onchange="javascript:subTotal('2')" /></td>
<td><input type="text" id="uPrice2" name="uPrice2" value="2.75" readonly="readonly" /></td>
</tr>
<tr>
<td colspan="3">
SubTotal
<input type="text" id="orderSubTotal" name="orderSubTotal" readonly="readonly" style="text-align: right" value="0.00" />
<br />Shipping
<input type="text" id="orderShip" name="orderShip" readonly="readonly" style="text-align: right" value="0.00" />
<br />Total
<input type="text" id="orderTotal" name="orderTotal" readonly="readonly" style="text-align: right" value="0.00" />
</td>
</tr>
</table>
</form>
I think the real problem is in your loop: You're looping from 0 to rows inclusive. So if you pass in 10 for rows, you'll be looping 11 times, starting with 0 and continuing through (including) 10. I suspect that's your real problem. If you don't have a quantity0 element, or (assuming rows is 10) you don't have a quantity10 element, then $("#quantity" + i).val() will return undefined, which converts to NaN when you convert it (implicitly or explicitly). (And the same for uPrice0 / uPrice10.) And of course, once you have NaN, any mathematical operation using it results in NaN.
In terms of your question about how to ensure they don't change, basically, convert them to numbers early. You're currently using quantity and uPrice without converting them, which means initially they're strings. Now, JavaScript is pretty smart about converting them for you, but sometimes you want to be explicit.
Separately: Where does x come from?
You haven't shown any data to work with, but just speculatively:
function subTotal(rows) {
var i, subTotal, lineTotal, quantity, uPrice, orderShip, orderTotal;
subTotal = 0;
for (i = 0; i < rows; ++i) {
// OR
//for (i = 1; i <= rows; ++i) {
quantity = $('#quantity' + i).val();
uPrice = $('#uPrice' + i).val();
if ((quantity == '') || (uPrice == '')) {
} else {
quantity = parseFloat(quantity);
uPrice = parseFloat(uPrice);
// Might consider checking isNaN(quantity) and isNan(uPrice) here
lineTotal = quantity * uPrice;
subTotal += lineTotal;
alert('subtotal = ' + subTotal);
}
if (i == x) { // Where does `x` come from?
$('#orderSubTotal').val(subTotal );
orderShip = subTotal * 0.25;
$('#orderShip').val(orderShip.toFixed(2));
orderTotal = subTotal + orderShip;
$('#orderTotal').val(orderTotal.toFixed(2));
}
}
}
The problem is that you're performing a mathematical calculation on the fields before using parseFloat:
var lineTotal = quantity * uPrice; // <-- result is most likely NaN here
subTotal = parseFloat(subTotal ) + parseFloat(lineTotal);
Perform your parsing at the point you get the values to make life a little easier:
var quantity = parseFloat($('#quantity' + i).val());
var uPrice = parseFloat($('#uPrice' + i).val());
Then change the subTotal = line to this:
subTotal += lineTotal;
Another possible issue is if the result of $('#uPrice' + i).val() doesn't start with a parseable float — if it starts with a currency symbol, e.g. £ or $, for instance — parseFloat will always return NaN for that field. You can work around it using $('#uPrice' + i).val().slice(1).
Do some error checking:
function subTotal(rows) {
var subTotal = 0;
while (var i=0; i < rows; i++) {
// convert as soon as you get the values
var quantity = parseFloat($('#quantity' + i).val());
var uPrice = parseFloat($('#uPrice' + i).val());
if (isNaN(quantity) || isNaN(uPrice)) { // error checking
alert("Invalid values on row " + i);
continue;
}
var lineTotal = quantity * uPrice;
subTotal += lineTotal;
alert('subtotal = ' + subTotal);
if (i == x) {
$('#orderSubTotal').val(subTotal );
var orderShip = subTotal * 0.25;
$('#orderShip').val(orderShip.toFixed(2));
var orderTotal = subTotal + orderShip;
$('#orderTotal').val(orderTotal.toFixed(2));
}
}
}
You're probably running into an index problem at some point, getting a NaN from one of the (non-existing fields), adding it to subTotal which makes it a NaN instantly.
You better convert the value before doing any mathematical operation. So the code should be:
var numQuanitity = parseFloat(quantity);
var numPrice = parseFloat(uPrice);
if (isNaN(numQuanitity) || isNaN(numPrice)) {
//you can alert or ignore
}
else {
var lineTotal = numQuanitity * numPrice;
subTotal += lineTotal;
alert('subtotal = ' + subTotal);
}
...

Categories