Javascript: Real time calculations in a form - javascript

Using JavaScript I am working on a form that calculates in real time someone's BMI and TBW based on weight and height inputs.
I am using a addEventListener and onkeyup. I am very new to JavaScript, so bear with me.
What am I doing wrong?
Update: I have followed advice and replaced the "onkeyup" event with "oninput", and have put the height and weight values within the functions. I have also added .value. I am still have issues though.
<body>
<form id="adime-form" name="adime" method="post">
<div class="three-column clear">
<label for="">Age</label>
<input type="number" name="age" id="age"> <!--Input-->
</div>
<div class="three-column">
<label for="">Sex</label>
<input type="text" name="sex" id="sex"><!--Input-->
</div>
<div class="three-column">
<label for="">Height</label>
<input type="number" name="height" id="height"><!--Input-->
</div>
<div class="three-column">
<label for="">Weight</label>
<input type="number" name="weight" id="weight"><!--Input-->
</div>
<div class="three-column">
<label for="">BMI</label>
<input type="text" name="bmi" id="bmi" oninput="returnBmi"><!--Output-->
</div>
<div class="three-column">
<label for="">Total Body Water</label>
<input type="text" name="tbw-perc" id="tbw-perc" oninput="returnTbw"><!--Output-->
</div>
</form>
<script>
var getAge = document.getElementById("age");
var getSex = document.getElementById("sex");
document.getElementById("bmi").addEventListener("input", returnBmi);
document.getElementById("tbw-perc").addEventListener("input", returnTbw);
function returnBmi(){
var getHeight = document.getElementById("height").value;
var getWeight = document.getElementById("weight").value;
var getBmi = getWeight / (getHeight**2) * 703;
document.getElementById("bmi").innerHTML = getBMI;
}
function returnTbw(){
var getHeight = document.getElementById("height").value;
var getWeight = document.getElementById("weight").value;
var getTbw = -2.097 + 0.1069 *( getHeight * 2.54) + 0.2466 * (getWeight * .45);
document.getElementById("tbw-perc").innerHTML = getTbw;
}
</script>
enter code here

Consider using the 'input' event on the inputs: document.getElementById("bmi").addEventListener("input", returnBmi);
Also, take the Weight and Height values, INSIDE the update function:
function returnBmi(){
var getHeight = document.getElementById("height").value;
var getWeight = document.getElementById("weight").value;
var getBmi = getWeight / (getHeight**2) * 703;
document.getElementById("bmi").innerHTML = getBMI;
}
As you need to extract the values when the event is triggered.

Related

How to clear an input of type number when a button is clicked

I am making a mortgage calculator and am trying to clear all the inputs when the clear button is presses. I can't seem to get it to work. Below is my html and JavaScript code, I have also tried setting the inputs = null and that didn't work.
HTML:
<div class="calculator">
<h1>Mortgage Calculator</h1>
<div class="input-container">
<label for="Loan-amount">Total Loan Amount</label>
<input type="number" name="Loan-amount" id="total" min="0">
</div>
<div class="input-container">
<label for="down-payment">Down payment</label>
<input type="number" name="Loan-amount" id="down" min="0">
</div>
<div class="input-container">
<label for="interest-rate">Interest rate %</label>
<input type="number" name="interest-rate" id="interest" min="0">
</div>
<div class="input-container">
<label for="loan-term">Loan Term (in years)</label>
<input type="number" name="loan-term" id="duration" min="0">
</div>
<div class="answer">
<h2>Estimated payment:</h2>
<p id="paragraph-value"></p>
</div>
<div class="button-container">
<button id="submitBtn">Calculate</button>
<button id="clearBtn">Clear</button>
</div>
<p id="alert"></p>
</div>
JavaScript:
const clearBtn = document.querySelector("#clearBtn");
clearBtn.addEventListener("click", function (e) {
let total = document.getElementById("total").value;
let interest = document.querySelector("#interest").value;
let duration = document.querySelector("#duration").value;
let downPayment = document.querySelector("#down").value;
total = "";
interest = "";
duration = "";
downPayment = "";
});
You're not setting a value to the inputs, you're just over-writing the value of a varable:
total = "";
To set the value of the input, you'd set the .value property on the input:
document.getElementById("total").value = "";
For example:
const clearBtn = document.querySelector("#clearBtn");
clearBtn.addEventListener("click", function (e) {
document.getElementById("total").value = "";
});
<input type="number" id="total" />
<button id="clearBtn">Reset</button>
At a more generic level, you seem to be confused about the difference between these two things:
var total = document.getElementById("total").value;
total = "";
and:
var total = document.getElementById("total");
total.value = "";
In the first case the variable holds a copy of the value itself, and you're re-assigning the variable to a new value. This does nothing to the element.
But in the second case the variable holds a reference to the element, and you're updating a property on that element.

I cannot get the javaScript to do the function i am requesting it to do, in my case multiply two values by a hidden and then add a final value

I am so lost as to why this is not working properly, as it is on similar previous code. This is for field personnel, a cheat Sheet to simply enter values and get a fast answer (calculation). They enter the value of Num5/6/7 code multiplies 3 values one hidden then adds the last value together and upon click button the result is shown.
Here is my code (taken from copy/paste of a working conversion).
<div class="containerHydro">
<p>
<label >Fluid Column Length</label>
<input type="number" id="num5">
<label >Fluid Weight</label>
<input type="number" id="num6">
<label >Well Head Pressure</label>
<input type="number" id="num7">
<p>
<input type="button" value="Sum" onclick="calculate()"/>
</p>
<p id="total1"></p>
</div>
The Function also copy/paste of multiply two int then divide by hidden (which works BTW)
function calculate() {
var numFive = document.getElementById('num5').value;
var numSix = document.getElementById('num6').value;
var numSvn = document.getElementById('num7').value;
var total1 = parseInt(numFive) * parseInt(numSix) * 0.052 + parseInt('numSvn');
var p =document.getElementById('total1');
p.innerHTML += total1;
}
Here is the same idea which works fine-
Code-
<div class="container7">
<p>
<label id="H2S Percent">H2S Percentage</label>
<input id="num3" type="number" name="num3" placeholder="H2S Percent">
<label id="H2S Percent">WHP</label>
<input id="num4" type="number" name="num4"placeholder="Well Head Pressure" > <br>
</p>
<input type="button" value="H2S Partial Pressure" onclick="math()"/>
<p id="result"></p>
</div>
Function
function math() {
var numThree = document.getElementById('num3').value;
var numFour = document.getElementById('num4').value;
var result = parseInt(numThree) * parseInt(numFour) / 1000000;
var p = document.getElementById('result');
p.innerHTML += result;
}
function calculate() {
var numFive = document.getElementById('num5').value;
var numSix = document.getElementById('num6').value;
var numSvn = document.getElementById('num7').value;
var total1 = parseInt(numFive) * parseInt(numSix) * 0.052 + parseInt(numSvn);
var p = document.getElementById('total1');
p.innerHTML += total1;
}
input {
display: block;
}
<div class="containerHydro">
<p>
<label>Fluid Column Length</label>
<input type="number" id="num5">
<label>Fluid Weight</label>
<input type="number" id="num6">
<label>Well Head Pressure</label>
<input type="number" id="num7">
<p>
<input type="button" value="Sum" onclick="calculate()" />
</p>
<p id="total1"></p>
</div>

Why document.getElementById().value returns a string even though its type is Number?

I am trying to make a tip calculator and the total variable returns a string because typeof bill is a string, why is it so, even though the text input box type is number?
output("bill entered is 1000 and no of person is 1):- string
150
150
1000150
document.querySelector('#persons').addEventListener('change', (findresult));
document.querySelector('#bill').addEventListener('change', (findresult));
document.querySelector('#percent').addEventListener('change', (findresult));
function findresult() {
var persons = document.getElementById('persons').value;
var bill = document.getElementById('bill').value;
var percent = document.getElementById('percent').value;
// console.log(persons);
console.log(typeof bill);
// console.log(percent);
var tip = (bill * percent) / 100;
var tip_person = tip / persons;
var total = bill + tip;
console.log(tip);
console.log(tip_person);
console.log(total);
}
<div class="container">
<h1>Tip calcuator</h1><br>
<div class="inputs">
<input type="number" class="inputfield" id="persons" placeholder="No of Persons"><br><br>
<input type="number" class="inputfield" id="bill" placeholder="Bill"><br><br>
<input type="number" class="inputfield" id="percent" placeholder="Tip%">
</div>
<br>
<div class="result">
<br>
<p>Tip Per Person :</p>
<p>TOTAL :</p>
</div>
</div>
Surround the bill, percent declaration values with parseFloat to allow for decimals while converting the value String to a Number.
var bill = parseFloat(document.getElementById('bill').value);
var percent = parseFloat(document.getElementById('percent').value);
You may allow decimals in the Number Input by using the step attribute and set it to 0.01. This will affect the values created when using the up,down button on the Input.
<input type="number" class="inputfield" id="bill" placeholder="Bill" step="0.01" >
document.querySelector('#persons').addEventListener('change', (findresult));
document.querySelector('#bill').addEventListener('change', (findresult));
document.querySelector('#percent').addEventListener('change', (findresult));
function findresult() {
var persons = document.getElementById('persons').value;
// Use parseFloat to allow for decimals
var bill = parseFloat(document.getElementById('bill').value);
var percent = parseFloat(document.getElementById('percent').value);
// console.log(persons);
console.log(typeof bill);
// console.log(percent);
var tip = (bill * percent) / 100;
var tip_person = tip / persons;
var total = bill + tip;
console.log(tip);
console.log(tip_person);
console.log(total);
}
<div class="container">
<h1>Tip calcuator</h1><br>
<div class="inputs">
<input type="number" class="inputfield" id="persons" placeholder="No of Persons"><br><br>
<!-- Allow cents to be allowed via the `step` attribute -->
<input type="number" class="inputfield" id="bill" placeholder="Bill" step="0.01" ><br><br>
<input type="number" class="inputfield" id="percent" placeholder="Tip%">
</div>
<br>
<div class="result">
<br>
<p>Tip Per Person :</p>
<p>TOTAL :</p>
</div>
</div>
User parseInt(), it will convert string into number.
function findresult() {
var persons = parseInt(document.getElementById('persons').value);
var bill = parseInt(document.getElementById('bill').value);
var percent = parseInt(document.getElementById('percent').value);
// console.log(persons);
console.log(bill);
// console.log(percent);
var tip = (bill * percent) / 100;
var tip_person = tip / persons;
var total = bill + tip;
console.log(tip);
console.log(tip_person);
console.log(total);
}
As mentioned by #Heretic Monkey, the input element has a property valueAsNumber and since the input type is always a number, we wouldn't have to worry about the parsing.
so we can use document.getElementById('persons').valueAsNumber
Also a few suggestions, it's always nice to break your code in smaller parts. Therefore separating the logic of fetching the input values and performing calculations separately will be a better approach and its not a good practice to call the DOM objects repeatedly.
For example, we can create a function for change event listener and read the event argument and update the necessary object of values,
document.querySelector('#persons').addEventListener('change', (update));
document.querySelector('#bill').addEventListener('change', (update));
document.querySelector('#percent').addEventListener('change', (update));
let values = {
persons: 0,
bill: 0,
percent: 0,
}
function update(event) {
values[event.currentTarget.id] = event.target.valueAsNumber;
findresult();
}
Finally, you can read the values as follows,
var persons = values["persons"];
var bill = values["bill"];
var percent = values["percent"];
So putting all together,
document.querySelector('#persons').addEventListener('change', (update));
document.querySelector('#bill').addEventListener('change', (update));
document.querySelector('#percent').addEventListener('change', (update));
let values = {
persons: 0,
bill: 0,
percent: 0,
}
function update(event) {
values[event.currentTarget.id] = event.target.valueAsNumber;
findresult();
}
function findresult() {
var persons = values["persons"];
var bill = values["bill"];
var percent = values["percent"];
var tip = (bill * percent) / 100;
var tip_person = tip / persons;
var total = bill + tip;
console.log(tip);
console.log(tip_person);
console.log(total);
}
<div class="container">
<h1>Tip calcuator</h1><br>
<div class="inputs">
<input type="number" class="inputfield" id="persons" placeholder="No of Persons" step="0.01"><br><br>
<input type="number" class="inputfield" id="bill" placeholder="Bill"><br><br>
<input type="number" class="inputfield" id="percent" placeholder="Tip%">
</div>
<br>
<div class="result">
<br>
<p>Tip Per Person :</p>
<p>TOTAL :</p>
</div>
</div>
Hope it helps.

how to sort list in array and display in sort into textboxes

This is the index.php
This Javascript is for random numbers and displays into 9 text boxes.
<script>
function GetRandom()
{
var myElement = document.getElementById("no1")
myElement.value = Math.floor((Math.random() * 1000) + 1);
var myElement = document.getElementById("no2")
myElement.value = Math.floor((Math.random() * 100) + 1);
var myElement = document.getElementById("no3")
myElement.value = Math.floor((Math.random() * 10000) + 1);
var myElement = document.getElementById("no4")
myElement.value = Math.floor((Math.random() * 1000) + 1);
var myElement = document.getElementById("no5")
myElement.value = Math.floor((Math.random() * 10000) + 1);
var myElement = document.getElementById("no6")
myElement.value = Math.floor((Math.random() * 1000) + 1);
var myElement = document.getElementById("no7")
myElement.value = Math.floor((Math.random() * 1000) + 1);
var myElement = document.getElementById("no8")
myElement.value = Math.floor((Math.random() * 1000) + 1);
var myElement = document.getElementById("no9")
myElement.value = Math.floor((Math.random() * 10000) + 1);
}
</script>
This javascript is take 9 text boxes value into array and sort list
<script>
function sortlist()
{
var captureNumb = document.getElementById("no1");
var captureNumb = document.getElementById("no2");
var captureNumb = document.getElementById("no3");
var captureNumb = document.getElementById("no4");
var captureNumb = document.getElementById("no5");
var captureNumb = document.getElementById("no6");
var captureNumb = document.getElementById("no7");
var captureNumb = document.getElementById("no8");
var captureNumb = document.getElementById("no9");
var captureNumb = document.getElementById("no1");
var numbers = captureNumb.value.split(" ");
captureNumb.value = numbers.sort(function (a, b) {
return a - b
}).join(" ");
}
</script>
</head>
<body>
<div class="form-inline">
<div class="col-xs-12">
<div class="form-group">
<input type="text" class="form-control" id="no1" name="no1" placeholder="No 1">
</div>
<div class="form-group">
<label for="exampleInputName2"></label>
<input type="text" class="form-control" id="no2" name="no2" placeholder="No 2">
</div>
<div class="form-group">
<label for="exampleInputName2"></label>
<input type="text" class="form-control" id="no3" name="no3" placeholder="No 3">
</div>
<div class="form-group">
<label for="exampleInputName2"></label>
<input type="text" class="form-control" id="no4" name="no4" placeholder="No 4">
</div>
<div class="form-group">
<label for="exampleInputName2"></label>
<input type="text" class="form-control" id="no5" name="no5" placeholder="No 5">
</div>
<div class="form-group">
<label for="exampleInputName2"></label>
<input type="text" class="form-control" id="no6" name="no6" placeholder="No 6">
</div>
<div class="form-group">
<label for="exampleInputName2"></label>
<input type="text" class="form-control" id="no7" name="no7" placeholder="No 7">
</div>
<div class="form-group">
<label for="exampleInputName2"></label>
<input type="text" class="form-control" id="no8" name="no8" placeholder="No 8">
</div>
<div class="form-group">
<label for="exampleInputName2"></label>
<input type="text" class="form-control" id="no9" name="no9" placeholder="No 9">
</div>
<br><br><br>
<div align="center">
<button type="button" class="btn btn-primary" onclick="GetRandom()">Populate</button>
<button type="button" class="btn btn-primary" onclick="sortlist()" >Sort list</button>
<button type="button" class="btn btn-primary">Primary</button>
</div>
</div>
</div>
How to click button sortlist and re-display follow by sort list?
tried to capture the value from 9 textboxes.
Your code need to be seriously looked at. You've got many repeated statements that could be solved with loops, and on every line where you redefine a variable, something like var myElement = ... two lines in a row, there is really no point in assigning it to a variable, as you never reference myElement and it's value is overridden on the next line.
In terms of what you're requesting regarding sorting, you need to dynamically insert them from some data structure.
<?php
$values = someGeneratingFunction();
$values = someSortFunction($values);
for($i=0;$i<count($values);$i++) {
echo "<input type=\"text\" class=\"form-control\" id=\"no" . $i . "\" name=\"no" . $i . "\" placeholder=\"No 1\">"
}
// Note the insertion of the ID values ("no1", "no2" etc.) using the loop instead of repeatedly typing the same thing.
?>
Keep in mind the above code doesn't use the entire HTML structure you've supplied, but you can use this as a general idea for how to achieve what you want. When you call a sort method, you can just re-run this code and it will just print all the elements in the array values in whatever order they've been put in.
EDIT
Consider the below JavaScript.
function sortList() {
var values = [];
for(i=1;i<10;i++) {
values.push(document.getElementById("no".concat(i)));
}
return values.sort( function(a,b) { return a-b } );
}
We initialize an array to hold all the elements identified by the IDs "no1", "no2" etc. Then we push them on, 1 by 1, in a for loop that accesses them all uses the indices (note this is what I was getting at, as this is better than repeating the same code 10 lines in a row, only altering a number.), and then we return our sorted array. Notice that we are passing a function as a parameter to when we call values.sort( function(a,b) { return a-b } ). This is because by default, the .sort() method sorts as strings, alphanumerically in ascending order. So the array [1, 3, 200, 15000] would be sorted as [1, 15000, 200, 3] which is quite clearly not in numeric order. By providing the additional function as a parameter, we tell it to subtract the two (it acts as our comparator) and then will provide us with accurate numeric results.

How do I prevent jQuery result to show up in two different forms?

How do I get two separate results using jQuery in these forms? I enter information in the first form and the answer shows up in the second.
HTML:
<div class="span12">
<div class="span4">
<div class="row-fluid exercise1 one_rep_calc_container">
<form>
<div class="span4">Weight<input class="weight" type="number" name="weight" size="2" ></div>
<div class="span4">Reps<input class="reps" type="number" name="reps" size="2" ></div>
<div class="span4">OneRepMax<input class="one_rep_max" type="number" Name="oneRepMax" size="2" ></div>
</form>
</div>
</div>
<div class="span4">
<div class="row-fluid exercise1 one_rep_calc_container">
<form>
<div class="span4">Weight<input class="weight" type="number" name="weight" size="2" ></div>
<div class="span4">Reps<input class="reps" type="number" name="reps" size="2" ></div>
<div class="span4">OneRepMax<input class="one_rep_max" type="number" Name="oneRepMax" size="2" ></div>
</form>
</div>
</div>
</div>
The class oneRepMax is the solution form why the results of weight and reps.
jQuery:
$('.one_rep_calc_container .weight, .one_rep_calc_container .reps').change(function(){
var weight = parseInt($('.one_rep_calc_container .weight').val(), 10 );
var reps = parseInt($('.one_rep_calc_container .reps').val(), 10);
if(weight > 0 && reps > 0){
var oneRepMaxVal = ((reps*weight)/30) + weight;
$('.one_rep_calc_container .one_rep_max').val(oneRepMaxVal);
} else {
$('.one_rep_calc_container .one_rep_max').val('');
}
});
$('.one_rep_calc_container .calc_one_rep_button').click(function(){
var weight = parseInt($('.one_rep_calc_container .weight').val(), 10 );
var reps = parseInt($('.one_rep_calc_container .reps').val(), 10);
var oneRepMaxVal = ((reps*weight)/30) + weight;
$('.one_rep_calc_container .one_rep_max').val(oneRepMaxVal);
});
So how do I keep the results from the first form of oneRepMax separate from the second one?
Try this:
$('.one_rep_calc_container .weight, .one_rep_calc_container .reps').change(function(){
var parent = $(this).parents('.one_rep_calc_container');
var weight = parseInt(parent.find('.weight').val(), 10 );
var reps = parseInt(parent.find('.reps').val(), 10);
if(weight > 0 && reps > 0){
var oneRepMaxVal = ((reps*weight)/30) + weight;
parent.find('.one_rep_max').val(oneRepMaxVal);
}
else {
parent.find('.one_rep_max').val('');
}
});
$('.one_rep_calc_container .calc_one_rep_button').click(function(){
var parent = $(this).parents('.one_rep_calc_container');
var weight = parseInt(parent.find('.weight').val(), 10 );
var reps = parseInt(parent.find('.reps').val(), 10);
var oneRepMaxVal = ((reps*weight)/30) + weight;
parent.find('.one_rep_max').val(oneRepMaxVal);
});
The idea is to get the parent of the current element. That parent is the context for all your operations afterwards, with that way, you work only with the elements that are children of the current parent.
You should give your inputs ids so you can refer specifically to each.
<input id="weight1" class="weight" type="number" name="weight" size="2" >
Then you can use
$('#weight1').val()
to refer to specific ones.
Fundamentally, you should understand that the jquery selectors select and operate as many elements that match the criteria you specify. Both of the forms have the same identifiers and so the Jquery calls the functions on both of them. As others have mentioned you need to differentiate the two forms such that Jquery only operates on the one you want it to.

Categories

Resources