Why is the multiplication happening only after refresh? - javascript

I have a calculator. This has a form which, for certain calculations, works only when I refresh the page. Addition works but multiplication only works after refresh. Why is that?
I don't want to use JQuery!
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Card Form</title>
<link href="styles/cardform.css" rel="stylesheet" type="text/css" />
</head>
<body onload='hideTotal()'>
<div id="wrap">
<form action="" id="cardform" onsubmit="return false;">
<div>
<div class="cont_order">
<fieldset>
<legend>Check Quotes</legend>
<label>Size Of the Card</label>
<label>Width in cm: </label> <input type="text" id="width" />
<label>Height in cm: </label> <input type="text" id="height" />
<br/>
<br/>
<label class='radiolabel'><input type="radio" name="selectedcard1" value="Round13" onclick=""/>Standard</label>
<label class='radiolabel'><input type="radio" name="selectedcard1" value="Round14" onclick="" />Toughened</label><br/>
<br/>
<label>Card: </label>
<label class='radiolabel'><input type="radio" name="selectedcard2" value="Round17" onclick=""/>Clear</label>
<label class='radiolabel'><input type="radio" name="selectedcard2" value="Round18" onclick="" />Frosted</label>
<label class='radiolabel'><input type="radio" name="selectedcard2" value="Round19" onclick="" />Leaded</label>
<label class='radiolabel'><input type="radio" name="selectedcard2" value="Round20" onclick="" />White Bar</label>
<br/>
<label>Frame: </label>
<label class='radiolabel'><input type="radio" name="selectedcard3" value="Round21" onclick=""/>uPVC</label>
<label class='radiolabel'><input type="radio" name="selectedcard3" value="Round22" onclick="" />Metal</label>
<label class='radiolabel'><input type="radio" name="selectedcard3" value="Round23" onclick=""/>Wood</label>
<br/>
<input type="submit" value="Calculate" onClick="calculateTotal()" />
<INPUT TYPE="reset" VALUE="RESET" onClick="resetIt()" />
<div id="totalPrice"></div>
</fieldset>
</div>
</div>
</form>
</div>
<!--End of wrap-->
</body>
<script>
var size1 = document.getElementById("width").value;
var size2 = document.getElementById("height").value;
var total_size = ((size1 * size2) / 10000);
var card_prices = new Array();
card_prices["Round13"] = (total_size * 67);
card_prices["Round14"] = (total_size * 87);
card_prices["Round17"] = (total_size * 0.05);
card_prices["Round18"] = (total_size * 0.65);
card_prices["Round19"] = (total_size * 0.85);
card_prices["Round20"] = (total_size * 0.95);
function getCardSizePrice2() {
var cardSizePrice = 0;
//Get a reference to the form id="cardform"
var theForm = document.forms["cardform"];
//Get a reference to the card the user Chooses name=selectedCard":
var selectedCard1 = theForm.elements["selectedcard1"];
//Here since there are 4 radio buttons selectedCard.length = 4
//We loop through each radio buttons
for (var i = 0; i < selectedCard1.length; i++) {
//if the radio button is checked
if (selectedCard1[i].checked) {
//we set cardSizePrice to the value of the selected radio button
//i.e. if the user choose the 8" card we set it to 25
//by using the card_prices array
//We get the selected Items value
//For example card_prices["Round8".value]"
cardSizePrice = card_prices[selectedCard1[i].value];
//If we get a match then we break out of this loop
//No reason to continue if we get a match
break;
}
}
//We return the cardSizePrice
return cardSizePrice;
}
function getCardSizePrice3() {
var cardSizePrice = 0;
//Get a reference to the form id="cardform"
var theForm = document.forms["cardform"];
//Get a reference to the card the user Chooses name=selectedCard":
var selectedCard = theForm.elements["selectedcard2"];
//Here since there are 4 radio buttons selectedCard.length = 4
//We loop through each radio buttons
for (var i = 0; i < selectedCard.length; i++) {
//if the radio button is checked
if (selectedCard[i].checked) {
cardSizePrice = card_prices[selectedCard[i].value];
break;
}
}
return cardSizePrice;
}
function getCardSizePrice4() {
card_prices["Round21"] = 2;
card_prices["Round22"] = 5;
card_prices["Round23"] = 5;
var cardSizePrice = 0;
//Get a reference to the form id="cardform"
var theForm = document.forms["cardform"];
//Get a reference to the card the user Chooses name=selectedCard":
var selectedCard = theForm.elements["selectedcard3"];
//Here since there are 4 radio buttons selectedCard.length = 4
//We loop through each radio buttons
for (var i = 0; i < selectedCard.length; i++) {
//if the radio button is checked
if (selectedCard[i].checked) {
cardSizePrice = card_prices[selectedCard[i].value];
break;
}
}
return cardSizePrice;
}
var divobj = document.getElementById('totalPrice');
function calculateTotal() {
//Here we get the total price by calling our function
//Each function returns a number so by calling them we add the values they return together
var cardPrice = getCardSizePrice2() + getCardSizePrice3() + getCardSizePrice4();
//display the result
divobj.style.display = 'block';
divobj.innerHTML = "Total Price For the Card: £" + " " + cardPrice;
displaytotal(divobj);
}
function displaytotal() {
}
function hideTotal() {
var divobj = document.getElementById('totalPrice');
divobj.style.display = 'none';
}
function resetIt() {
var divobj = document.getElementById('totalPrice');
divobj.style.display = 'none';
}
</script>
</html>

I understand you've found your issue (I believe it had to do with the fact that you had your code set up with a submit button and you had totals being calculated as soon as the page load event triggered, rather than upon a click of the total button).
But, beyond that, you may still want to look at this answer very carefully as the code you have is just awful in many regards:
HTML:
Your HTML was not being used correctly. You were not using <label>
or <fieldset> elements properly.
Since you were really just needing a calculator that doesn't actually
submit the data anywhere, you shouldn't have a submit button.
You were using inline HTML event handlers (onsubmit, onclick,
etc.), which should not be used because:
They create "spaghetti code" that is difficult to read and leads to
duplication of code.
They cause global event handling wrapper functions to be implicitly
created around the attribute values that you supply that make the
binding of the this object not work as expected.
They don't follow W3C Standards for Event Handling
JavaScript:
You were setting up variables for the HTML elements you were going to
use inside your various functions, which meant that every time the
function runs, it has to re-scan the document all over again to find
the element.
You were using an array when an Object was more appropriate.
You had essentially the same function written 3 times instead of just
having it once and passing an argument to it that can change as you
need it to.
Here is a cleaned up version that follows best-practices, semantics and doesn't repeat itself. See the inline comments for specifics.
window.addEventListener("DOMContentLoaded", function(){
// Get references to DOM elements that we'll need access to just once. Don't set variables
// up to store their values at first. Set the variable to the elmement. That way, you can
// go back to the element as often as you need to in order to get any property value you
// like, without having to re-scan the document for it all over again:
var size1 = document.getElementById("width");
var size2 = document.getElementById("height");
var divObj = document.getElementById('totalPrice');
var theForm = document.getElementById("cardform");
var selectedCard1 = theForm.querySelectorAll("[name=selectedcard1]");
var selectedCard2 = theForm.querySelectorAll("[name=selectedcard2]");
var selectedCard3 = theForm.querySelectorAll("[name=selectedcard3]");
var calc = document.querySelector("input[type=button]");
var res = document.querySelector("input[type=reset]");
// Set up event handlers for various DOM elements:
calc.addEventListener("click", calculateTotal);
res.addEventListener("click", reset);
// Create a storage mechanism that holds "keys" and associated "values"
// Arrays can only do this with sequential numeric indexes. Objects, do it
// with string property names.
var card_prices = {};
// No reason to have 3 functions that all do basically the same thing but only
// to different objects. Just have one function that accepts a reference to the
// radiobuttons it needs to work with
function getCardSizePrice(cards){
var cardSizePrice = 0;
// Loop through each radio button in the passed in group
for(var i = 0; i < cards.length; i++) {
//if the radio button is checked
if(cards[i].checked) {
// Lookup the value of the selected radio button in our object and get the
// associate property value
cardSizePrice = card_prices[cards[i].value];
// No reason to continue if we get a match
break;
}
}
// We return the cardSizePrice
return cardSizePrice;
}
function calculateTotal() {
// You didn't have the following code in this funciton, so it was running immediately
// when the page loaded.
// Remember, values that you take out of form elements are strings!
// If you want to treat them as numbers, you should explicitly convert them
// to numbers first:
var s1 = parseFloat(size1.value);
var s2 = parseFloat(size2.value);
var total_size = (s1 * s2) / 10000;
// Set all the property values
card_prices["Round13"] = total_size * 67,
card_prices["Round14"] = total_size * 87,
card_prices["Round17"] = total_size * .05,
card_prices["Round18"] = total_size * .65,
card_prices["Round19"] = total_size * .85,
card_prices["Round20"] = total_size * .95,
card_prices["Round21"] = 2;
card_prices["Round22"] = 5;
card_prices["Round23"] = 5;
// Here we get the total price by calling our function
// Each function returns a number so by calling them we add the values they return together
var cardPrice = getCardSizePrice(selectedCard1) +
getCardSizePrice(selectedCard2) +
getCardSizePrice(selectedCard3);
displayTotal(cardPrice);
}
function displayTotal(price) {
// display the result
divObj.classList.remove("hidden");
divObj.innerHTML = "Total Price For the Card: £" + " " + price.toFixed(2);
}
function reset(){
divObj.innerHTML = "";
}
});
#totalPrice { background-color:#ff0; } // Default style for element
#panel { margin-top: 1em;}
fieldset { margin-bottom:1em; }
<body>
<div id="wrap">
<form action="#" id="cardform">
<div class="cont_order">
<h1>Check Quotes</h1>
<!-- Fieldsets are for logical grouping of form elements. While they do have a
visual component to them, they are primarially for accessibility for
visually impaired. -->
<fieldset>
<legend>Size Of the Card</legend>
<!-- Labels associate with form elements via the "for" attribute and the target
element's "id" attribute. They aren't just for displaying random text.
They are a key aspect of designing for accessibility. You can click/touch the
label and activate the associated form element. -->
<label for="width">Width in cm:</label> <input type="text" id="width">
<label for="height">Height in cm:</label> <input type="text" id="height">
<br><br>
<input type="radio" name="selectedcard1" id="selectedcard1a" value="Round13">
<label for="selectedcard1a" class='radiolabel'>Standard</label>
<input type="radio" name="selectedcard1" id="selectedcard1b" value="Round14">
<label for="selectedcard1b" class='radiolabel'>Toughened</label><br>
</fieldset>
<fieldset>
<legend>Card</legend>
<input type="radio" name="selectedcard2" id="selectedcard2a" value="Round17">
<label for="selectedcard2a" class='radiolabel'>Clear</label>
<input type="radio" name="selectedcard2" id="selectedcard2b" value="Round18">
<label for="selectedcard2b" class='radiolabel'>Frosted</label>
<input type="radio" name="selectedcard2" id="selectedcard2c" value="Round19">
<label for="selectedcard2c" class='radiolabel'>Leaded</label>
<input type="radio" name="selectedcard2" id="selectedcard2d" value="Round20">
<label for="selectedcard2d" class='radiolabel'>White Bar</label>
</fieldset>
<fieldset>
<legend>Frame</legend>
<input type="radio" name="selectedcard3" id="selectedcard3a" value="Round21">
<label for="selectedcard3a" class='radiolabel'>uPVC</label>
<input type="radio" name="selectedcard3" id="selectedcard3b" value="Round22">
<label for="selectedcard3b" class='radiolabel'>Metal</label>
<input type="radio" name="selectedcard3" id="selectedcard3c" value="Round23">
<label for="selectedcard3c" class='radiolabel'>Wood</label>
</fieldset>
<div id="panel">
<input type="button" value="Calculate">
<input type="reset" value="Reset">
<div id="totalPrice"></div>
</div>
</div>
</form>
</div>

Related

How can I change my array of values if some other value changes in javascript/html?

Hi I'm trying to make a webpage to calculate cake prices using this example: http://javascript-coder.com/javascript-form/javascript-calculator-script.phtml
All the code is also available here.
I want to make the filling price more expensive if their cake is bigger, how can I change this?
So if a user selects a bigger cake I want to increase the price of the filling. Not just with a certain % but with a different amount of $ depending on the size and filling, I would prefer to change the "filling_prices" array depending on the size of the cake.
I tried this:
if (cake_prices[selectedCake[i].value] == 20){
var filling_prices= new Array();
filling_prices["None"]=0;
filling_prices["Lemon"]=5;
filling_prices["Custard"]=5;
filling_prices["Fudge"]=7;
filling_prices["Mocha"]=8;
filling_prices["Raspberry"]=10;
filling_prices["Pineapple"]=5;
filling_prices["Dobash"]=9;
filling_prices["Mint"]=5;
filling_prices["Cherry"]=5;
filling_prices["Apricot"]=8;
filling_prices["Buttercream"]=7;
filling_prices["Chocolate Mousse"]=12;
}
else{
var filling_prices= new Array();
filling_prices["None"]=0;
filling_prices["Lemon"]=10;
filling_prices["Custard"]=10;
filling_prices["Fudge"]=14;
filling_prices["Mocha"]=16;
filling_prices["Raspberry"]=20;
filling_prices["Pineapple"]=10;
filling_prices["Dobash"]=18;
filling_prices["Mint"]=10;
filling_prices["Cherry"]=10;
filling_prices["Apricot"]=16;
filling_prices["Buttercream"]=14;
filling_prices["Chocolate Mousse"]=24;
}
This doesn't seem to work, how could I make this work? I'm sorry if this is kind of a stupid question but I'm just starting out.
HTML code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<title>Cake Form</title>
<script type="text/javascript" src="js/formcalculations.js"></script>
<link href="styles/cakeform.css" rel="stylesheet" type="text/css" />
</head>
<body onload='hideTotal()'>
<div id="wrap">
<form action="" id="cakeform" onsubmit="return false;">
<div>
<div class="cont_order">
<fieldset>
<legend>Make your cake!</legend>
<label >Size Of the Cake</label>
<label class='radiolabel'><input type="radio" name="selectedcake" value="Round6" onclick="calculateTotal()" />Round cake 6" - serves 8 people ($20)</label><br/>
<label class='radiolabel'><input type="radio" name="selectedcake" value="Round8" onclick="calculateTotal()" />Round cake 8" - serves 12 people ($25)</label><br/>
<label class='radiolabel'><input type="radio" name="selectedcake" value="Round10" onclick="calculateTotal()" />Round cake 10" - serves 16 people($35)</label><br/>
<label class='radiolabel'><input type="radio" name="selectedcake" value="Round12" onclick="calculateTotal()" />Round cake 12" - serves 30 people($75)</label><br/>
<br/>
<label >Filling</label>
<select id="filling" name='filling' onchange="calculateTotal()">
<option value="None">Select Filling</option>
<option value="Lemon">Lemon($5)</option>
<option value="Custard">Custard($5)</option>
<option value="Fudge">Fudge($7)</option>
<option value="Mocha">Mocha($8)</option>
<option value="Raspberry">Raspberry($10)</option>
<option value="Pineapple">Pineapple($5)</option>
<option value="Dobash">Dobash($9)</option>
<option value="Mint">Mint($5)</option>
<option value="Cherry">Cherry($5)</option>
<option value="Apricot">Apricot($8)</option>
<option value="Buttercream">Buttercream($7)</option>
<option value="Chocolate Mousse">Chocolate Mousse($12)</option>
</select>
<br/>
<p>
<label for='includecandles' class="inlinelabel">Include Candles($5)</label>
<input type="checkbox" id="includecandles" name='includecandles' onclick="calculateTotal()" />
</p>
<p>
<label class="inlinelabel" for='includeinscription'>Include Inscription($20)</label>
<input type="checkbox" id="includeinscription" name="includeinscription" onclick="calculateTotal()" />
<input type="text" id="theinscription" name="theinscription" value="Enter Inscription" />
</p>
<div id="totalPrice"></div>
</fieldset>
</div>
<div class="cont_details">
<fieldset>
<legend>Contact Details</legend>
<label for='name'>Name</label>
<input type="text" id="name" name='name' />
<br/>
<label for='address'>Address</label>
<input type="text" id="address" name='address' />
<br/>
<label for='phonenumber'>Phone Number</label>
<input type="text" id="phonenumber" name='phonenumber'/>
<br/>
</fieldset>
</div>
<input type='submit' id='submit' value='Submit' onclick="calculateTotal()" />
</div>
</form>
</div><!--End of wrap-->
</body>
</html>
I changed
if (cake_prices[selectedCake[i].value] == 20){
to
if (getCakeSizePrice() == 20){
in the javascript code, but it doesn't seem to work
Javascript code:
/*
This source is shared under the terms of LGPL 3
www.gnu.org/licenses/lgpl.html
You are free to use the code in Commercial or non-commercial projects
*/
//Set up an associative array
//The keys represent the size of the cake
//The values represent the cost of the cake i.e A 10" cake cost's $35
var cake_prices = new Array();
cake_prices["Round6"]=20;
cake_prices["Round8"]=25;
cake_prices["Round10"]=35;
cake_prices["Round12"]=75;
//Set up an associative array
//The keys represent the filling type
//The value represents the cost of the filling i.e. Lemon filling is $5,Dobash filling is $9
//We use this this array when the user selects a filling from the form
// getCakeSizePrice() finds the price based on the size of the cake.
// Here, we need to take user's the selection from radio button selection
function getCakeSizePrice()
{
var cakeSizePrice=0;
//Get a reference to the form id="cakeform"
var theForm = document.forms["cakeform"];
//Get a reference to the cake the user Chooses name=selectedCake":
var selectedCake = theForm.elements["selectedcake"];
//Here since there are 4 radio buttons selectedCake.length = 4
//We loop through each radio buttons
for(var i = 0; i < selectedCake.length; i++)
{
//if the radio button is checked
if(selectedCake[i].checked)
{
//we set cakeSizePrice to the value of the selected radio button
//i.e. if the user choose the 8" cake we set it to 25
//by using the cake_prices array
//We get the selected Items value
//For example cake_prices["Round8".value]"
cakeSizePrice = cake_prices[selectedCake[i].value];
//If we get a match then we break out of this loop
//No reason to continue if we get a match
break;
}
}
//We return the cakeSizePrice
return cakeSizePrice;
}
// var filling_prices= new Array();
// filling_prices["None"]=0;
// filling_prices["Lemon"]=5;
// filling_prices["Custard"]=5;
// filling_prices["Fudge"]=7;
// filling_prices["Mocha"]=8;
// filling_prices["Raspberry"]=10;
// filling_prices["Pineapple"]=5;
// filling_prices["Dobash"]=9;
// filling_prices["Mint"]=5;
// filling_prices["Cherry"]=5;
// filling_prices["Apricot"]=8;
// filling_prices["Buttercream"]=7;
// filling_prices["Chocolate Mousse"]=12;
if (getCakeSizePrice() == 20){
var filling_prices= new Array();
filling_prices["None"]=0;
filling_prices["Lemon"]=5;
filling_prices["Custard"]=5;
filling_prices["Fudge"]=7;
filling_prices["Mocha"]=8;
filling_prices["Raspberry"]=10;
filling_prices["Pineapple"]=5;
filling_prices["Dobash"]=9;
filling_prices["Mint"]=5;
filling_prices["Cherry"]=5;
filling_prices["Apricot"]=8;
filling_prices["Buttercream"]=7;
filling_prices["Chocolate Mousse"]=12;
}
else{
var filling_prices= new Array();
filling_prices["None"]=0;
filling_prices["Lemon"]=10;
filling_prices["Custard"]=10;
filling_prices["Fudge"]=14;
filling_prices["Mocha"]=16;
filling_prices["Raspberry"]=20;
filling_prices["Pineapple"]=10;
filling_prices["Dobash"]=18;
filling_prices["Mint"]=10;
filling_prices["Cherry"]=10;
filling_prices["Apricot"]=16;
filling_prices["Buttercream"]=14;
filling_prices["Chocolate Mousse"]=24;
}
//This function finds the filling price based on the
//drop down selection
function getFillingPrice()
{
var cakeFillingPrice=0;
//Get a reference to the form id="cakeform"
var theForm = document.forms["cakeform"];
//Get a reference to the select id="filling"
var selectedFilling = theForm.elements["filling"];
//set cakeFilling Price equal to value user chose
//For example filling_prices["Lemon".value] would be equal to 5
cakeFillingPrice = filling_prices[selectedFilling.value];
//finally we return cakeFillingPrice
return cakeFillingPrice;
}
//candlesPrice() finds the candles price based on a check box selection
function candlesPrice()
{
var candlePrice=0;
//Get a reference to the form id="cakeform"
var theForm = document.forms["cakeform"];
//Get a reference to the checkbox id="includecandles"
var includeCandles = theForm.elements["includecandles"];
//If they checked the box set candlePrice to 5
if(includeCandles.checked==true)
{
candlePrice=5;
}
//finally we return the candlePrice
return candlePrice;
}
function insciptionPrice()
{
//This local variable will be used to decide whether or not to charge for the inscription
//If the user checked the box this value will be 20
//otherwise it will remain at 0
var inscriptionPrice=0;
//Get a refernce to the form id="cakeform"
var theForm = document.forms["cakeform"];
//Get a reference to the checkbox id="includeinscription"
var includeInscription = theForm.elements["includeinscription"];
//If they checked the box set inscriptionPrice to 20
if(includeInscription.checked==true){
inscriptionPrice=20;
}
//finally we return the inscriptionPrice
return inscriptionPrice;
}
function calculateTotal()
{
//Here we get the total price by calling our function
//Each function returns a number so by calling them we add the values they return together
var cakePrice = getCakeSizePrice() + getFillingPrice() + candlesPrice() + insciptionPrice();
//display the result
var divobj = document.getElementById('totalPrice');
divobj.style.display='block';
divobj.innerHTML = "Total Price For the Cake $"+cakePrice;
}
function hideTotal()
{
var divobj = document.getElementById('totalPrice');
divobj.style.display='none';
}
You have to set filling_prices when you change cake size. What happens now is that getCakeSizePrice() returns 0 at the start of your program. So the filling_prices will be set to the cheaper prices and will never change.
Here is a working codepen: https://codepen.io/martitv/pen/WYYdNq?editors=0010
Due to how you program is structured, this should be done in calculateTotal()
Create a function like this:
var filling_prices;
function setFillingPrices(cakeSizePrice) {
if (cakeSizePrice == 20){
filling_prices= new Array();
filling_prices["None"]=0;
filling_prices["Lemon"]=5;
filling_prices["Custard"]=5;
filling_prices["Fudge"]=7;
filling_prices["Mocha"]=8;
filling_prices["Raspberry"]=10;
filling_prices["Pineapple"]=5;
filling_prices["Dobash"]=9;
filling_prices["Mint"]=5;
filling_prices["Cherry"]=5;
filling_prices["Apricot"]=8;
filling_prices["Buttercream"]=7;
filling_prices["Chocolate Mousse"]=12;
}
else{
filling_prices= new Array();
filling_prices["None"]=0;
filling_prices["Lemon"]=10;
filling_prices["Custard"]=10;
filling_prices["Fudge"]=14;
filling_prices["Mocha"]=16;
filling_prices["Raspberry"]=20;
filling_prices["Pineapple"]=10;
filling_prices["Dobash"]=18;
filling_prices["Mint"]=10;
filling_prices["Cherry"]=10;
filling_prices["Apricot"]=16;
filling_prices["Buttercream"]=14;
filling_prices["Chocolate Mousse"]=24;
}
setFillingPriceText();
}
then call it in your calculateTotal() like this:
function calculateTotal()
{
//Here we get the total price by calling our function
//Each function returns a number so by calling them we add the values they return together
var cakeSizePrice = getCakeSizePrice();
var fillingPrice = getFillingPrice(cakeSizePrice);
var candlesPrice = getCandlesPrice();
var insciptionPrice = getInsciptionPrice();
var cakePrice = cakeSizePrice + fillingPrice + candlesPrice + insciptionPrice;
//display the result
var divobj = document.getElementById('totalPrice');
divobj.style.display='block';
divobj.innerHTML = "Total Price For the Cake $"+cakePrice;
}
I also created a function called setFillingPriceText() that updates the options labels/text with the new price when selecting a new cakesize.
It looks like this:
function setFillingPriceText() {
var theForm = document.forms["cakeform"];
//Get a reference to the select id="filling"
var fillingElements = theForm.elements["filling"].options;
var fillings = Object.keys(filling_prices);
for(var i = 1; i < fillingElements.length; i++){
fillingElements[i].text = fillings[i] + "(" + filling_prices[fillings[i]] + "$)";
}
}

value from a JavaScript form

I'm building a form that allows to calculate the Bishop Score: https://jsfiddle.net/molecoder/1oqxsw81/ .
The user is allowed to select between 4 options and each of these options (0 cm, 1-2 cm, ...) have an associated value.
Here is the HTML code for the form:
<form action="" id="bishopform" onsubmit="return true;">
<div>
<fieldset>
<legend>Bishop score</legend>
<p>(modify one field to see the score)</p>
<div id="bishopScore"></div>
<label><b>Cervical Dilatation</b></label><br/>
<label class='radiolabel'><input type="radio" name="selectedcervicaldilatation" value="cerdi1" onclick="calculateTotalBishop()"/>0 cm</label><br/>
<label class='radiolabel'><input type="radio" name="selectedcervicaldilatation" value="cerdi2" onclick="calculateTotalBishop()" checked/>1-2 cm</label><br/>
<label class='radiolabel'><input type="radio" name="selectedcervicaldilatation" value="cerdi3" onclick="calculateTotalBishop()" />3-4 cm</label><br/>
<label class='radiolabel'><input type="radio" name="selectedcervicaldilatation" value="cerdi4" onclick="calculateTotalBishop()"/>5-6 cm</label><br/>
<br/>
</fieldset>
</div>
</form>
Here is the JavaScript code to process the selection:
var cervical_dilatation = new Array();
cervical_dilatation["cerdi1"]=0;
cervical_dilatation["cerdi2"]=1;
cervical_dilatation["cerdi3"]=2;
cervical_dilatation["cerdi4"]=3;
// getCervicalDilation() finds the points based on the answer to "Cervical Dilation".
// Here, we need to take user's the selection from radio button selection
function getCervicalDilation()
{
var cerdiPoints=0;
//Get a reference to the form id="bishopform"
var theForm = document.forms["bishopform"];
//Get a reference to the answer the user Chooses name=selectedcervicaldilatation":
var selectedCervicalDilation = theForm.elements["selectedcervicaldilatation"];
//Here since there are 4 radio buttons selectedCervicalDilation.length = 4
//We loop through each radio buttons
for(var i = 0; i < selectedCervicalDilation.length; i++)
{
//if the radio button is checked
if(selectedCervicalDilation[i].checked)
{
//we set cerdiPoints to the value of the selected radio button
cerdiPoints = cervical_dilatation[selectedCervicalDilation[i].value];
//If we get a match then we break out of this loop
//No reason to continue if we get a match
break;
}
}
//We return the cerdiPoints
return cerdiPoints;
}
function calculateTotalBishop()
{
//Here we get the Bishop Score by calling our function
//Each function returns a number so by calling them we add the values they return together
var bishopScore = 3*getCervicalDilation() + 1;
//display the result
var divobj = document.getElementById('bishopScore');
divobj.style.display='block';
divobj.innerHTML = bishopScore+"% likelihood that induction will be successful";
}
For any particular reason, I'm not able to see the result of user's selection.
How can this be fixed?
The problem is that calculateTotalBishop() has to be a global function... But jsfiddle wraps your code in window.onload... And that's the reason an error is logged which says Uncaught ReferenceError: calculateTotalBishop is not defined
To fix this just change the "Load Type" in js settings in jsfiddle from "onLoad" to "No wrap - in body"... That will solve the problem
Working fiddle : https://jsfiddle.net/1oqxsw81/1/
PS:
It's recommended to use addEventListener in js instead of onclick in html
and it'll be much better if you use onchange event because the value can be changed from a keyboard also
It doesn't work because of the how the JSFiddle handles their scripts in the preview. Because they inject the entered script into iframe by using window.onload method, your functions become private in the new scope, and can't be called from html.
Your code works expected as it is in the fiddle from SO:
var cervical_dilatation = new Array();
cervical_dilatation["cerdi1"]=0;
cervical_dilatation["cerdi2"]=1;
cervical_dilatation["cerdi3"]=2;
cervical_dilatation["cerdi4"]=3;
// getCervicalDilation() finds the points based on the answer to "Cervical Dilation".
// Here, we need to take user's the selection from radio button selection
function getCervicalDilation()
{
var cerdiPoints=0;
//Get a reference to the form id="bishopform"
var theForm = document.forms["bishopform"];
//Get a reference to the answer the user Chooses name=selectedcervicaldilatation":
var selectedCervicalDilation = theForm.elements["selectedcervicaldilatation"];
//Here since there are 4 radio buttons selectedCervicalDilation.length = 4
//We loop through each radio buttons
for(var i = 0; i < selectedCervicalDilation.length; i++)
{
//if the radio button is checked
if(selectedCervicalDilation[i].checked)
{
//we set cerdiPoints to the value of the selected radio button
cerdiPoints = cervical_dilatation[selectedCervicalDilation[i].value];
//If we get a match then we break out of this loop
//No reason to continue if we get a match
break;
}
}
//We return the cerdiPoints
return cerdiPoints;
}
function calculateTotalBishop()
{
//Here we get the Bishop Score by calling our function
//Each function returns a number so by calling them we add the values they return together
var bishopScore = 3*getCervicalDilation() + 1;
//display the result
var divobj = document.getElementById('bishopScore');
divobj.style.display='block';
divobj.innerHTML = bishopScore+"% likelihood that induction will be successful";
}
#bishopScore{
padding:10px;
font-weight:bold;
background-color:limegreen;
}
<form action="" id="bishopform" onsubmit="return true;">
<div>
<fieldset>
<legend>Bishop score</legend>
<p>(modify one field to see the score)</p>
<div id="bishopScore"></div>
<label><b>Cervical Dilatation</b></label><br/>
<label class='radiolabel'><input type="radio" name="selectedcervicaldilatation" value="cerdi1" onclick="calculateTotalBishop()"/>0 cm</label><br/>
<label class='radiolabel'><input type="radio" name="selectedcervicaldilatation" value="cerdi2" onclick="calculateTotalBishop()" checked/>1-2 cm</label><br/>
<label class='radiolabel'><input type="radio" name="selectedcervicaldilatation" value="cerdi3" onclick="calculateTotalBishop()" />3-4 cm</label><br/>
<label class='radiolabel'><input type="radio" name="selectedcervicaldilatation" value="cerdi4" onclick="calculateTotalBishop()"/>5-6 cm</label><br/>
<br/>
</fieldset>
</div>
</form>

Dynamic assigning of event listener for multiple classes is not working

Im struggling to find problem.
Idea behind code:
dynamically assign event listener "oninput" to specific inputs on page determined by classes stored in "classes" array.
Problem:
function PassValue does not handle any element event where class is different from the last index in "classes" array(only the last class in array is handled).
When I change order of "class" array elements it results in different class being handled - again class on last index in array.
Image of how it works (or check Snippet)
When I hover over console element in first part "Datum" should be highlighed just as "Blast KD" is on second part. Its simplified representation of when I Type something in them, same text should appear in input under them, but that works only for one of them.
Question:
Does anyone know why is it happening and how to fix it(so all inputs are handled)?
$(function() {
$('.constant-select-form-numeric').attr('list', 'consoptions-numeric');
$('.constant-select-form-numeric-NT').attr('list', 'consoptions-numeric-NT');
$('.constant-select-form-date').attr('list', 'consoptions-date');
});
$(document).ready(function() {
var classes = ['.constant-select-form-date', '.constant-select-form-numeric', '.constant-select-form-numeric-NT'];
var form = $(document).find('form');
for (var j = 0; j < classes.length; j++) {
var c = classes[j];
//console.log(c);
var e = $(document).find(c);
if (e.length > 0) {
// ... switch(c) differentiating classes from each other(assingning atributes)
switch (c) {
case '.constant-select-form-date':
form[0].innerHTML += "<datalist id='consoptions-date'>\n\
<option data-value='-1'>Unknown</option>\n\
</datalist>";
break;
case '.constant-select-form-numeric-NT':
form[0].innerHTML += "<datalist id='consoptions-numeric-NT'>\n\
<option data-value='-2'>NT</option>\n\
</datalist>";
break;
default:
form[0].innerHTML += "<datalist id='consoptions-numeric'>\n\
<option data-value='-3'>NA</option>\n\
</datalist>";
break;
}
// assign EventListener to each element of c
for (var i = 0; i < e.length; i++) {
var element = $("input[for=" + e[i].attributes.for.value + "]")[0];
var hidden = $("input[name=" + e[i].attributes.for.value + "]")[0];
element.value = hidden.value;
element.addEventListener("input", function(elem) {
PassValue(elem.target);
});
PassValue(element);
//print element DOM
console.log(element);
}
}
}
});
function PassValue(element) {
console.log(element);
var x = element.value;
console.log(x);
// rest of function...
var hiddenInput = $(document).find("input[name=" + element.attributes.for.value + "]")[0];
hiddenInput.value = x;
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<html>
<body>
<form>
<fieldset class="form-group">
<label for="datum">Datum: </label>
<input for=datum class="form-control constant-select-form-date">
<input type="text" name="datum" id="frm-newMessageForm-datum">
</fieldset>
<fieldset class="form-group">
<label for="datum1">Datum1: </label>
<input for=datum1 class="form-control constant-select-form-date">
<input type="text" name="datum1" id="frm-newMessageForm-datum1">
</fieldset>
<fieldset class="form-group">
<label for="blast_kd">Text: </label>
<input for=blast_kd class="form-control constant-select-form-numeric">
<input type="text" name="blast_kd" id="frm-newMessageForm-blast_kd">
</fieldset>
<fieldset class="form-group">
<label for="blast_kd1">Text1: </label>
<input for=blast_kd1 class="form-control constant-select-form-numeric">
<input type="text" name="blast_kd1" id="frm-newMessageForm-blast_kd1">
</fieldset>
</form>
</body>
</html>
Nevermind, I solved it with completely different approach on different layer.(adding db constant fields is supposed to be in different layer, not in js)

Can't connect properly an input range value to javascript calculation

I created (build on template) a simple js form. Everything is working with "radio" and "select" input, but i cant connect a "range" value for sum it with everything else.
this how form and calculations works: (sorry for a lot of noobcode)
function showVal(newVal){
document.getElementById("valBox").innerHTML=newVal;
}
function valNum(){
var valNum = document.getElementById("valBox")
}
var cake_prices = new Array();
cake_prices["Round6"]=9;
cake_prices["Round8"]=11;
cake_prices["Round10"]=12;
var filling_prices= new Array();
filling_prices["Yearone"]=12;
filling_prices["Yeartwo"]=60;
filling_prices["Yearthree"]=120;
var billing_prices= new Array();
billing_prices["Billone"]=100;
billing_prices["Billtwo"]=200;
billing_prices["Billthree"]=300;
billing_prices["Billfour"]=400;
billing_prices["Billfive"]=300;
function getCakeSizePrice()
{
var cakeSizePrice=0;
//Get a reference to the form id="cakeform"
var theForm = document.forms["cakeform"];
//Get a reference to the cake the user Chooses name=selectedCake":
var selectedCake = theForm.elements["selectedcake"];
//Here since there are 4 radio buttons selectedCake.length = 4
//We loop through each radio buttons
for(var i = 0; i < selectedCake.length; i++)
{
//if the radio button is checked
if(selectedCake[i].checked)
{
//we set cakeSizePrice to the value of the selected radio button
//i.e. if the user choose the 8" cake we set it to 25
//by using the cake_prices array
//We get the selected Items value
//For example cake_prices["Round8".value]"
cakeSizePrice = cake_prices[selectedCake[i].value];
//If we get a match then we break out of this loop
//No reason to continue if we get a match
break;
}
}
//We return the cakeSizePrice
return cakeSizePrice;
}
function getBillingPrice()
{
var cakeBillingPrice=0;
//Get a reference to the form id="cakeform"
var theForm = document.forms["cakeform"];
//Get a reference to the select id="filling"
var selectedBilling = theForm.elements["billing"];
//set cakeFilling Price equal to value user chose
//For example filling_prices["Lemon".value] would be equal to 5
cakeBillingPrice = billing_prices[selectedBilling.value];
//finally we return cakeFillingPrice
return cakeBillingPrice;
}
function calculateTotal()
{
//Here we get the total price by calling our function
//Each function returns a number so by calling them we add the values they return together
var cakePrice = (getCakeSizePrice() + getBillingPrice()) * valNum();
var num = (cakePrice);
var miPrice = parseInt (num - (num * .35));
var miDiff = parseInt(cakePrice - miPrice);
//display the result
var divobj = document.getElementById('totalPrice');
divobj.style.display='block';
divobj.innerHTML = "Total "+cakePrice;
var divobj = document.getElementById('miPrice');
divobj.style.display='block';
divobj.innerHTML = "Total "+miPrice;
var divobj = document.getElementById('miDiff');
divobj.style.display='block';
divobj.innerHTML = "Total "+miDiff;
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<title>Cake Form</title>
<script type="text/javascript" src="js/formcalculations.js"></script>
<link href="styles/cakeform.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="wrap">
<form action="" id="cakeform" onsubmit="return false;">
<div>
<div class="cont_order">
<fieldset>
<label >Select your province</label>
<label class='radiolabel'><input type="radio" name="selectedcake" value="Round6" onclick="calculateTotal()" />SASKATCHEWAN</label><br/>
<label class='radiolabel'><input type="radio" name="selectedcake" value="Round8" onclick="calculateTotal()" />MANITOBA</label><br/>
<label class='radiolabel'><input type="radio" name="selectedcake" value="Round10" onclick="calculateTotal()" />ALBERTA</label><br/>
<br/>
<br/>
<br>
</br>
<label >BILL</label>
<select id="billing" name='billing' onchange="calculateTotal()">
<option value="Billone">100</option>
<option value="Billtwo">200</option>
<option value="Billthree">300</option>
<option value="Billfour">400</option>
<option value="Billfive">500</option>
</select>
<br/>
<label >TOTAL WITH UTILITY</label>
<div id="totalPrice"></div>
<label >TOTAL WITH MI</label>
<div id="miPrice"></div>
<label >TOTAL SAVED</label>
<div id="miDiff"></div>
<br>
<span id="valBox"></span>
<input type="range" min="5" max="10" step="1"
oninput="showVal(this.value)" onchange="showVal(this.value)">
</fieldset>
</div>
</div>
</form>
</div><!--End of wrap-->
</body>
</html>
everything is working without "range" input and valNum (do i created it correctly?) function.
like if I'm doing:
function calculateTotal()
{
var cakePrice = (getCakeSizePrice() + getBillingPrice());
}
but when I'm adding newVal function chrome showing me total: NaN;
function calculateTotal()
{
var cakePrice = (getCakeSizePrice() + getBillingPrice()+newVal();
}
everything is working without "range" input and valNum (do i created it correctly?) function....
var cakePrice = (getCakeSizePrice() + getBillingPrice()) * valNum();
-valNum() func does not return any value.
but when I'm adding newVal function chrome showing me total: NaN;
var cakePrice = (getCakeSizePrice() + getBillingPrice()+newVal();
-I don't see a newVal() func in the code. There is a newVal variable, but its scope is limited to the fucntion.
Define a global variable and then define the function as below:
var valNum;
function valNum(){
valNum = document.getElementById("valBox")
}
And make use of valNum as below :
var cakePrice = (parseFloat(getCakeSizePrice()) + parseFloat(getBillingPrice())) * parseFloat(valNum);

radio button .checked to perform a math expression using user input javascript

I have two textboxes where a user enters a number into each one and then clicks a radio button to select the mathematical operation to be performed upon the calculate button.This is for a homework assignment, so only javascript and html
are being used, no jquery. Currently when I click the button, nothing appears to happen and I am getting no console errors...
HTML
<div>
<p>Enter two numbers, select a math, then click the button.<br>
The answer will be shown below.</p>
<form>
1st number: <input type="text" name="number1">
2nd number: <input type="text" name="number2">
<br>
<input type="radio" name="add">Add <br>
<input type="radio" name="subtract">Subtract <br>
<input type="radio" name="multiply">Multiply <br>
<input type="radio" name="division">Division <br>
<input type="button" name="calc" onclick="calculate()" value="Calculate"> <br>
</form>
<p id="math_res"></p>
</div>
Javascript
function calculate(){
var num1 = parseInt("document.getElementsByName('number1').value;", 10);
var num2 = parseInt("document.getElementsByName('number2').value;", 10);
var add = document.getElementsByName("add");
var sub = document.getElementsByName("subtract");
var multi = document.getElementsByName("multiply");
var divis = document.getElementsByName("division");
var res = document.getElementById("math_res").innerHTML;
if (add.checked == true){
res = num1 + num2;
}
else if ( sub.checked == true){
res = num1 + num2;
}
else if (multi.checked == true){
res = num1 * num2;
}
else if (divis.checked == true){
res = num1 / num2;
}
}
I thought my function would take the input from the two text boxes and convert the user input to an integer and assign them to variable num1 and num2. Then assign each radio button to a variable to reduce typing of document.get...
that each if statement would check to see if that radio but was checked. If true perform calculation if false move to next if statement and display the results in a paragraph element.
where did I go wrong?
You have a couple of issues.
getElementsByName returns a collection of elements, not a single element so:
var add = document.getElementsByName("add");
will assign undefined to add. But you don't need to use it, just reference the controls as named properties of the form. Pass a reference to the button from the listener:
<input type="button" name="calc" onclick="calculate(this)" value="Calculate">
Then in the function get the form:
function calculate(element) {
var form = element.form;
Now just do:
var num1 = parseInt(form.number1.value, 10);
and so on, which also fixes the other issues you have with referencing the controls.
Also, radio buttons need to have the same name so that only one is selectable, so as Felix says, give them all the same name and differentiate on value (or class or some other attribute value). You'll need to loop over them to find out the operation to perform, so the HTML might be:
<input type="radio" name="operation" value="add">Add <br>
<input type="radio" name="operation" value="subtract">Subtract <br>
<input type="radio" name="operation" value="multiply">Multiply <br>
<input type="radio" name="operation" value="division">Division <br>
Then to get the operation:
var radios = form.operation;
var op;
for (var i=0; i<radios.length; i++) {
if (radios[i].checked) {
op = radios[i].value;
break;
}
}
Now check the value of op to work out whether to add, subtract, etc.
Here's a quick example, I don't recommend inline scripts like this but it's handy for playing.
<form>
<input type="radio" name="operation" value="add">Add <br>
<input type="radio" name="operation" value="subtract">Subtract <br>
<input type="radio" name="operation" value="multiply">Multiply <br>
<input type="radio" name="operation" value="division">Division <br>
<input type="button" onclick="
var form = this.form;
var radios = form.operation;
var op;
for (var i=0; i<radios.length; i++) {
if (radios[i].checked) {
op = radios[i].value;
break;
}
}
form.selectedOperation.value = op || 'No operation selected';
" value="Get selected operation">
<input type="text" readonly name="selectedOperation"><br>
<input type="reset">
</form>
There are a few issues I can notice.
1.
getElementsByName returns a NodeList, which is Array-like. You need to retrieve the first element in the NodeList before accessing its value. For example,
document.getElementsByName('number1')[0].value
2.
You are passing a literal code string to parseInt. You should write something like
parseInt(document.getElementsByName('number1')[0].value, 10);
3.
The code var res = document.getElementById('math_res').innerHTML stores a reference to the innerHTML of the element. When you assign res = num1 + num2 for example, you are simply overwriting the reference, instead of actually altering the innerHTML. To correct this,
var elem = document.getElementById('math_res');
// later...
elem.innerHTML = num1 + num2;
4. You are incorrectly defining multiple radio buttons with different names. In order for the browser to render them as a "radio button group" where only one can be selected, they must have the same name, but different "value" attributes. See RobG's answer or the Plunkr below for an example of how to define the radio button group and extract its value using JavaScript.
A working version of your code is here.
Edit Please note that these are minimal edits to make your code work. RobG's answer shows a more correct way of extracting the values of form fields.
Here is my version, hope it helps you.
<!DOCTYPE html>
<html>
<body>
<div>
<p>Enter two numbers, select a math, then click the button.<br>
The answer will be shown below.</p>
<form>
1st number: <input type="text" name="number1" id = 'number1'>
2nd number: <input type="text" name="number2" id = 'number2'>
<br>
<input type="radio" name="button" id = 'add' >Add <br>
<input type="radio" name="button" id = 'substract'>Subtract <br>
<input type="radio" name="button" id = 'multiply'>Multiply <br>
<input type="radio" name="button" id = 'division'>Division <br>
<input type="button" name="calc" onclick="calculate()" value="Calculate"> <br>
</form>
<p id="math_res"></p>
</div>
<script>
function calculate(){
//Obtaining the references to the text inputs
var number1 = parseInt(document.getElementById('number1').value);
var number2 = parseInt(document.getElementById('number2').value);
//Reference of the result Box
var resultBox = document.getElementById('math_res');
resultBox.innerHTML = '';
//Reference of the radio buttons
var buttonAdd = document.getElementById('add');
var buttonSubstract = document.getElementById('substract');
var buttonMultiply = document.getElementById('multiply');
var buttonDivision = document.getElementById('division');
//Make the magic
if(buttonAdd.checked == true){
resultBox.innerHTML = number1 + number2
}
else{
if(buttonSubstract.checked == true){
resultBox.innerHTML = number1 - number2
}
else{
if(buttonMultiply.checked == true){
resultBox.innerHTML = number1 * number2
}
else{
if(buttonDivision.checked == true){
resultBox.innerHTML = number1 / number2
}
}
}
}
}
</script>
</body>

Categories

Resources