skip to Main Content

I want to make an input that can be changed by a slider and by manual input, just like a regular <input type="number">. It has to be the same input because of JavaScript.

For example, here is the code I wrote:

const mph_in = document.getElementById("mph");
const dec_in = document.getElementById("dec");
const t_in = document.getElementById("t");
const out = document.getElementById("out");

mph_in.addEventListener('input', main);
dec_in.addEventListener('input', main);
t_in.addEventListener('input', main);


console.log(mph);

function m2mi(metre){
    return metre/1609.344;

}

function main(){

    // mph = 75.0;
    // dec = 0.9;
    // t = 1.0;


    mph = parseFloat(mph_in.value);
    dec = parseFloat(dec_in.value);
    t = parseFloat(t_in.value);

    v = mph*(1609.344/3600);

    reaction = t * v;

    braking = (v*v)/(2*dec);

    s = reaction + braking;

    console.log("main loaded");
    console.log("reaction distance: "+reaction);

    out.innerHTML = "Reaction distance: "+m2mi(reaction)+" mi<br> Braking distance: "+m2mi(braking)+" mi <br> <b>Stopping distance: "+m2mi(s)+" mi </b>";

}

function test(){
    console.log(m2mi(2000));

    // console.log("v = "+v);
}
<!-- 
  Train speed [mph]: 
  <input type="number" name="mph" id="mph" placeholder="75" value="75">
  <br> 
-->

Train speed [mph]: 
<input type="range" id="mph" name="mph" min="0" max="125" value="75" oninput="this.nextElementSibling.value = this.value"/>
<output></output>

<br>

Deceleration [m/s<sup>2</sup>]: 
<input type="number" name="dec" id="dec" placeholder="0.9" value="0.9">

<br>

Reaction time [s]: <input type="number" name="t" id="t" placeholder="3" value="3">
<br>
    
<button onclick="main()">Calculate</button><br>
<button onclick="test()">Debug</button><br>
<span id="out" >[output]</span>

The code works as intended, except the fact that the speed can only be controlled by a slider (and I would want to make it controllable by manual input too, just like the other inputs) and the deceleration and reaction time also controllable by a slider (not only by manual input). Is there any way to do this?

2

Answers


  1. You can try this way:

    When you menual/slider input, the slider/menual input to auto update to the value.

    You can try a custom event, or try Vue’s v-modal(if you can use Vue). You can try change event.

    Login or Signup to reply.
  2. You can get current <input>‘s name & value in change event, then update other <input>‘s value which has same name.

    const inputs = document.querySelectorAll("input");
    const update = ({ target }) => {
      const { name, value } = target;
      document.querySelectorAll(`input[name="${name}"]`).forEach((input) => target !== input && (input.value = value));
    };
    inputs.forEach((input) => {
      input.addEventListener("change", (e) => {
        update(e);
        main();
      });
    });
    
    const mph_in = document.getElementById("mph");
    const dec_in = document.getElementById("dec");
    const t_in = document.getElementById("t");
    const out = document.getElementById("out");
    
    function m2mi(metre) {
      return metre / 1609.344;
    }
    
    function main() {
      // mph = 75.0;
      // dec = 0.9;
      // t = 1.0;
      mph = parseFloat(mph_in.value);
      dec = parseFloat(dec_in.value);
      t = parseFloat(t_in.value);
    
      v = mph * (1609.344 / 3600);
    
      reaction = t * v;
    
      braking = (v * v) / (2 * dec);
    
      s = reaction + braking;
    
      console.log("main loaded");
      console.log("reaction distance: " + reaction);
    
      out.innerHTML = "Reaction distance: " + m2mi(reaction) + " mi<br> Braking distance: " + m2mi(braking) + " mi <br> <b>Stopping distance: " + m2mi(s) + " mi </b>";
    }
    
    function test() {
      console.log(m2mi(2000));
      // console.log("v = "+v);
    }
    
    const inputs = document.querySelectorAll("input");
    const update = ({
      target
    }) => {
      const {
        name,
        value
      } = target;
      document.querySelectorAll(`input[name="${name}"]`).forEach((input) => target !== input && (input.value = value));
    };
    inputs.forEach((input) => {
      input.addEventListener("change", (e) => {
        update(e);
        main();
      });
    });
    Train speed [mph]:<input type="number" id="mph" name="mph" min="0" max="125" value="75" placeholder="75">
    <br> Train speed [mph]:<input type="range" id="mph-range" name="mph" min="0" max="125" value="75" />
    <output></output>
    <br> Deceleration [m/s<sup>2</sup>]:
    <input type="number" name="dec" id="dec" placeholder="0.9" value="0.9">
    <br> Reaction time [s]: <input type="number" name="t" id="t" placeholder="3" value="3">
    <br>
    <button onclick="main()">Calculate</button><br>
    <button onclick="test()">Debug</button><br>
    <span id="out">[output]</span>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search