I would like to calculate the time it takes light to travel a given number of kilometers in a vacuum. I have the form with some inputs and submit button and I want the calculated time in JS script and display results in the Result [min] and Result [h] fields in the form, after clicking the submit button, but it isn't working. What can be wrong here?
This is my form:
<div >
<p>This is a calculator that allows you to calculate the time it takes light to travel a given number of kilometers in a vacuum.</p>
</div>
<form >
<label for="km_count">Enter number</label>
<input type="number" id="km_count" name="km_count">
<label for="km_count">[km]</label>
<br> <br>
<label for="result_min">Result: </label>
<input type="text" id="result_min" name="result_min" disabled>
<label for="result_min">[min] </label>
<br> <br>
<label for="result_h">Result: </label>
<input type="text" id="result_h" name="result_h" disabled>
<label for="result_h">[h] </label>
<br> <br>
<input type="submit" value="Submit" onclick="results()"> <input type="reset" value="Reset">
</form>
and my scrpit placed just before body closing tag:
<script>
function results(){
var km_count = document.getElementByID("km_count").value;
var result_1 = km_count / 300 000 / 60;
var result_2 = km_count / 300 000 / 3600;
document.getElementById("result_min").innerHTML = result_1;
document.getElementById("result_h").innerHTML = result_2;
}
</script>
CodePudding user response:
You're using a "submit" button each click/submit will reload the page, in your case, you need to prevent default behavior (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
Also, I recommend you to use addEventlistner (https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener)
here is a quick fix for your code:
<form onsubmit="return results(event)">
<label for="km_count">Enter number</label>
<input type="number" id="km_count" name="km_count">
<label for="km_count">[km]</label>
<br> <br>
<label for="result_min">Result: </label>
<input type="text" id="result_min" name="result_min" disabled>
<label for="result_min">[min] </label>
<br> <br>
<label for="result_h">Result: </label>
<input type="text" id="result_h" name="result_h" disabled>
<label for="result_h">[h] </label>
<br> <br>
<input type="submit" value="Submit"> <input type="reset" value="Reset">
</form>
<script>
function results(event){
event.preventDefault();
var km_count = document.getElementById("km_count").value;
var result_1 = km_count / 300000 / 60;
var result_2 = km_count / 300000 / 3600;
document.getElementById("result_min").value = result_1;
document.getElementById("result_h").value = result_2;
}
</script>
CodePudding user response:
You had the following problems in your code:
- Using
document.getElementByID
instead ofdocument.getElementById
(typo) - Using the
click
event handler on your submit button instead of thesubmit
event on the form (more appropriate) - Not using
event.preventDefault()
in your event handler, so that the browser won't propagate the event and won't fulfill its part of the game actually performing a new http request - You were setting the inputs content with
.innerHTML
instead of using the more appropriate in this case.value
like you already did with the input
In addition to that, as already suggested by some other comments, it would be more appropriate to add the event handler using .addEventListener
instead of dealing with the on
eventname attribute on html doing the binding in another realm.
In this snippet below I also kept the logic to calculate the distance traveled in a separate function getTimeSpent(km, speed)
that will be general, relative to the speed that now it's required to be passed from the caller.
Since the speed parameter was generalized, I put it inside the data-speed
attribute of the input element for the distance (km). Anyway if it won't be set, the lightspeed
value (defined apart as a constant in the global scope) will be used.
The caller is just a mere event handler with the knowledge of the html elements for input and output and of the function to calculate the distance traveled.
The maths for calculating the distance was better factored to avoid the repeating of the same operation multiple times.
document.querySelector('form.light_forms')
.addEventListener('submit', event => {
const inputKM = document.getElementById("km_count");
const distanceKM = parseFloat(inputKM.value);
//the speed gets fetched from the data-speed attribute if it's present,
//otherwise it's the constant lightspeed set in the higher scope
const speedKMperS =
(inputKM.hasAttribute("data-speed")) ?
parseFloat(inputKM.dataset.speed) : lightspeed;
const time = getTimeSpent(distanceKM, speedKMperS);
document.getElementById("result_min").value = time.minutes;
document.getElementById("result_h").value = time.hours;
event.preventDefault();
});
const lightspeed = 300000;
function getTimeSpent(km, speed) {
const seconds = km / speed;
const minutes = seconds / 60;
const hours = minutes / 60;
return {
hours: hours,
minutes: minutes,
seconds: seconds
};
}
<div >
<p>This is a calculator that allows you to calculate the time it takes light to travel a given number of kilometers in a vacuum.</p>
</div>
<form >
<label for="km_count">Enter number</label>
<input type="number" id="km_count" name="km_count" data-speed="300000">
<label for="km_count">[km]</label>
<br><br>
<label for="result_min">Result: </label>
<input type="text" id="result_min" name="result_min" disabled>
<label for="result_min">[min] </label>
<br><br>
<label for="result_h">Result: </label>
<input type="text" id="result_h" name="result_h" disabled>
<label for="result_h">[h] </label>
<br><br>
<input type="submit" value="Submit" onsubmit="results()">
<input type="reset" value="Reset">
</form>