Reputation: 39
I am trying to convert a Python script into an HTML/Javascript web based converter. The script is very simple and I followed the steps at https://www.w3schools.com/howto/howto_js_length_converter.asp, which work great, if all fields are dynamic. In my case, I need one variable to not change. On an example: user provides the "AssayWeight" value and one of the following: PPM or Grav. After that, scripts calculates the other value from PPM/Grav that the user didn't provide. Here's the code I have so far:
<script>
function ppmtoGravConverter(source,valNum) {
valNum = parseFloat(valNum);
var inputPPMtoGrav = document.getElementById("inputPPMtoGrav");
var inputAssayWeight = document.getElementById("inputAssayWeight");
var inputGravtoPPM = document.getElementById("inputGravtoPPM");
if (source=="inputPPMtoGrav") {
inputGravtoPPM.value=(valNum*inputAssayWeight/1000).toFixed(4);
}
if (source=="inputGravtoPPM") {
inputPPMtoGrav.value=(valNum*1000/inputAssayWeight).toFixed(4);
}
}
</script>
and html from w3schools:
<label>Assay Weight</label>
<input id="inputAssayWeight" type="number" placeholder="Assay Weight" oninput="ppmtoGravConverter(this.id,this.value)" onchange="ppmtoGravConverter(this.id,this.value)">
<br><br>
<label>PPM</label>
<input id="inputPPMtoGrav" type="number" placeholder="PPM" oninput="ppmtoGravConverter(this.id,this.value)" onchange="ppmtoGravConverter(this.id,this.value)">
<label>Grav (mg)</label>
<input id="inputGravtoPPM" type="number" placeholder="Grav (mg)" oninput="ppmtoGravConverter(this.id,this.value)" onchange="ppmtoGravConverter(this.id,this.value)">
Please let me know what am I missing. This is my 2nd day looking at Javascript. Thanks!
Upvotes: 0
Views: 528
Reputation: 43880
Wrap everything in a <form>
tag and give it an #id.
<form id='main'><!-- EVERYTHING --></form>
Bind "input"
event to the <form>
and call an event handler (i.e. a function to handle a triggered event). Refer to: JavaScript Event Handling
document.forms.main.oninput = inputHandler;
Define function inputHandler()
-- remember to pass the Event Object
function inputHandler(event) {...
Define all variables -- refer to: Obtaining References to Forms and Form Elements in JavaScript
// Collect all form controls into a NodeList
const field = this.elements;
// Find the element user interacted with
const input = event.target;
// Reference any form control by #id or [name] attribute by prefixing it with `field`
const aW = field.assayWeight;
// Assign a variable to form control values and convert them into a real Number
let AWT = parseFloat(aW.value);
Delegate "input"
event by using if/else
flow control statements. By explicitly allowing specific elements to react to an event and implicitly preventing other elements by simple omission is an important part of a programming paradigm called Event Delegation.
if (input.matches('#assayWeight')) {...
The HTML/CSS layout and styling features a toggling system in which it allows the user to enter "assay weight" and either "PPM" or "Grav". Hover over the titles and then click one and then the other to see the toggling. Refer to: Exposing Form Fields Via Checked Radio Buttons
[name=conv],
.mask {
display: none
}
[name=conv]:checked + fieldset .mask {
display: inline-block;
}
document.forms.convPpmG.oninput = convert;
function convert(event) {
const field = this.elements;
const input = event.target;
const awt = field.aWt;
const ppm = field.pPM;
const grv = field.grv;
const gtp = field.gToP;
const ptg = field.pToG;
let AWT = parseFloat(awt.value);
let PPMin = parseFloat(ppm.value);
let GRVin = parseFloat(grv.value);
if (input.matches('#aWt')) {
// log(AWT, "Assay Weight");
}
if (input.matches('#pPM')) {
// log(PPMin, "PPM Input");
let GRVout = PPMin * AWT / 1000;
// log(GRVout, "Grav Output");
ptg.value = GRVout.toFixed(4);
}
if (input.matches('#grv')) {
// log(GRVin, "Grav Input");
let PPMout = GRVin * 1000 / AWT;
// log(PPMout, "PPM Output");
gtp.value = PPMout.toFixed(4);
}
}
// A utility logger - not required
const log = (data, key = 'Field') => console.log(JSON.stringify(key + ': ' + data));
root,
body {
font: 400 3vw/1.5 Consolas, monospace;
}
fieldset fieldset {
min-height: 20vh;
}
input,
output {
width: 10ch;
margin-right: 5px;
margin-bottom: 8px;
font: inherit;
text-align: right;
}
#aWt {
display: inline-block;
}
[type=reset] {
text-align: center;
}
.switch {
padding: 3px 5px;
}
[type=reset]:hover,
.switch:hover {
color: tomato;
background: rgba(56, 87, 199, 0.4);
cursor: pointer;
}
[name=conv],
.mask {
display: none
}
[name=conv]:checked+fieldset .mask {
display: inline-block;
}
<form id='convPpmG'>
<fieldset>
<legend>PPM / Grav Convertor</legend>
<label>Assay Weight</label>
<input id="aWt" type="number" min='0' value="0">
<input type='reset'>
<br>
<input id='ppmToGrav' name='conv' type='radio'>
<fieldset>
<legend>
<label for='ppmToGrav' class='switch'>PPM to Grav</label>
</legend>
<label class='mask'>
PPM: <input id="pPM" type="number" min='0' value="0">
to Grav: <output id='pToG'>0</output> mg
</label>
</fieldset>
<hr>
<input id='gravToPPM' name='conv' type='radio'>
<fieldset>
<legend>
<label for='gravToPPM' class='switch'>Grav to PPM</label>
</legend>
<label class='mask'>
Grav: <input id="grv" type="number" min='0' value="0">
mg to PPM: <output id='gToP'>0</output>
</label>
</fieldset>
</fieldset>
</form>
Upvotes: 1
Reputation: 516
The issue is that in your formula, you are using inputAssayWeight
instead of actually taking its value and using it. Replace those two if
conditions with
if (source=="inputPPMtoGrav") {
inputGravtoPPM.value=(valNum*parseFloat(inputAssayWeight.value)/1000).toFixed(4);
}
if (source=="inputGravtoPPM") {
inputPPMtoGrav.value=(valNum*1000/parseFloat(inputAssayWeight.value)).toFixed(4);
}
That should fix your issue.
Upvotes: 1