Home > Software design >  Dynamically update unique number input field with multiple slider range inputs (Javascript)
Dynamically update unique number input field with multiple slider range inputs (Javascript)

Time:06-30

I have multiple fields in a form that each have a input range slider and a number input. I would like to update the individual number input field based on the range slider value. I was able to make this work for the first field with slider/number, but can't seem to make it work with the others. I would like to avoid having to write code for each form field, ideally would have this work dynamically.

Image of form fields (can only update the first)

HTML:

<div >

<h2>Savings and Investments:</h2>

<div >
    Non-Registered investments (Taxable):

    <span >
        <input type="range"  min="0" max="5000000" step="5000" value="0" id="customRange">

        <span >
            <span >$</span>
            <input type="number" id="demo"  value=0>
        </span>
    </span>                                
</div>

<div >
    Tax-free savings account (TFSA):

    <span >
        <input type="range"  min="0" max="5000000" step="5000" value="0" id="customRange">

        <span >
            <span >$</span>
            <input type="number" id="demo"  value=0 >
        </span>
    </span>

</div>

<div >
    Registered Retirement Savings (ex: RRSP): 

    <span >
        <input type="range"  min="0" max="5000000" step="5000" value="0" id="customRange">

        <span >
            <span >$</span>
            <input type="number" id="demo"  value=0>
        </span>
    </span>

</div>

<div >
    Other: 
    <span >
        <input type="range"  min="0" max="5000000" step="5000" value="0" id="customRange">

        <span >
            <span >$</span>
            <input type="number" id="demo"  value=0>
        </span>
    </span>
</div>

Javascript:

var slider = document.getElementById("customRange");

var output = document.getElementById("demo");

output.innerHTML = slider.value; // Display the default slider value

// Update the current slider value (each time you drag the slider handle)
slider.oninput = function() {
output.value = this.value;
}

CodePudding user response:

your first issue is id="customRange and id="demo" ... multiple times ... how can document.getElementById("customRange") know which one you want? It doesn't, it gets the first

So, do it like this, no need for the id's now (I left them in because I'm too lazy to edit them out)

document.querySelectorAll(".form-group").forEach(range => {
  const slider = range.querySelector('input[type=range]');
  const output = range.querySelector('.number-input input');
  output.innerHTML = slider.value; // Display the default slider value
  slider.addEventListener('input', () => {
    output.value = slider.value;
  });
});
<div >

<h2>Savings and Investments:</h2>

<div >
    Non-Registered investments (Taxable):

    <span >
        <input type="range"  min="0" max="5000000" step="5000" value="0" id="customRange">

        <span >
            <span >$</span>
            <input type="number" id="demo"  value=0>
        </span>
    </span>                                
</div>

<div >
    Tax-free savings account (TFSA):

    <span >
        <input type="range"  min="0" max="5000000" step="5000" value="0" id="customRange">

        <span >
            <span >$</span>
            <input type="number" id="demo"  value=0 >
        </span>
    </span>

</div>

<div >
    Registered Retirement Savings (ex: RRSP): 

    <span >
        <input type="range"  min="0" max="5000000" step="5000" value="0" id="customRange">

        <span >
            <span >$</span>
            <input type="number" id="demo"  value=0>
        </span>
    </span>

</div>

<div >
    Other: 
    <span >
        <input type="range"  min="0" max="5000000" step="5000" value="0" id="customRange">

        <span >
            <span >$</span>
            <input type="number" id="demo"  value=0>
        </span>
    </span>
</div>

CodePudding user response:

I'm guessing that the OP has Bootstrap loaded, so I included Bootstrap 5. If a page has more than one Form Control, always wrap everything in a <form>. Each <input type='number'> has been replaced with an <output>. The terse syntax is from the HTMLFormElement interface.

One important thing concerning OP code. Do not duplicate ids, they must be unique, there's 4 id="demo".

Details are commented in example

// Bind the "input" event to <form>
document.forms.finance.oninput = calcRange;

/*
Event handler passes Event Object by default
Reference the tag the user has interacted with
Reference all form controls
*/
/*
If the user interacted with a .form-range...
...reference the <output> that is associated with >data<...
...assign the value of >data< to associated <output>
*/
function calcRange(e) {
  const data = e.target;
  const IO = this.elements;

  if (data.matches('.form-range')) {
    const view = IO[`${data.id}-view`];
    view.value = data.value;
  }
}
<!DOCTYPE html>
<html lang="en">

<head>
  <title></title>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
  <style></style>
</head>

<body>
  <form id='finance' class='container'>
    <fieldset >
      <legend >Savings and Investments:</legend>

      <label for='taxable' >Non-Registered Investments (Taxable):</label>
      <div class='col-7 mt-2'>
        <input id='taxable'  type="range" min="0" max="5000000" step="5000" value="0">
      </div>
      <div class='col-5'>
        <div >
          <b >$</b>
          <output for='taxable' id='taxable-view' >0</output>
          <b >.00</b>
        </div>
      </div>

      <label for='tfsa' >Tax-Free Savings Account (TFSA):</label>
      <div class='col-7 mt-2'>
        <input id='tfsa'  type="range" min="0" max="5000000" step="5000" value="0">
      </div>
      <div class='col-5'>
        <div >
          <b >$</b>
          <output for='tfsa' id='tfsa-view' >0</output>
          <b >.00</b>
        </div>
      </div>

      <label for='rrsp' >Registered Retirement Savings Plan (RRSP):</label>
      <div class='col-7 mt-2'>
        <input id='rrsp'  type="range" min="0" max="5000000" step="5000" value="0">
      </div>
      <div class='col-5'>
        <div >
          <b >$</b>
          <output for='rrsp' id='rrsp-view' >0</output>
          <b >.00</b>
        </div>
      </div>

      <label for='other' >Other Investment Assets:</label>
      <div class='col-7 mt-2'>
        <input id='other'  type="range" min="0" max="5000000" step="5000" value="0">
      </div>
      <div class='col-5'>
        <div >
          <b >$</b>
          <output for='other' id='other-view' >0</output>
          <b >.00</b>
        </div>
      </div>

    </fieldset>
  </form>

</body>

</html>

  • Related