Home > database >  HTML and JS basics, filling form after clicking submit button
HTML and JS basics, filling form after clicking submit button

Time:12-29

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 of document.getElementById (typo)
  • Using the click event handler on your submit button instead of the submit 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 oneventname 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>

  • Related