JQuery not appending html - javascript

Currently working on an "retirement calculator" where I have to generate a table for money-saved each year based on data entered into the first two forms. Unfortunately I can't figure out why it's not appending the table to the site. I don't receive any errors on the console.
I'm also a complete novice at JS/JQ. The code for calculate is near the bottom. I realize it may look at little all over the place, I'm trying to get it to work first before I got back and clean it up some.
EDIT: I took out some methods so there isn't so much to traverse. Assume that the variables involved in calculate are set to real values (aka they're not null/NaN).For example there's an add JQuery method that'll add more scenarios. But since it distracts from the problem I took it out. But the for loop runs in relation to the array
var scenarioCount=0;
var hasError=false
var error=false;
var YOB;
var CurrSav;
var RetAge;
var LifeExp;
var Year;
var scenarios = new Array();
$(document).ready(function ()
{
$('#calculate').on('click', function(e)
{
if(!isBasicInfoValid()) //check to see if basic info is correct
{
if(!error) //if there isn't already an error put one
{
$('#basic').append($("<div class='basicError'>Input is not valid! </div>"));
}
resetVars(); //reset the variables
error=true; //say there is an error on screen
}
else
{
$("#basic .basicError").remove();
error=false;
calculate();
}
e.preventDefault();
});
});
function calculate()
{
var body = document.getElementById('body');
//body is null right here for some reason
$(body).append("<div id='results' class='form'>");
for(var i=0;i<scenarios.length;i++)
{
var element = scenarios[i];
var n = parseInt(YOB)+parseInt(RetAge)-Year;
var m = LifeExp-RetAge;
var r = 1+element.workRate;
var g = 1 + element.retiredRate;
var I = CurrSav;
var T = element.retIncome;
var part1 = (T/Math.pow(g,m-1))*((1-Math.pow(g,m))/(1-g))-(I*Math.pow(r,n));
var S = part1*(1-r)/(1-Math.pow(r,n));
var savings=I;
$('#results').append("<div><h4>You need to save "+S+" dollars</h4></div>")
$('#results').append("<table id=t><tr><th>Year</th><th>Money Saved</th></tr>");
for(var j=n;j>0;j--)
{
savings=S+savings*r;
$('#t').append("<tr><td>"+j+"</td><td>"+savings+"</td></tr>")
}
for(var j=m;j>0;j--)
{
savings=(savings-T)*g;
$('#t').append("<tr><td>"+j+"</td><td>"+savings+"</td></tr>")
}
$('#results').append("</table></div>");
}
};
function resetVars()
{
YOB=null;
CurrSav=null;
RetAge=null;
LifeExp=null;
Year=null;
}
function scenarioObject()
{
var obj={
nameScen : document.forms["scenario"]["ScenarioName"].value,
workRate : document.forms["scenario"]["Working"].value,
retiredRate : document.forms["scenario"]["Retired"].value,
retIncome : document.forms["scenario"]["desiredInc"].value
}
return obj;
}
<!DOCTYPE html>
<html>
<head>
<title>Assignment 3</title>
<link rel='stylesheet' type='text/css' href='/uncSemester7/comp426/a3/assignment3.css'>
<script src='/uncSemester7/comp426/a3/jquery-1.10.2.js'></script>
<script src='/uncSemester7/comp426/a3/assignment3.js'></script>
</head>
<body>
<div class='form'>
<h3> Basic Information </h3>
<form id='basic'>
<div>Year of Birth: <input type='number' name='YOB'> </div>
<div>Current Savings: <input type='number' name='CurrSav'>
</div>
<div>Expected Retirement Age: <input type='number' name='RetAge'></div>
<div>Life expectancy: <input type='number' name='LifeExp'>
</div>
</form>
</div>
<div id='scenDiv' class='form'>
<div id='buttons'>
<div><button id='add' type='submit'>Add Scenario </button></div>
<div><button id='calculate' type='submit'> Calculate </button></div>
</div>
<h3> Scenario </h3>
<form id='scenario'>
<div>Name: <input type='text' name='ScenarioName'> </div>
<div>Rate of Investment Return (While Working): <input type='number' name='Working'></div>
<div>Rate of Investment Return (Retired): <input type='number' name='Retired'></div>
<div>Desired Retirement Yearly Income: <input type='number' name='desiredInc'></div>
</form>
</div>
</body>
</html>

You're using getElementById('body'), where you should be using getElementsByTagName('body')[0], as body is not an id, but a tag. Or better yet with jQuery since you're already using it, $('body').

Related

javascript event handler not working (button click - google says null)

I've looked over a number of threads here of similar problems to little avail - I can't figure out exactly what's going wrong here. Google claims that the element I'm trying to reference is null
Uncaught TypeError: Cannot read property 'addEventListener' of null at sales.js:12
and no matter how I've tried to fix it, it doesn't seem to work. As you can see in the js code, I've tried a number of ways of fixing it based on stuff I've found here.
Originally the <script src ="sales.js"> in the HTML file was up in the head, but I read in some pages here that putting it there can make it load before everything else and to put it down before the HTML closing tag.
Any suggestions?
HTML Code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sales Tax Calculator</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<main>
<h1>Sales Calculator</h1>
<p>Complete the form and click "Calculate".</p>
<fieldset>
<legend>
Item Information
</legend>
<label for="item">Item:</label>
<input type="text" id="item" ><br>
<label for="price">Price:</label>
<input type="text" id="price" ><br>
<label for="discount">Discount %:</label>
<input type="text" id="discount" ><br>
<label for="taxRate">Tax Rate:</label>
<input type="text" id="taxRate" ><br>
<label for="total">Discount Price:</label>
<input type="text" id="discountPrice" disabled ><br>
<label for="salesTax">Sales Tax:</label>
<input type="text" id="salesTax" disabled ><br>
<label for="total">Total:</label>
<input type="text" id="total" disabled ><br><br>
<div id="buttons">
<input type="button" id="calculate" value="Calculate" >
<input type="button" id="clear" value="Clear" ><br></div>
</fieldset>
<pre>© Fall 2020 Rob Honomichl - Dakota State University</pre>
</main>
</body>
<script src="sales.js"></script>
</html>
JS Code:
//"use strict"
var $ = function (id) {
return document.getElementById(id);
};
//window.addEventListener("DOMContentLoaded", () => {
//$("#calculate").addEventListener("click", processEntries);
//});
window.addEventListener('DOMContentLoaded', function () {
document.getElementById("#calculate").addEventListener("click", processEntries);
});
//window.onload = function(){
//$("#calculate").addEventListener("click", processEntries);
//};
const processEntries = () => {
//Gather User Input
//var item = document.querySelector("#item").value;
var price = parseFloat(document.querySelector("#price").value).toFixed(2);
var discount = parseInt(document.querySelector("#discount").value);
var taxRate = parseInt(document.querySelector("#taxRate").value);
//Calculate Discounted Price
function discountPriceCalc(price, discount) {
const disPrice = price * (discount/100);
return disPrice.toFixed(2);
}
//Calculate Sales Tax
function salesTaxCalc(discountPrice, taxRate) {
const taxTotal = price * (taxRate/100);
return taxTotal.toFixed(2);
}
//Calculate Total
function totalCalc(discountPrice, salesTax) {
return ((Number(discountPrice) + Number(salesTax).toFixed(2)));
}
//Calculate the disabled text box values
var discountPrice = discountPriceCalc(price, discount);
var salesTax = salesTaxCalc(discountPrice, taxRate);
var Total = totalCalc(discountPrice, salesTax);
//Update Text Boxes
document.getElementById("discountPrice").value = discountPrice;
document.getElementById("salesTax").value = salesTax;
document.getElementById("total").value = Total;
//set focus to Item box after
document.getElementById("item").focus();
};
You need to get rid of the # in the getElementById call to properly locate the element.
window.addEventListener('DOMContentLoaded', function () {
document.getElementById("calculate").addEventListener("click", processEntries);
});

Writing single JS script for assigning ID's to output in HTML

I am creating a website that has a list of user inputs, however at a certain stage I want users to see a summarized page of all their inputs. If the input was not chosen it should not show as part of the summary (as in the script example below).
Here is my problem: there will be multiple user inputs and to write a JS script to achieve what I had done in an example script below will be lots of work and unfeasible. Is there a way the two JS scripts for the individual ID's can be combined into one as in the script below?
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<div>
<label>For the first test</label>
<input type="text" placeholder="Enter Number" name="clientinfo" id="test1" required>
</div>
<div>
<label>For the second test</label>
<input type="text" placeholder="Enter Number" name="clientinfo" id="test2" required>
</div>
<button id="myBtn">Test</button>
<div style="color:blue;">
<p id="result1"></p>
</div>
<div style="color:red">
<p id="result2"></p>
</div>
<script>
function getUserName() {
var test1 = document.getElementById('test1').value;
var result1 = document.getElementById('result1');
if (test1.length > 0) {
result1.textContent = 'Test1: ' + test1;
} else {
null;
}
}
var myBtn = document.getElementById('myBtn');
myBtn.addEventListener('click', getUserName, false);
</script>
<script>
function getUserName() {
var test2 = document.getElementById('test2').value;
var result2 = document.getElementById('result2');
if (test2.length > 0) {
result2.textContent = 'Test2: ' + test2;
} else {
null;
}
}
var myBtn = document.getElementById('myBtn');
myBtn.addEventListener('click', getUserName, false);
</script>
</body>
</html>
P.s. I would also like to know if a user were to press the test button with an input, remove the input and press the test button again, that the first input would be removed?
You can get all inputs and loop throw the result and create an dom element which will contain the value of the input
and each created element will be added to lets say a result element
See code snippet
function getUserName() {
var inputList = document.getElementsByTagName("INPUT");
var res = document.getElementById("result");
res.innerHTML = "";
var indx = 1;
for (i = 0; i < inputList.length; i++) {
if (inputList[i].value != "") {
var ele = document.createElement("p");
ele.innerHTML ="test " + indx + " : " + inputList[i].value
res.appendChild(ele);
indx++;
}
}
}
var myBtn = document.getElementById('myBtn');
myBtn.addEventListener('click', getUserName, false);
<div>
<label>For the first test</label>
<input type="text" placeholder="Enter Number" name="clientinfo" id="test1" required>
</div>
<div>
<label>For the second test</label>
<input type="text" placeholder="Enter Number" name="clientinfo" id="test2" required>
</div>
<button id="myBtn">Test</button>
<div id="result">
</div>

Updating same html Element with jQuery when user input changes

I am trying do some calculations that take user input and supply the calculated value for the user to see. The user will supply two values and then the result, ADF, will be returned.
Two problems that I am having: The value is calculated before I have entered the second value (FG); and when either value is changed, the old ADF is not replaced. I understand that is because it keeps applying .append(), but I do not know what I need to use instead. I have provided pictures of what is happening. I have listed my code below.
*Note the round() and ADF() functions are my Javascript functions used for the calculations and I didn't think it relevant to list that code. Let me know if you think it is relevant to see it.
Thanks in advance for your help.
function main() {
$(document).on('change', '#Gravities', function () {
OG = $('input[name=OG]').val();
FG = $('input[name=FG]').val();
var calc = round(ADF(OG,FG)*100, 2);
$('.ADFbox').append('<div class="ADF">'+calc+'%</div>');
});
}
$(document).ready(main);
<body>
<form id="Gravities">
<div>
<p><label class="originalGravity">OG: <input type='text' name='OG' value =""></input></label></p>
</div>
<div>
<p><label class="finalGravity">FG: <input type='text' name='FG' value=""></input></label></p>
</div>
</form>
<div class = 'ADFbox'>
<p>ADF:</p>
</div>
</body>
</html>
enter image description here
enter image description here
$(document).on("input", ".gravity", function() {
var thisval = $(this).val()
var nothisval = $(".gravity").not(this).val()
if (thisval.length > 0 && nothisval.length > 0) {//check if one value is empty
OG = $('input[name=OG]').val();
FG = $('input[name=FG]').val();
//var calc = round(ADF(OG, FG) * 100, 2);
var calc = OG * FG;//change this computation
//$('.ADFbox').append('<div class="ADF">' + calc + '%</div>');
$('.ADFbox').text("ADF:" + calc).change();
} else {
$('.ADFbox').text("ADF: 0");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<form id="Gravities">
<div>
<p><label class="originalGravity">OG: <input type='text' class="gravity"name='OG' value ="" /></label></p>
</div>
<div>
<p><label class="finalGravity">FG: <input type='text' class="gravity" name='FG' value=""/></label></p>
</div>
</form>
<div class='ADFbox'>
<p>ADF:</p>
</div>
</body>
Check of each value then proceed if both value has length more than 0
Note: input has no ending tag just close like <input />
To solve this you could place the .adf div in the HTML on load and then simply update it's text() instead of using append() to create a new copy after each calculation.
Below is a working example. Note that I simplified the calculation as you didn't provide the logic of the round() or ADF() functions. Try this:
function main() {
$(document).on('change', '#Gravities', function() {
OG = $('input[name=OG]').val();
FG = $('input[name=FG]').val();
//var calc = round(ADF(OG, FG) * 100, 2);
var calc = OG * FG;
$('.ADFbox .adf').text(calc + '%');
});
}
$(document).ready(main);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="Gravities">
<div>
<p>
<label class="originalGravity">
OG:
<input type='text' name='OG' value="">
</label>
</p>
</div>
<div>
<p>
<label class="finalGravity">
FG:
<input type='text' name='FG' value="">
</label>
</p>
</div>
</form>
<div class='ADFbox'>
<p>ADF: <div class="adf"></div></p>
</div>
The problem you are appending html not updating the existing text value.
Just change your code like below:
$(document).on('change', '#Gravities', function () {
OG = $('input[name=OG]').val();
FG = $('input[name=FG]').val();
if(OG != "" && FG != ""){
var calc = round(ADF(OG,FG)*100, 2);
$('.ADFbox').find("p").html("ADF:"+ calc + '%');
}
});
function main() {
$(document).on('change', '#Gravities', function () {
if($('input[name=OG]').val()!='' && $('input[name=FG]').val()!=''){
var calc = round(ADF(OG,FG)*100, 2);
$('.ADFbox').html('<div class="ADF">'+calc+'%</div>');
}
});
}
$(document).ready(main);
<body>
<form id="Gravities">
<div>
<p><label class="originalGravity">OG: <input type='text' name='OG' value =""></input></label></p>
</div>
<div>
<p><label class="finalGravity">FG: <input type='text' name='FG' value=""></input></label></p>
</div>
</form>
<div class = 'ADFbox'>
<p>ADF:</p>
</div>
</body>
</html>
You have added on change event. that's why it's getting calculated each time when any one of the fields got updated. I made few changes:
<form id="Gravities">
<div>
<p><label class="originalGravity">OG: <input type='number' name='OG' value =""></input></label></p>
</div>
<div>
<p><label class="finalGravity">FG: <input type='number' name='FG' value=""></input>
</label></p>
</div>
<button type="button" id="fgs">
Find ADF</button>
</button>
</form>
<div class = 'ADFbox'>
<p>ADF:</p>
</div>
function main() {
$("#fgs").on('click', function () {
OG = $('input[name=OG]').val();
FG = $('input[name=FG]').val();
var calc = OG*FG;
document.getElementsByClassName("ADFbox")[0].innerHTML= "ADF:"+" " +calc;
});
}
$(document).ready(main);
created working fiddle for you: https://jsfiddle.net/Safoora/hspdgqca/15/
Sorry if I'm not understanding you. As per my understanding you need to calculate only if both inputs field are changed? If it is so, you can do like this:
function main() {
$(document).on('change', '#Gravities input', function () {
OG = $('input[name=OG]');
FG = $('input[name=FG]');
$(this).data('changed',true); // set "changed=true" for current input
// Check if both input fields are changed
if(OG.data('changed') == true && FG.data('changed') == true){
//var calc = round(ADF(OG.val(),FG.val())*100, 2); // uncomment this
var calc = OG.val() * FG.val(); // comment this
$('.ADFbox').html(function(){
$('#Gravities input').data('changed',false); // set "changed=false" for next query
return '<div class="ADF">'+calc+'%</div>'
});
}
});
}
$(document).ready(main);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="Gravities">
<div>
<p><label class="originalGravity">OG: <input type='text' name='OG' value =""></input></label></p>
</div>
<div>
<p><label class="finalGravity">FG: <input type='text' name='FG' value=""></input></label></p>
</div>
</form>
<div class = 'ADFbox'>
<p>ADF:</p>
</div>

How to change html output through javascript?

I sincerely apologise if this question has been asked already but I'm fairly new to this and couldn't find the answer online...
I am learning about using javascript with html and I am trying to change the html output depending on what the user inputs. Somthing like this:
<!DOCTYPE html>
<html>
<script>
function showCost() {
var registrationJS = document.forms["myForm"]["registration"].value;
var adsJS = document.forms["myForm"]["ads"].value;
var cost = 0;
if (registrationJS == "premium") {
cost += 50;
}
if (ads == "yes") {
cost += 2;
}
cost = '$'+cost;
document.write(cost);
}
</script>
<head>
</head>
<body>
<form name="myForm" method="post">
Registration:<select id="registration">
<option value="premium">Premium</option>
<option value="free">Free</option>
</select>
Pay to get rid of ads?<br>
<input type="radio" id="ads" value="yes">Yes<br>
<input type="radio" id="ads" value="no">No<br>
Cost: <-- display cost -->
<script>showCost(); <-- ???? --> </script>
</form>
</body>
</html>
Basically, how can I make display the cost, and how can I make it so it updates every time I change one of the outputs it will display the new cost?
Btw I am aware that if I make it premium and then free it wont go back down I'm just trying to get the basics of the html part and the syntax... Thank you! :)
make a div:
Cost: <div id = "cost"></div>
and in the function instead of document.write(cost), do
document.getElementById('cost').innerHTML = cost;
to update with user input use suitable event handler: Events
Here is one way you can do, using event listener.
(function(sel,inp) {
function showCost() {
var cost = 0;
if (sel.value == "premium") {
cost += 50;
}
if (inp[0].checked) {
cost += 2;
}
cost = '$'+cost;
document.getElementById('cost').textContent = cost;
}
showCost();
sel.addEventListener('change', function(e) {
showCost(e);
})
for (var i = 0; i < inp.length; i++) {
inp[i].addEventListener('click', function(e) {
showCost(e);
})
}
})(document.querySelector('.registration'),document.querySelectorAll('input'));
<form name="myForm" method="post">
Registration:<select class="registration">
<option value="premium">Premium</option>
<option selected value="free">Free</option>
</select>
<br>
Pay to get rid of ads?<br>
<input type="radio" name="ads" value="yes">Yes<br>
<input type="radio" name="ads" checked value="no">No<br>
Cost:<span id="cost"></span>
</form>

Checking the value of radio button submission

I'm trying to validate the value found the in the radio button when the submit button is clicked. I'm not sure of the proper syntax, this is what I've pieced together from what I've found online so far.
$(document).ready(function(){
alert('testing');
// Create array to traverse so that on clicking submit, the current question
//is deleted, and the next question in the array is loaded.
var questionsArray = [];
//Create counters for both correct answers and current question
var correctAnswers = 0;
var currentQuestion = 0;
//String to use for messages
var rightAnswer = "That's correct! You have " + correctAnswers + " out of 10 correct!";
var wrongAnswer = "Oh dear, that's so so wrong! You have " + correctAnswers + " out of 10 correct";
//Contructor Function to create questions
function Question (question, choices, answer){
this.question = question;
this.choices = choices;
this.answer = answer;
}
//Question Creations
questionsArray.push(new Question('Who is the Flash', ['Walter White', 'Johnny Cage', 'Barry Allen', 'Peter Parker'], 'Barry Allen'));
//Testing:
$('.q_question').append(questionsArray[0]['question']);
$('.btn1').after(questionsArray[0]['choices'][0]);
$('.btn2').after(questionsArray[0]['choices'][1]);
$('.btn3').after(questionsArray[0]['choices'][2]);
$('.btn4').after(questionsArray[0]['choices'][3]);
$('#submit').on('click', function(){
alert('click!'); //Test to make sure the click on submit is being recorded.
currentQuestion ++;
var answer = $('input[name="1"]:checked').val(); //The .val() is new to me, pretty sure this is where I've gone wrong
if(answer == questionsArray[0]['answer']){
correctAnswers ++;
$('.jumbotron').append(rightAnswer);
} else {
$('.jumbotron').append(wrongAnswer);
}
});
});
HTML:
<!doctype html>
<html>
<head lang="en">
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href='css/css.css'>
<title>Super Awesome Quiz!</title>
</head>
<body>
<header class="header">
<h1 classs = "title">Welcome to My Super Awesome Quiz!!</h1>
<h3 class="question_counter">Ver. 1.1</h3>
</header>
<form class = "question">
<h2 class= "q_title"> </h2> <!-- Will use questionCounter here once created -->
<h3 class="q_question"></h3>
<input class='btn btn1' type="radio" name="1" value="answer" >
<br>
<input class='btn btn2' type="radio" name="1" value="answer" >
<br>
<input class='btn btn3' type="radio" name='1' value='answer' >
<br>
<input class='btn btn4' type="radio" name='1' value='answer' >
<br>
<input id="submit" type='submit' name='1' value='Submit'>
<br>
</form>
<div class='jumbotron'>
<h2></h2>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="js.js" type="text/javascript"></script>
</body>
</html>
Problem is you're not updating the value of the radio input:
$('.q_question').append(questionsArray[0]['question']);
$('.btn1').after(questionsArray[0]['choices'][0]);
$('.btn1').val(questionsArray[0]['choices'][0]); // set value to option value
...
This will cause the value of the input to hold the actual value which can be compared to the correct answer.
Another option is to compare to the value of the text after the radio button.

Categories