First, I am not a professional. This is a personal project, so apologies if my terminology or POV of the issue is wrong. I’m working on a special kind of calculator that requires user input for the calculations. The calculator is made of several tables, but the first table is the most important one. It simply requires the user to divide a single "unit" into ratios that will be used throughout the rest of the calculator. These numbers must equal 100 or else the rest of the output will be incorrect.
I would like for the "TOTAL (%)" to have a function that checks that the number calculated in the textbox equals 100. If it doesn’t, I would like for the number to turn red along with a warning.
The issue I’m having is that the function doesn’t seem to be working. I’ve concluded that it could be one or more of the following reasons:
- The function simply doesn’t work as written.
- The function isn’t being triggered on the right element.
- The function isn’t being triggered by the right event.
Here’s the code that I’ve written:
function valTotal() {
var x = document.getElementById('t1total').value;
var y = 100;
if (x > y) {
alert("Warning! Your total is greater than 100%. Please adjust your ratios above so that the total equals 100% before continuing.");
x.style.color = "#cf0911";
return false;
}
}
function myFun0() {
let water = document.getElementById('t1water').value;
let ingr1 = document.getElementById('t1ingr1').value;
let ingr2 = document.getElementById('t1ingr2').value;
let ingr3 = document.getElementById('t1ingr3').value;
let ingr4 = document.getElementById('t1ingr4').value;
let ingr5 = document.getElementById('t1ingr5').value;
let ingr6 = document.getElementById('t1ingr6').value;
let total = Number(water) + Number(ingr1) + Number(ingr2) + Number(ingr3) + Number(ingr4) + Number(ingr5) + Number(ingr6);
document.getElementById("t1total").value = total;
}
body {
font-family: monospace;
}
table,
td {
border: 1px solid black;
border-collapse: collapse;
}
.invis {
border-style: hidden;
}
.txcenter {
text-align: center;
}
.txbox1 {
width: 50px;
}
<!DOCTYPE html>
<html>
<head>
</head>
<!--Calculator-->
<body>
<div>
<h2 id="calc">Substrate Calculator</h2>
<table class="invis">
<tr>
<td>
<!--Table 1: SUB RATIO-->
<table style="float: left">
<tr style="background-color:#751e0b">
<td colspan="2">
<div class="txcenter">
<b style="color:white">SUB RATIO</b>
</div>
</td>
</tr>
<!--Table 1: SUB RATIO > Water (%)-->
<tr>
<td>
<div>Water (%)</div>
</td>
<td>
<input class="txbox1" type="textbox" id="t1water" onkeyup="myFun0();myFun1();myFun2()" onchange="myFun0();myFun1();myFun2()">
</td>
</tr>
<!--Table 1: SUB RATIO > Ingredient 1 (%)-->
<tr>
<td>
<div>Ingredient 1 (%)</div>
</td>
<td>
<input class="txbox1" type="textbox" id="t1ingr1" onkeyup="myFun0();myFun1();myFun2()" onchange="myFun0();myFun1();myFun2()">
</td>
</tr>
<!--Table 1: SUB RATIO > Ingredient 2 (%)-->
<tr>
<td>
<div>Ingredient 2 (%)</div>
</td>
<td>
<input class="txbox1" type="textbox" id="t1ingr2" onkeyup="myFun0();myFun1();myFun2()" onchange="myFun0();myFun1();myFun2()">
</td>
</tr>
<!--Table 1: SUB RATIO > Ingredient 3 (%)-->
<tr>
<td>
<div>Ingredient 3 (%)</div>
</td>
<td>
<input class="txbox1" type="textbox" id="t1ingr3" onkeyup="myFun0();myFun1();myFun2()" onchange="myFun0();myFun1();myFun2()">
</td>
</tr>
<!--Table 1: SUB RATIO > Ingredient 4 (%)-->
<tr>
<td>
<div>Ingredient 4 (%)</div>
</td>
<td>
<input class="txbox1" type="textbox" id="t1ingr4" onkeyup="myFun0();myFun1();myFun2()" onchange="myFun0();myFun1();myFun2()">
</td>
</tr>
<!--Table 1: SUB RATIO > Ingredient 5 (%)-->
<tr>
<td>
<div>Ingredient 5 (%)</div>
</td>
<td>
<input class="txbox1" type="textbox" id="t1ingr5" onkeyup="myFun0();myFun1();myFun2()" onchange="myFun0();myFun1();myFun2()">
</td>
</tr>
<!--Table 1: SUB RATIO > Ingredient 6 (%)-->
<tr>
<td>
<div>Ingredient 6 (%)</div>
</td>
<td>
<input class="txbox1" type="textbox" id="t1ingr6" onkeyup="myFun0();myFun1();myFun2()" onchange="myFun0();myFun1();myFun2()">
</td>
</tr>
<!--Table 1: SUB RATIO > TOTAL (%)-->
<tr>
<td>
<div>TOTAL (%)</div>
</td>
<td>
<input class="txbox1" type="textbox" id="t1total" onchange="valTotal()" readonly>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</body>
</html>
is just the first table of the calculator. The issue I’m having is with the "TOTAL (%)" field which is the only place where the validation function will be used.
Many many thanks.
EDIT: The function in question is the valTotal() function.
3
Answers
In your code there are some error.
Inside function valTotal
var x = document.getElementById('t1total');
with this line you are getting the element itself not its value. So to encounter that at the end you should dovar x = document.getElementById('t1total').value;
and that is the reason the validation is not working properly. in future doconsole.log
to check if the value you want is that you are getting or not.In the if statement you are changing the color of x also so make an else statement to revert it back also
if (x > y) { alert("Warning! Your total is greater than 100%. Please adjust your ratios above so that the total equals 100% before continuing."); x.style.color = "#cf0911"; return false;
}else { document.getElementById('t1total').style.color = ""; // Reset color if valid }
If you had previously set a color (e.g., red for an error state), this will reset it back to the default.
IN the function myFun0 call valTotal function so before entering the next ingredient you could get if it exceed the 100%.
function myFun0(){
// rest of the code
valTotal()
}
Now in html in the input
type = "textbox"
there is no such thing usetype = "text"
or instead of that usenumber
and on all the input you are callingonkeyup="myFun0();myFun1();myFun2()" onchange="myFun0();myFun1();myFun2()"
so first of all both
onkeyup
andonchange
are doing the same thing calling the same function so you can just use one of then and also you can read about them by this link onkeyup onchnage. the other function you are calling which are not even written in your code. just do<input class="txbox1" type="text" id="t1water" onkeyup="myFun0()">
for all the input.And on total no need to call
onchange = "valTotal()"
because on every keyup the total is being calculated.hoping this will be helpful to you.
I suggest something like this:
Edit: OP mentioned "…is just the first table of the calculator". The snippet now handles all tables identifiable with the data-attribute
data-calculate-total
Allow me to suggest some improvements to your code.
idea
to use inline event handlers. Use
addEventListener
to add handling.
input[type="number"]
for numeric input fields. It will give you a bit more control over the input. Aside:input[type="textbox"]
is a non existing type1.Or use a slider (
type="range"
as demonstrated in the snippet from mister JoJo’s answer)querySelectorAll
with a relevant css selector to retrieve the input elements to use for calculation of the total.1 But it worked! Yep, because browsers substitute the field with the default
type="text"
.With the above in mind, here is an example snippet. It uses event delegation for the handling. Note: for demo I’ve reduced the number of fields.