0

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 class="form-container">

<h2>Savings and Investments:</h2>

<div class="form-group">
    Non-Registered investments (Taxable):

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

        <span class="number-input">
            <span class="dollar-symbol">$</span>
            <input type="number" id="demo" class="submit-taxable" value=0>
        </span>
    </span>                                
</div>

<div class="form-group">
    Tax-free savings account (TFSA):

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

        <span class="number-input">
            <span class="dollar-symbol">$</span>
            <input type="number" id="demo" class="submit-tfsa" value=0 >
        </span>
    </span>

</div>

<div class="form-group">
    Registered Retirement Savings (ex: RRSP): 

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

        <span class="number-input">
            <span class="dollar-symbol">$</span>
            <input type="number" id="demo" class="submit-rrsp" value=0>
        </span>
    </span>

</div>

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

        <span class="number-input">
            <span class="dollar-symbol">$</span>
            <input type="number" id="demo" class="submit-investment-other" 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;
}
Justin P
  • 1
  • 2

2 Answers2

0

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 class="form-container">

<h2>Savings and Investments:</h2>

<div class="form-group">
    Non-Registered investments (Taxable):

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

        <span class="number-input">
            <span class="dollar-symbol">$</span>
            <input type="number" id="demo" class="submit-taxable" value=0>
        </span>
    </span>                                
</div>

<div class="form-group">
    Tax-free savings account (TFSA):

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

        <span class="number-input">
            <span class="dollar-symbol">$</span>
            <input type="number" id="demo" class="submit-tfsa" value=0 >
        </span>
    </span>

</div>

<div class="form-group">
    Registered Retirement Savings (ex: RRSP): 

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

        <span class="number-input">
            <span class="dollar-symbol">$</span>
            <input type="number" id="demo" class="submit-rrsp" value=0>
        </span>
    </span>

</div>

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

        <span class="number-input">
            <span class="dollar-symbol">$</span>
            <input type="number" id="demo" class="submit-investment-other" value=0>
        </span>
    </span>
</div>
Bravo
  • 6,022
  • 1
  • 10
  • 15
0

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/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
  <style></style>
</head>

<body>
  <form id='finance' class='container'>
    <fieldset class="border p-2 row">
      <legend class="float-none w-auto">Savings and Investments:</legend>

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

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

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

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

    </fieldset>
  </form>

</body>

</html>
zer00ne
  • 41,936
  • 6
  • 41
  • 68