I'm just trying to start with JavaScript and have put this little loop together. Providing I put 1 in the start box.. it works fine. If I put anything else though the loop itself never takes place.
According to the console my variables should all match the criteria for the loop to activate so I don't see the problem
function myFunction() {
console.clear();
var Start = document.getElementById("Start").value
console.log("Start=", Start)
var End = document.getElementById("End").value
console.log("End=", End)
var which_one = document.getElementById("which_one").value
console.log("which_one=", which_one)
var i = Start;
console.log("i=", i);
var Counter_Array = "";
console.log("Counter Array =", Counter_Array);
var Counter_Array_Split = "";
console.log("Counter Array Split = ", Counter_Array_Split)
var Show_Me = "";
console.log("Show Me = ", Show_Me)
console.log("------Loop Starts------")
for (; Start < End; Start++) {
console.log("Start=", Start)
console.log("i looped=", Start);
Counter_Array += "," + Start
var Counter_Array_Split = Counter_Array.split(',');
console.log("CounterArrayLog=", Counter_Array);
console.log("Counter Array Split = ", Counter_Array_Split);
// sets all elements with the id demo to have the value of the newURL variable
document.getElementById("array").innerHTML = Counter_Array_Split;
}
console.log("------Loop Ends------")
var Show_Me = Counter_Array_Split[which_one]
console.log("Show Me = ", Show_Me)
document.getElementById("my_val").innerHTML = Show_Me;
}
.My_Form {
display: block;
background-color: orange;
;
border: 1;
width: 500px;
border-style: solid;
border-radius: 5px;
}
.my_div {
display: block;
background-color: lightblue;
;
border: 1;
width: 500px;
border-style: solid;
border-radius: 5px;
}
<h2>Example Javascript Loop</h2>
<div class="My_Form">
Start #: <input type="text" name="Start" id="Start" value="2"><br> End #: <input type="text" name="fname" id="End" value="10"> <br> Show
me the <input type="text" name="fname" id="which_one" value="5">th value in the array <br>
</div>
<br>
<div class="my_div">
The array built was
<p id="array"></p>
The Value picked was
<p id="my_val"></p>
</div><br>
<button onclick="myFunction()">
Click Me
</button>
<br>
You need to use integers in the for loop, by default you use string, so you need to parse it first.
1st problem: '5' < '10' this is false.
2nd problem: '5'++ will convert it to 5 and only after that will be incremented.
function myFunction() {
console.clear();
var Start = parseInt( document.getElementById("Start").value, 10)
console.log("Start=", Start)
var End = parseInt(document.getElementById("End").value, 10)
console.log("End=", End)
var which_one = document.getElementById("which_one").value
console.log("which_one=", which_one)
var i = Start;
console.log("i=", i);
var Counter_Array = "";
console.log("Counter Array =", Counter_Array);
var Counter_Array_Split = "";
console.log("Counter Array Split = ", Counter_Array_Split)
var Show_Me = "";
console.log("Show Me = ", Show_Me)
console.log("------Loop Starts------")
for (; Start < End; Start++) {
console.log("Start=", Start)
console.log("i looped=", Start);
Counter_Array += "," + Start
var Counter_Array_Split = Counter_Array.split(',');
console.log("CounterArrayLog=", Counter_Array);
console.log("Counter Array Split = ", Counter_Array_Split);
// sets all elements with the id demo to have the value of the newURL variable
document.getElementById("array").innerHTML = Counter_Array_Split;
}
console.log("------Loop Ends------")
var Show_Me = Counter_Array_Split[which_one]
console.log("Show Me = ", Show_Me)
document.getElementById("my_val").innerHTML = Show_Me;
}
.My_Form {
display: block;
background-color: orange;
;
border: 1;
width: 500px;
border-style: solid;
border-radius: 5px;
}
.my_div {
display: block;
background-color: lightblue;
;
border: 1;
width: 500px;
border-style: solid;
border-radius: 5px;
}
<h2>Example Javascript Loop</h2>
<div class="My_Form">
Start #: <input type="text" name="Start" id="Start" value="2"><br> End #: <input type="text" name="fname" id="End" value="10"> <br> Show
me the <input type="text" name="fname" id="which_one" value="5">th value in the array <br>
</div>
<br>
<div class="my_div">
The array built was
<p id="array"></p>
The Value picked was
<p id="my_val"></p>
</div><br>
<button onclick="myFunction()">
Click Me
</button>
<br>
Related
What I don't understand is why does my code not change the text of the label when the radio is selected?
This is what is suppose to happen:
Which when 'Fahrenheit to Celsius' is selected the first image should be true (the text of the first and second label should change)
When 'Celsius to Fahrenheit' is selected the second image should be true (the text of the first and second label should change)
What I'm guessing is my problem is with the if ($("input:to_celsius").val() == "true") statement but I don't quite know why it's wrong.
***Current error message:
{
"message": "Uncaught TypeError: Cannot set property 'onclick' of null",
"filename": "https://stacksnippets.net/js",
"lineno": 69,
"colno": 30
}
"use strict";
var $ = function(id) { return document.getElementById(id); };
var clearTextBoxes = function() {
$("#degrees_entered").value = "";
$("#degrees_computed").value = "";
};
window.onload = function() {
$("#to_celsius").onclick = toCelsius;
$("#to_fahrenheit").onclick = toFahrenheit;
$("#degrees_entered").focus();
};
// Change the text of label 1 and 2 when the radio 'Celsius to Fahrenheit' is selected and clears all other inputs
var toFahrenheit = function() {
if ($("#to_fahrenheit").val() == "true") {
$("#degree_labl_1").text("Enter C degrees");
$("#degree_label_2").text("Degrees Fahrenheit");
clearTextBoxes();
}
}
// Change the text of label 1 and 2 when the radio 'Fahrenheit to Celsius' is selected and clears all other inputs
var toCelsius = function() {
if ($("#to_celsius").val() == "true") {
$("#degree_labl_1").text("Enter F degrees");
$("#degree_label_2").text("Degrees Celsius");
clearTextBoxes();
}
}
body {
font-family: Arial, Helvetica, sans-serif;
background-color: white;
margin: 0 auto;
width: 450px;
border: 3px solid blue;
}
h1 {
color: blue;
margin: 0 0 .5em;
}
main {
padding: 1em 2em;
}
label {
float: left;
width: 10em;
margin-right: 1em;
}
input {
margin-bottom: .5em;
}
#convert {
width: 10em;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Convert Temperatures</title>
<link rel="stylesheet" href="styles.css">
<script src="convert_temp.js"></script>
<script src="jquery-3.4.1.min.js"></script>
</head>
<body>
<main>
<h1>Convert temperatures</h1>
<input type="radio" name="conversion_type" id="to_celsius" checked>Fahrenheit to Celsius<br>
<input type="radio" name="conversion_type" id="to_fahrenheit">Celsius to Fahrenheit<br><br>
<label id="degree_label_1">Enter F degrees:</label>
<input type="text" id="degrees_entered" ><br>
<label id="degree_label_2">Degrees Celsius:</label>
<input type="text" id="degrees_computed" disabled><br>
<label> </label>
<input type="button" id="convert" value="Convert" /><br>
</main>
</body>
</html>
There are multiple issues in your code.
Looks like you are trying to use jQuery here, but in your case you are overriding the jQuery $ function with a custom function. So in effect you are not using jQuery here by calling the $ function but using pure javascript selectors
var $ = function(id) {
return document.getElementById(id);
};
With a function declaration as above, you can select elements only by Id and the Id should not be prefixed with #
$("#degree_label_1") won't work here
$("degree_label_1") will work.
So I suggest changing the $ function declaration to something like below.
var $ = function(selector) {
return document.querySelector(selector);
};
Here I changed document.getElementById -> document.querySelector so that selectors are more flexible (You can use any css selectors like "#id", ".classname" etc)
As we are not using jQuery here, the below code will not work. In jQuery, its correct but there are syntax differences in accessing the dom in plain javascript
$("#to_fahrenheit").val() == "true"
One way to implement the same is..
Assign values to the radio button inputs
<input
type="radio"
name="conversion_type"
id="to_celsius"
value="f_to_c"
checked
/>Fahrenheit to Celsius<br />
<input
type="radio"
name="conversion_type"
id="to_fahrenheit"
value="c_to_f"
/>Celsius to Fahrenheit<br />
and check the value
$("#to_fahrenheit").value == "c_to_f"
Same applies to the below line. There's a typo as well (Missed an e in degree_label_1)
$("#degree_labl_1").text("Enter F degrees")
should be changed to
$("#degree_label_1").textContent = "Enter F degrees"
Complete code would look like below.
"use strict";
var $ = function(id) {
return document.querySelector(id);
};
var clearTextBoxes = function() {
$("#degrees_entered").value = "";
$("#degrees_computed").value = "";
};
window.onload = function() {
$("#to_celsius").onclick = toCelsius;
$("#to_fahrenheit").onclick = toFahrenheit;
$("#convert").onclick = convert;
$("#degrees_entered").focus();
};
// Change the text of label 1 and 2 when the radio 'Celsius to Fahrenheit' is selected and clears all other inputs
var toFahrenheit = function() {
if ($("#to_fahrenheit").value == "c_to_f") {
$("#degree_label_1").textContent = "Enter C degrees";
$("#degree_label_2").textContent = "Degrees Fahrenheit";
clearTextBoxes();
}
};
// Change the text of label 1 and 2 when the radio 'Fahrenheit to Celsius' is selected and clears all other inputs
var toCelsius = function() {
if ($("#to_celsius").value == "f_to_c") {
$("#degree_label_1").textContent = "Enter F degrees";
$("#degree_label_2").textContent = "Degrees Celsius";
clearTextBoxes();
}
};
var convert = function() {
var conversiontype = $(
'[name="conversion_type"]:checked'
).value;
var enteredValue = Number($("#degrees_entered").value);
if (conversiontype === "f_to_c") {
$("#degrees_computed").value = ((enteredValue - 32) * 5) / 9;
} else {
$("#degrees_computed").value = (enteredValue * 9) / 5 + 32;
}
};
body {
font-family: Arial, Helvetica, sans-serif;
background-color: white;
margin: 0 auto;
width: 450px;
border: 3px solid blue;
}
h1 {
color: blue;
margin: 0 0 0.5em;
}
main {
padding: 1em 2em;
}
label {
float: left;
width: 10em;
margin-right: 1em;
}
input {
margin-bottom: 0.5em;
}
#convert {
width: 10em;
}
<h1>Convert temperatures</h1>
<input
type="radio"
name="conversion_type"
id="to_celsius"
value="f_to_c"
checked
/>Fahrenheit to Celsius<br />
<input
type="radio"
name="conversion_type"
id="to_fahrenheit"
value="c_to_f"
/>Celsius to Fahrenheit<br /><br />
<label id="degree_label_1">Enter F degrees:</label>
<input type="text" id="degrees_entered" /><br />
<label id="degree_label_2">Degrees Celsius:</label>
<input type="text" id="degrees_computed" disabled /><br />
<label> </label>
<input type="button" id="convert" value="Convert" /><br />
If you want to use jQuery, you should remove below function declaration
var $ = function(id) {
return document.getElementById(id);
};
And modify your code as follows.
"use strict";
var clearTextBoxes = function() {
$("#degrees_entered").val("");
$("#degrees_computed").val("");
};
window.onload = function() {
$("#to_celsius").on("click", toCelsius);
$("#to_fahrenheit").on("click", toFahrenheit);
$("#convert").on("click", convert);
$("#degrees_entered").focus();
};
// Change the text of label 1 and 2 when the radio 'Celsius to Fahrenheit' is selected and clears all other inputs
var toFahrenheit = function() {
if ($("#to_fahrenheit").val() == "c_to_f") {
$("#degree_label_1").text("Enter C degrees");
$("#degree_label_2").text("Degrees Fahrenheit");
clearTextBoxes();
}
};
// Change the text of label 1 and 2 when the radio 'Fahrenheit to Celsius' is selected and clears all other inputs
var toCelsius = function() {
if ($("#to_celsius").val() == "f_to_c") {
$("#degree_label_1").text("Enter F degrees");
$("#degree_label_2").text("Degrees Celsius");
clearTextBoxes();
}
};
var convert = function() {
var conversiontype = $(
'[name="conversion_type"]:checked'
).val();
var enteredValue = Number($("#degrees_entered").val());
if (conversiontype === "f_to_c") {
$("#degrees_computed").val(((enteredValue - 32) * 5) / 9);
} else {
$("#degrees_computed").val((enteredValue * 9) / 5 + 32);
}
};
body {
font-family: Arial, Helvetica, sans-serif;
background-color: white;
margin: 0 auto;
width: 450px;
border: 3px solid blue;
}
h1 {
color: blue;
margin: 0 0 0.5em;
}
main {
padding: 1em 2em;
}
label {
float: left;
width: 10em;
margin-right: 1em;
}
input {
margin-bottom: 0.5em;
}
#convert {
width: 10em;
}
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<h1>Convert temperatures</h1>
<input type="radio" name="conversion_type" id="to_celsius" value="f_to_c" checked />Fahrenheit to Celsius<br />
<input type="radio" name="conversion_type" id="to_fahrenheit" value="c_to_f" />Celsius to Fahrenheit<br /><br />
<label id="degree_label_1">Enter F degrees:</label>
<input type="text" id="degrees_entered" /><br />
<label id="degree_label_2">Degrees Celsius:</label>
<input type="text" id="degrees_computed" disabled /><br />
<label> </label>
<input type="button" id="convert" value="Convert" /><br />
I'm having an issue calculating the difference of two variables that should change depending on input values and number of inputs.
The jQuery works fine adding/subtracting buttons it's the peoplePaid() function that I've been dealing with.
I'm trying to write the difference (.difference) of paidTotal minus each input of pCheck.
So the first question is how do I get the value for difference (paidTotal - pCheck) to write to .difference for each input on the page.
And if I have to loop iy what may need to be done.
Thank you!
$(document).ready(function () {
var maxFields = 20;
var addButton = $('#plusOne');
var deleteButton = $('#minusOne');
var wrapper = $('#userNumbers');
var fieldInput = '<div><input type="text" name="persons" class="persons"/></div>';
var x = 1;
$(addButton).click(function () {
if (x < maxFields) {
x++;
$(wrapper).append(fieldInput);
}
});
$(deleteButton).click(function (e) {
e.preventDefault();
var myNode = document.getElementById("userNumbers");
i = myNode.childNodes.length - 1;
if (i >= 0) {
myNode.removeChild(myNode.childNodes[i]);
x--;
}
});
});
function peoplePaid() {
var checkTotal = parseFloat(document.getElementById('check').value);
var personsCheck = document.getElementsByClassName('persons');
var paidTotal = document.getElementById('paidTotal');
var serviceQuality = document.getElementById('serviceQuality').value;
var difference = document.getElementsByClassName('difference');
var pCheck = 0;
for (var i = 0; i < personsCheck.length; i += 1) {
pCheck += parseFloat(personsCheck[i].value);
}
paidTotal.innerHTML = (checkTotal * serviceQuality) - pCheck;
for (var i = 0; i < personsCheck.length; i += 1) {
checkDifference = parseFloat(paidTotal - pCheck).value;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3>Check Total</h3>
$ <input type="text" id="check" value="" />
<h3>Tip%</h3>
<select name="tip" id="serviceQuality">
<option disabled selected value="1">-- Choose an Option --</option>
<option value="1">0%</option>
<option value="1.06">6%</option>
<option value="1.15">15%</option>
<option value="1.2">20%</option>
<option value="1.3">30%</option>
</select>
<h3>Number of People: <span id="numberOfPeople"></span></h3>
<button type="button" onclick="plusOne()" id="plusOne">+</button>
<button type="button" onclick="minusOne()" id="minusOne">-</button>
<div>
<div id="userNumbers">
<input type="text" class="persons" name="person" />
<p class="difference">$</p>
</div>
</div>
<button onclick="peoplePaid()">Calculate</button>
<!--Paid Amount-->
<div>
<h3>Paid Amount: <span id="paidTotal"></span></h3>
</div>
Disscrepancies
There were some discrepancies that should be addressed:
(Major) There are two functions called by onclick event handlers:
<button type="button" onclick="plusOne()" id="plusOne">+</button>
<button type="button" onclick="minusOne()" id="minusOne">-</button>
First of all, a quick run of this Snippet logs errors about these functions not existing. Secondly, you should never use on-event handlers when using jQuery, it's like using paddle (on-event handlers) on a speed boat (event delegation using .on()).
(Minor) If you store jQuery Objects in variables, do not wrap those variables in $(...) because they already wrapped in $(...) when you declared them:
var addButton = $('#plusOne');
$(addButton).on('click',... // That is like doing this: $($('#plusOne'))
addButton.on('click',...... // This is the cleaner way or...
var $addButton = $('#plusOne');
$addButton.on('click'...... /* This is a common practice which serves as an obvious
reminder that the variable is a jQuery Object */
Plain JavaScript Array Methods
(Core) The solution is to collect all of the input.customer' by gathering the <input>s into a NodeList with .querySelctorAll() and then converting it into an array with Array.from():
var customers = Array.from(document.querySelectorAll('.customer'));
Next, use .map() to extract each of the <input>'s values, and then return them as an array:
var payments = customers.map(function(customer) {
return parseFloat(customer.value);
});
Finally, use .reduce() to add all of the values in the payments array into one number:
paidTotal = payments.reduce(function(total, number) {
return total + number;
});
Demo
var max = 20;
var count = 1;
var paidTotal = 0;
var customerQty = $('#totalCustomers');
var add = $('#add');
var group = $('.group');
var paid = `
<li>
<input type="number" class="customer" step='0.01'/>
<button type="button" class="remove">-</button>
</li>`;
add.on('click', function(e) {
if (count < max) {
count++;
group.append(paid);
} else {
return false;
}
customerQty.val(count);
});
group.on('click', '.remove', function() {
if (count > 0) {
count--;
var subtract = parseFloat($(this).prev('.customer').val()).toFixed(2);
var total = parseFloat($('#paidTotal').val()).toFixed(2);
var newTotal = parseFloat(total - subtract).toFixed(2);
$('#paidTotal').val(newTotal);
var due = parseFloat($('#balanceDue').val());
$('#balanceDue').val((due + parseFloat(subtract)).toFixed(2));
$(this).parent().remove();
} else {
return false;
}
customerQty.val(count);
});
$('#bill').on('input', totalPaid);
function totalPaid(e) {
var check = $('#check').val();
var tip = $('#tip').val();
var total = $('#paidTotal');
var due = $('#balanceDue');
var customers = Array.from(document.querySelectorAll('.customer'));
var payments = customers.map(function(customer) {
return parseFloat(customer.value);
});
//console.log('payments: '+payments);
paidTotal = payments.reduce(function(total, number) {
return total + number;
});
$('#amountDue').val(parseFloat(check * tip).toFixed(2));
//console.log('paidTotal: '+paidTotal);
total.val(parseFloat(paidTotal).toFixed(2));
due.val(parseFloat((check * tip) - total.val()).toFixed(2));
}
html {
font: 400 16px/1.5 Consolas;
}
body {
font-size: 1rem;
}
fieldset {
width: 490px;
}
button,
label,
select,
input,
output {
display: inline-block;
font: inherit;
line-height: 1.5;
}
label {
margin: 5px;
}
input {
width: 12ex;
text-align: center
}
button {
cursor: pointer;
}
output {
margin-left: -5px;
}
#totalCustomers {
font-size: 1.2rem;
color: blue;
}
#tip {
padding: 5px 0;
margin-left: -5px;
}
.tip {
margin-left: -2px;
}
.customers {
height: fit-content;
min-height: 60px;
}
.group {
margin: -8% 10px auto -25px;
padding-left: 1.5em;
width: 40%;
list-style-position: inside;
}
.group li {
padding-left: 0.1em;
}
.add {
transform: translate(105%, -15%);
}
/*
For debugging purposes only (Optional)
*/
.as-console-wrapper {
width: 250px;
min-height: 100%;
margin-left: 50%;
background: #000;
color: lime;
}
.as-console-row.as-console-row {
background: #000;
}
.as-console-row.as-console-row::after {
content: '';
padding: 0;
margin: 0;
border: 0;
width: 0;
}
<form id='bill'>
<fieldset class='total'>
<legend>Total Amount Due</legend>
$ <input type="number" id="check" value="" step='0.01' min='0.00'>
<label class='tip'>Tip%</label>
<select id="tip">
<option disabled selected value="">Pick</option>
<option value="1">0%</option>
<option value="1.06">6%</option>
<option value="1.15">15%</option>
<option value="1.2">20%</option>
<option value="1.3">30%</option>
</select>
<label>Amount Due: $
<output id="amountDue">0.00</output>
</label>
</fieldset>
<fieldset class='customers'>
<legend>Total Customers:
<output id="totalCustomers">1</output>
</legend>
<label class='add'> Add a Customer
<button type="button" id="add">+</button>
</label>
<ol class='group'>
<li>
<input type="number" class="customer" step='0.01' min='0.00' />
<button type="button" class="remove">-</button>
</li>
</ol>
</fieldset>
<fieldset class='grandTotal'>
<legend>Total Balance</legend>
<label>Paid Amount: $
<output id="paidTotal">0.00</output>
</label>
<br>
<label>Balance Due: $
<output id="balanceDue">0.00</output>
</label>
</fieldset>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
in my class we are using firstChild.nodeValue to display text if a user enters in an incorrect value. However, I can't get my two other fields to display the error message and only the first one. What am I doing wrong? When I run it in the code snipped is says that the nodeValue is null. I have the error messages display through a span and they are being used by the firstChild.nodeValue.
var $ = function (id) {
return document.getElementById(id);
}
var calculateClick = function () {
var investment = parseInt( $("investment").value);
var rate = parseFloat( $("rate").value);
var years = parseInt($("years").value);
//var amount = interest * rate * years;
if (investment==="" || investment < 100 || investment > 100000){
$("investment_error").firstChild.nodeValue="Must be an integer from 100 - 100,000";
}
else if (rate ==="" || rate <0.1 || rate >12){
$("rate_error").firstChild.nodeValue="Must be a value from .1 - 12";
}
else if (years ==="" || years <1 || years > 50){
$("years_error").firstChild.nodeValue="Must be an integer from 1 - 50";
}
var nt = 4*years;
var amount = investment * (1 + (rate/4)) ** nt;
$("future_value").value=amount.toFixed(2);
}
var clear_fields = function (){
$("investment").value="";
$("rate").value="";
$("years").value="";
$("future_value").value="";
}
window.onload = function () {
$("calculate").onclick = calculateClick;
$("calculate").ondblclick=clear_fields;
$("investment").focus();
}
body {
font-family: Arial, Helvetica, sans-serif;
background-color: white;
margin: 0 auto;
width: 48%;
padding: 0 1em .5em;
border: 3px solid blue;
}
h1 {
margin: .5em 0;
text-align: center;
}
label {
float: left;
width: 10em;
text-align: right;
padding-bottom: .5em;
}
input {
margin-left: 1em;
margin-bottom: .5em;
}
span {
color: blue;
}
<!DOCTYPE html>
<html>
<head>
<title>Future Value Calculator</title>
<link rel="stylesheet" href="future_value.css">
<script src="future_value.js"></script>
</head>
<body>
<main>
<h1 id="heading">Future Value Calculator</h1>
<label for="investment">Investment Amount:</label>
<input type="text" id="investment">
<span id="investment_error"> </span><br>
<label for="rate">Annual Interest Rate:</label>
<input type="text" id="rate">
<span id="rate_error"></span><br>
<label for="years">Number of Years:</label>
<input type="text" id="years">
<span id="years_error"></span><br>
<label for="future_value">Future Value:</label>
<input type="text" id="future_value" disabled="disabled"><br>
<label> </label>
<input type="button" id="calculate" value="Calculate"><br>
</main>
</body>
</html>
Its working on the first span becouse you have space between the span tags as:
with space
<span id="investment_error"> </span>
without
<span id="rate_error"></span>
In any case you should use innerHTML instead.
first child is good in case you already have a child in the html tags like this
<div>
<p id="i_am_div_first_child"> first child</p>
</div>
please hit correct answer if that was helpfull.
So what is the difference? A simple test will show you why.
console.log("1:", document.querySelector("#s1").firstChild)
console.log("2:", document.querySelector("#s2").firstChild)
<span id="s1"> </span>
<span id="s2"></span>
The one has a whitespace in it, the others do not the one with the whitespace has a firstChild, the others do not.
What should you do?
I would just set the textContent or innerHTML of the span and not set the nodeValue.
And another issue with your code, is you have
var rate = parseFloat( $("rate").value);
and
if ( rate==="")
That empty string check is not going to happen to be true ever since parseFloat is going to return NaN.
$("rate_error").firstChild returns null because it has no childrne (not even whit space), and so does not have a nodeValue property.
You could just use innerHTML instead of firstChild.nodeValue.
Also you don't need the else, just tell the user immediately all they have to fix.
var $ = function(id) {
return document.getElementById(id);
}
var calculateClick = function() {
var investment = parseInt($("investment").value);
var rate = parseFloat($("rate").value);
var years = parseInt($("years").value);
//var amount = interest * rate * years;
if (investment === "" || investment < 100 || investment > 100000) {
$("investment_error").innerHTML = "Must be an integer from 100 - 100,000";
}
if (rate === "" || rate < 0.1 || rate > 12) {
$("rate_error").innerHTML = "Must be a value from .1 - 12";
}
if (years === "" || years < 1 || years > 50) {
$("years_error").innerHTML = "Must be an integer from 1 - 50";
}
var nt = 4 * years;
var amount = investment * (1 + (rate / 4)) ** nt;
$("future_value").value = amount.toFixed(2);
}
var clear_fields = function() {
$("investment").value = "";
$("rate").value = "";
$("years").value = "";
$("future_value").value = "";
}
window.onload = function() {
$("calculate").onclick = calculateClick;
$("calculate").ondblclick = clear_fields;
$("investment").focus();
}
body {
font-family: Arial, Helvetica, sans-serif;
background-color: white;
margin: 0 auto;
width: 48 %;
padding: 0 1em .5em;
border: 3px solid blue;
}
h1 {
margin: .5em 0;
text-align: center;
}
label {
float: left;
width: 10em;
text-align: right;
padding-bottom: .5em;
}
input {
margin-left: 1em;
margin-bottom: .5em;
}
span {
color: blue;
}
<!DOCTYPE html>
<html>
<head>
<title>Future Value Calculator</title>
<link rel="stylesheet" href="future_value.css">
<script src="future_value.js"></script>
</head>
<body>
<main>
<h1 id="heading">Future Value Calculator</h1>
<label for="investment">Investment Amount:</label>
<input type="text" id="investment">
<span id="investment_error"> </span><br>
<label for="rate">Annual Interest Rate:</label>
<input type="text" id="rate">
<span id="rate_error"></span><br>
<label for="years">Number of Years:</label>
<input type="text" id="years">
<span id="years_error"></span><br>
<label for="future_value">Future Value:</label>
<input type="text" id="future_value" disabled="disabled"><br>
<label> </label>
<input type="button" id="calculate" value="Calculate"><br>
</main>
</body>
</html>
I apologize for asking silly questions, but I have tried to mess with the CSS and changed very little. I am trying to get the label/dropdown (which says "withdrawal" by default to align with the others and also get rid of some of the space between the text areas so that it looks more like the screenshot provided by my instructor. I did manage to reduce some of the extra space between areas by reducing the pixels, but I am not certain how to get it to look exactly like the screenshot.
If anyone would please give suggestions, I would genuinely appreciate it.
var pad_left = function(text, width, pad) { //sets up text area formatting
var result = text.toString();
while (result.length < width) {
result = pad + result;
}
return result; // populates text area
}
var pad_right = function(text, width, pad) { // sets up text area formatting
var result = text.toString();
while (result.length < width) {
result = result + pad;
}
return result;
}
var getResults = function(results) { // actual calculation functions
if (results.length == 0) {
return "";
}
var balance = 2000; / /actual format of text area
var list = pad_right("Date", 12, " ");
list += pad_right("Amount", 12, " ");
list += pad_right("Running Balance", 15, " ") + "\n";
list += pad_right("", 11, "-") + " ";
list += pad_right("", 11, "-") + " ";
list += pad_right("", 15, "-") + "\n";
for (var i = 0; i < results.length; i++) { // loop to calculate balances
var trans = results[i];
list += pad_right(trans["date"], 12, " ");
if(trans["type"] == "withdrawal") // withdrawal calculation
{
balance -= trans["amount"]
list += "$" + pad_left( "-" + trans["amount"].toFixed(2), 11, " ") + " ";
} else { //for Deposits
balance += trans["amount"]
list += "$" + pad_left( trans["amount"].toFixed(2), 11, " ") + " ";
}
list += "$" + pad_left(balance.toFixed(2), 14, " ") + "\n";
}
return list;
}
var get_runningBalance = function(results) { // function to calculate Running Balance
var runningBalance = 0, amount;
for (var i in results) {
runningBalance = startBal - "amount" ;
runningBalance += parseInt(runningBalance.toFixed(2));
}
return runningBalance;
}
var get_startBal = function(transactions){ // fills Starting Balance
return 2000;
}
var get_totalDep = function(transactions){ // function to calculate Total Deposits
var totalDep = 0;
for(var i = 0; i < transactions.length; i++){
var trans = transactions[i];
if(trans["type"] == "deposit")
{
totalDep += trans["amount"]
}
}
return totalDep;
}
var get_totalWd = function(transactions){ // function to calculate Total Withdrawals
var totalWd = 0;
for(var i = 0; i < transactions.length; i++){
var trans = transactions[i];
if(trans["type"] == "withdrawal")
{
totalWd -= trans["amount"]
}
}
return totalWd;
}
var get_endBal = function(transactions){ // function to calculate Ending Balance
var balance = 2000;
for(var i = 0; i < transactions.length; i++){
var trans = transactions[i];
if(trans["type"] == "withdrawal")
{
balance -= trans["amount"]
} else { // Is Deposit
balance += trans["amount"]
}
}
return balance.toFixed(2);
}
// sets up the global variables and arrays for the functions
var balances = [];
var transactions = [];
var $ = function (id) {
return document.getElementById(id);
}
// pulls the info from text boxes
var update_display = function() {
$("startBal").value = get_startBal(transactions);
$("totalDep").value = get_totalDep(transactions);
$("totalWd").value = get_totalWd(transactions);
$("endBal").value = get_endBal(transactions);
$("date").value = "";
$("amount").value = "";
$("date").focus();
$("results").value = getResults(transactions);
}
// function to add transactions to the text area
var addTrans_click = function () {
var trans = [];
trans["date"] = $("date").value;
trans["amount"] = parseFloat($("amount").value);
trans["type"] = $("type").value;
if (trans["date"] == "") return;
if (isNaN(trans["amount"])) return;
transactions.push(trans);
update_display();
}
// the event handlers
window.onload = function () {
$("addTrans").onclick = addTrans_click;
$("date").focus();
}
body {
background: none repeat scroll;
font-family: Arial,Helvetica,sans-serif;
}
#content {
background: none repeat scroll;
border: 8px solid gray;
margin: 10px auto;
padding: 5px 20px;
text-align: center;
width: 600px;
}
h1, h2 {
text-align: left;
}
label {
display: block;
float: left;
padding-right: 1em;
text-align: right;
width: 10em;
}
input {
display: block;
float: left;
}
select {
display: block;
text-align: center;
width: 10em;
}
.formLayout label {
float: left;
text-align: right;
width: 10em;
}
.formLayout input {
margin-bottom: 0.5em;
margin-left: 0.5em;
}
.formLayout br {
clear: both;
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Monthly Balance Calculator</title>
<link href="monthly_balance.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="mbc_library.js"></script>
<script type="text/javascript" src="monthly_balance.js"></script>
</head>
<body>
<div id="content">
<h1>Monthly Balance Calculator</h1>
<br />
<h2>Add Transaction</h2>
<hr />
<br />
<div class="formLayout">
<label for="date">Date:</label>
<input type="text" name="date" id="date" />
<br />
<br />
<label for="type">Type:</label>
<select name="type" id="type">
<option value="withdrawal">Withdrawal</option>
<option value="deposit">Deposit</option>
</select>
<br />
<label for="amount">Amount:</label>
<input type="text" name="amount" id="amount"/>
<br />
<br />
<label> </label>
<input type="button" id="addTrans" value="Add Transaction" />
<br />
</div>
<h2>Transactions</h2>
<hr />
<br />
<textarea name="results" id="results" rows="10" cols="60" disabled="disabled">
</textarea>
<br />
<br />
<h2>Summary</h2>
<hr />
<br />
<div class="formLayout">
<label for="startBal">Starting Balance:</label>
<input type="text" name="startBal" id="startBal"
class="disabled" disabled="disabled"/>
<br />
<br />
<label for="totalDep">Total Deposits:</label>
<input type="text" name="totalDep" id="totalDep"
class="disabled" disabled="disabled"/>
<br />
<br />
<label for="totalWd">Total Withdrawals:</label>
<input type="text" name="totalWd" id="totalWd"
class="disabled" disabled="disabled"/>
<br />
<br />
<label for="endBal">Ending Balance</label>
<input type="text" name="endBal" id="endBal"
class="disabled" disabled="disabled"/>
<br />
<br />
</div>
</body>
</html>
Note, I had to add BOTH JS files in the same form because this site only allows me to paste two, despite the fact that I added two to the HTML page
I think this is what you need.
Check with below code.
var pad_left = function(text, width, pad) { //sets up text area formatting
var result = text.toString();
while (result.length < width) {
result = pad + result;
}
return result; // populates text area
}
var pad_right = function(text, width, pad) { // sets up text area formatting
var result = text.toString();
while (result.length < width) {
result = result + pad;
}
return result;
}
var getResults = function(results) { // actual calculation functions
if (results.length == 0) {
return "";
}
var balance = 2000; / /actual format of text area
var list = pad_right("Date", 12, " ");
list += pad_right("Amount", 12, " ");
list += pad_right("Running Balance", 15, " ") + "\n";
list += pad_right("", 11, "-") + " ";
list += pad_right("", 11, "-") + " ";
list += pad_right("", 15, "-") + "\n";
for (var i = 0; i < results.length; i++) { // loop to calculate balances
var trans = results[i];
list += pad_right(trans["date"], 12, " ");
if(trans["type"] == "withdrawal") // withdrawal calculation
{
balance -= trans["amount"]
list += "$" + pad_left( "-" + trans["amount"].toFixed(2), 11, " ") + " ";
} else { //for Deposits
balance += trans["amount"]
list += "$" + pad_left( trans["amount"].toFixed(2), 11, " ") + " ";
}
list += "$" + pad_left(balance.toFixed(2), 14, " ") + "\n";
}
return list;
}
var get_runningBalance = function(results) { // function to calculate Running Balance
var runningBalance = 0, amount;
for (var i in results) {
runningBalance = startBal - "amount" ;
runningBalance += parseInt(runningBalance.toFixed(2));
}
return runningBalance;
}
var get_startBal = function(transactions){ // fills Starting Balance
return 2000;
}
var get_totalDep = function(transactions){ // function to calculate Total Deposits
var totalDep = 0;
for(var i = 0; i < transactions.length; i++){
var trans = transactions[i];
if(trans["type"] == "deposit")
{
totalDep += trans["amount"]
}
}
return totalDep;
}
var get_totalWd = function(transactions){ // function to calculate Total Withdrawals
var totalWd = 0;
for(var i = 0; i < transactions.length; i++){
var trans = transactions[i];
if(trans["type"] == "withdrawal")
{
totalWd -= trans["amount"]
}
}
return totalWd;
}
var get_endBal = function(transactions){ // function to calculate Ending Balance
var balance = 2000;
for(var i = 0; i < transactions.length; i++){
var trans = transactions[i];
if(trans["type"] == "withdrawal")
{
balance -= trans["amount"]
} else { // Is Deposit
balance += trans["amount"]
}
}
return balance.toFixed(2);
}
// sets up the global variables and arrays for the functions
var balances = [];
var transactions = [];
var $ = function (id) {
return document.getElementById(id);
}
// pulls the info from text boxes
var update_display = function() {
$("startBal").value = get_startBal(transactions);
$("totalDep").value = get_totalDep(transactions);
$("totalWd").value = get_totalWd(transactions);
$("endBal").value = get_endBal(transactions);
$("date").value = "";
$("amount").value = "";
$("date").focus();
$("results").value = getResults(transactions);
}
// function to add transactions to the text area
var addTrans_click = function () {
var trans = [];
trans["date"] = $("date").value;
trans["amount"] = parseFloat($("amount").value);
trans["type"] = $("type").value;
if (trans["date"] == "") return;
if (isNaN(trans["amount"])) return;
transactions.push(trans);
update_display();
}
// the event handlers
window.onload = function () {
$("addTrans").onclick = addTrans_click;
$("date").focus();
}
body {
background: none repeat scroll 0 0 rgba(0, 0, 0, 0);
font-family: Arial,Helvetica,sans-serif;
}
#content {
background: none repeat scroll 0 0 rgba(0, 0, 0, 0);
border: 8px solid gray;
margin: 10px auto;
padding: 5px 20px;
text-align: center;
width: 600px;
}
h1, h2 {
text-align: left;
}
h2 {
margin-bottom: 0;
padding-bottom: 0;
}
label {
display: block;
float: left;
text-align: right;
width: 10em;
}
input {
display: block;
float: left;
}
select {
display: block;
float: left;
text-align: center;
width: 10em;
margin-bottom: 0.5em;
margin-left: 0.5em;
}
.formLayout label {
float: left;
text-align: right;
width: 10em;
}
.formLayout input {
margin-bottom: 0.5em;
margin-left: 0.5em;
}
.formLayout br {
clear: both;
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Monthly Balance Calculator</title>
<link href="monthly_balance.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="mbc_library.js"></script>
<script type="text/javascript" src="monthly_balance.js"></script>
</head>
<body>
<div id="content">
<h1>Monthly Balance Calculator</h1>
<br />
<h2>Add Transaction</h2>
<hr />
<br />
<div class="formLayout">
<label for="date">Date:</label>
<input type="text" name="date" id="date" />
<br />
<label for="type">Type:</label>
<select name="type" id="type">
<option value="withdrawal">Withdrawal</option>
<option value="deposit">Deposit</option>
</select>
<br />
<label for="amount">Amount:</label>
<input type="text" name="amount" id="amount"/>
<br />
<label> </label>
<input type="button" id="addTrans" value="Add Transaction" />
<br />
</div>
<h2>Transactions</h2>
<hr />
<br />
<textarea name="results" id="results" rows="10" cols="60" disabled="disabled">
</textarea>
<br />
<br />
<h2>Summary</h2>
<hr />
<br />
<div class="formLayout">
<label for="startBal">Starting Balance:</label>
<input type="text" name="startBal" id="startBal"
class="disabled" disabled="disabled"/>
<br />
<label for="totalDep">Total Deposits:</label>
<input type="text" name="totalDep" id="totalDep"
class="disabled" disabled="disabled"/>
<br />
<label for="totalWd">Total Withdrawals:</label>
<input type="text" name="totalWd" id="totalWd"
class="disabled" disabled="disabled"/>
<br />
<label for="endBal">Ending Balance</label>
<input type="text" name="endBal" id="endBal"
class="disabled" disabled="disabled"/>
<br />
</div>
</body>
</html>
I'm sorry for asking a question that I'm sure is simple but I'm stuck. I have a project that requires the user to select 3 notes, the value for each should populate in the text box until the 3rd is entered. After that a compare is done to an array and a notification sent to the user letting them know if they have made a valid selection or not.
The problem I'm having is getting all 3 to populate, each time I click a button it overwrites the existing value. I've tried to push them to an array but it only contains the current value, I've tried a loop but that populates the selection 3x. I'm sure I'm overlooking something simple but have not been able to figure out what it is. Can someone point me in the right direction?
Thanks!
<!doctype html>
<html>
<head>
<title> Scope </title>
<meta charset="utf-8">
<style>
html {
height: 100%;
}
body {
height: 100%;
margin: 0px;
font-family: Helvetica, sans-serif;
}
div#container {
margin: auto;
width: 300px;
}
form {
margin-top: 20%;
}
form input[type="text"] {
font-size: 120%;
text-align: center;
}
form input[type="button"] {
background-color: lightblue;
font-size: 110%;
}
</style>
<script>
function addNote(event) {
var validChords = {
C: "CEG",
F: "FAC",
G: "GBD"
};
var note = event.target.value;
console.log(note);
var getNotes = [];
var noteDisplay = document.getElementById("notesDisplay");
var displayMessage = document.getElementById("message");
getNotes.push(note);
console.log(getNotes);
noteDisplay.value = getNotes;
noteDisplay.innterHTML = getNotes;
displayMessage.innterHTML = "Please Enter Antoher Note!";
//Code below is different things I've been playing with trying to
// figure this out.
// var success = false;
// if (notes.length > 0) {
// if (note) {
// for (var i =0; i < 3; i++) {
// if(notes[i] == note) {
// var found = true;
// getNotes.push(note);
// }
// }
// }
// }
// if (getNotes.length < 3) {
// }
}
window.onload = function() {
var notes = ["C", "D", "E", "F", "G", "A", "B"];
var cButton = document.getElementById("c");
cButton.onclick = addNote;
var dButton = document.getElementById("d");
dButton.onclick = addNote;
var eButton = document.getElementById("e");
eButton.onclick = addNote;
var fButton = document.getElementById("f");
fButton.onclick = addNote;
var gButton = document.getElementById("g");
gButton.onclick = addNote;
var aButton = document.getElementById("a");
aButton.onclick = addNote;
var bButton = document.getElementById("b");
bButton.onclick = addNote;
// your code here
}
</script>
</head>
<body>
<div id="container">
<form>
<p id="message">Enter a major triad chord:</p>
<p>
<input id="notesDisplay" type="text" size="21">
</p>
<p>
<input id="c" type="button" value="C">
<input id="d" type="button" value="D">
<input id="e" type="button" value="E">
<input id="f" type="button" value="F">
<input id="g" type="button" value="G">
<input id="a" type="button" value="A">
<input id="b" type="button" value="B">
</p>
</form>
</div>
</body>
</html>
I finally figured out how to get the entries and compare to the object containing specific values and return either a note or a message to try again. I'm almost there but am having an issue with my loops (I think). When a button is clicked a message is supposed to display saying "please enter another note" until the 3rd selection is made, when the first button is clicked I'm getting the "you have made an invalid selection message" and I don't understand why. The last piece I'm missing is the form is supposed to clear after either message is displayed. This is driving me nuts, can someone give me a hint as to what I still have wrong? Thanks!
Revised Code:
Scope
html {
height: 100%;
}
body {
height: 100%;
margin: 0px;
font-family: Helvetica, sans-serif;
}
div#container {
margin: auto;
width: 300px;
}
form {
margin-top: 20%;
}
form input[type="text"] {
font-size: 120%;
text-align: center;
}
form input[type="button"] {
background-color: lightblue;
font-size: 110%;
}
//Array to hold notes entered by user, counter to hold number of
//buttons clicked
var getNotes = [];
var counter = 0;
//addNote function, collects the notes entered by the user and displays
//them in the text box. When the number of notes entered equals 3 a
//compare is done to the validChords object. If the notes equal a valid
//chord a messages is displayed to the user telling them which chord was
//entered, if the chord is not correct a message is displayed telling
//them to try again. After either the form should be cleared.
function addNote(event) {
var validChords = {
C: "CEG",
F: "FAC",
G: "GBD"
};
var note = event.target.value;
var noteDisplay = document.getElementById("notesDisplay");
var displayMessage = document.getElementById("message");
if (counter <= 3) {
getNotes.push(note);
var removeComma = "";
for (i = getNotes.length-1; i >=0; i--) {
removeComma = getNotes[i]+removeComma;
}
noteDisplay.value = removeComma;
noteDisplay.innerHTML = removeComma;
displayMessage.innerHTML = "Please Enter Antoher Note!";
counter = counter+1;
}
if (counter == 3) {
for (var prop in validChords) {
if (removeComma === validChords[prop]) {
displayMessage.innerHTML = "You have entered a " + prop + "
Chord!";
notesDisplay.innterHTML = " ";
counter = 0;
}
}
} else {
displayMessage.innerHTML = "You have not entered a valid chord,
please try again!";
notesDisplay.innterHTML = " ";
counter = 0;
}
}
window.onload = function() {
var notes = ["C", "D", "E", "F", "G", "A", "B"];
var cButton = document.getElementById("c");
cButton.onclick = addNote;
var dButton = document.getElementById("d");
dButton.onclick = addNote;
var eButton = document.getElementById("e");
eButton.onclick = addNote;
var fButton = document.getElementById("f");
fButton.onclick = addNote;
var gButton = document.getElementById("g");
gButton.onclick = addNote;
var aButton = document.getElementById("a");
aButton.onclick = addNote;
var bButton = document.getElementById("b");
bButton.onclick = addNote;
}
</script>
</head>
<body>
<div id="container">
<form>
<p id="message">Enter a major triad chord:</p>
<p>
<input id="notesDisplay" type="text" size="21">
</p>
<p>
<input id="c" type="button" value="C">
<input id="d" type="button" value="D">
<input id="e" type="button" value="E">
<input id="f" type="button" value="F">
<input id="g" type="button" value="G">
<input id="a" type="button" value="A">
<input id="b" type="button" value="B">
</p>
</form>
</div>
</body>
</html>
I believe it's because you initialize getNote to an empty array every time you call the addNote function, check if that is the problem.
Thanks