user2970972
user2970972

Reputation: 93

Linking Event Handlers in forEach Loop Javascript NodeList

I'm trying to link the event of two input types in a NodeList. I'm able to link a single pair of inputs but once I add more pairs, I'm unable to link them. What am I doing wrong?

var range = document.querySelectorAll(".inputRange");
var field = document.querySelectorAll(".inputNumber");
// console.log(range);
// console.log(field);

range.forEach(input => {
  input.addEventListener("input", e => {
    // console.log("RANGE EVENT: " +e.type)
    field.value = e.target.value;
  });
});
field.forEach(input => {
  input.addEventListener("input", e => {
    range.value = e.target.value;
  });
});
<div class="card grd">
  <h4 class="r1">Recipe</h4>
  <p>Low</p>
  <h2 class="r2"><input class="inputNumber" id="num1" min="0" max="100" type="number" value="0.75" step=".01" maxlength="8" /></h2>
  <div class="sldcon">
    <input class="inputRange" id="range" type="range" min="0" max="100" value="0.75" step=".01" />
  </div>
  <p>Mid</p>
  <h2 class="r2"><input class="inputNumber" id="num1" min="0" max="100" type="number" value="35" step=".01" maxlength="8" /></h2>
  <div class="sldcon">
    <input class="inputRange" id="range" type="range" min="0" max="100" value="35" step=".01" />
  </div>
  <p>High</p>
  <h2 class="r2"><input class="inputNumber" id="num1" min="0" max="1000" type="number" value="40" step=".01" maxlength="8" /></h2>
  <div class="sldcon">
    <input class="inputRange" id="range" type="range" min="0" max="1000" value="40" step=".01" />
  </div>
</div>

Upvotes: 1

Views: 529

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370809

Iterate over only one of the collections, and inside the loop, get a reference to the linked input by navigating the nearby DOM, then add listeners to both:

document.querySelectorAll(".inputNumber").forEach((field) => {
  const range = field.parentElement.nextElementSibling.children[0];
  range.oninput = () => field.value = range.value;
  field.oninput = () => range.value = field.value;
});
<div class="card grd">
  <h4 class="r1">Recipe</h4>
  <p>Low</p>
  <h2 class="r2"><input class="inputNumber" id="num1" min="0" max="100" type="number" value="0.75" step=".01" maxlength="8" /></h2>
  <div class="sldcon">
    <input class="inputRange" id="range" type="range" min="0" max="100" value="0.75" step=".01" />
  </div>
  <p>Mid</p>
  <h2 class="r2"><input class="inputNumber" id="num1" min="0" max="100" type="number" value="35" step=".01" maxlength="8" /></h2>
  <div class="sldcon">
    <input class="inputRange" id="range" type="range" min="0" max="100" value="35" step=".01" />
  </div>
  <p>High</p>
  <h2 class="r2"><input class="inputNumber" id="num1" min="0" max="1000" type="number" value="40" step=".01" maxlength="8" /></h2>
  <div class="sldcon">
    <input class="inputRange" id="range" type="range" min="0" max="1000" value="40" step=".01" />
  </div>
</div>

Or you could reference the same index on the other collection:

const ranges = document.querySelectorAll(".inputRange");
document.querySelectorAll(".inputNumber").forEach((field, i) => {
  const range = ranges[i];
  range.oninput = () => field.value = range.value;
  field.oninput = () => range.value = field.value;
});
<div class="card grd">
  <h4 class="r1">Recipe</h4>
  <p>Low</p>
  <h2 class="r2"><input class="inputNumber" id="num1" min="0" max="100" type="number" value="0.75" step=".01" maxlength="8" /></h2>
  <div class="sldcon">
    <input class="inputRange" id="range" type="range" min="0" max="100" value="0.75" step=".01" />
  </div>
  <p>Mid</p>
  <h2 class="r2"><input class="inputNumber" id="num1" min="0" max="100" type="number" value="35" step=".01" maxlength="8" /></h2>
  <div class="sldcon">
    <input class="inputRange" id="range" type="range" min="0" max="100" value="35" step=".01" />
  </div>
  <p>High</p>
  <h2 class="r2"><input class="inputNumber" id="num1" min="0" max="1000" type="number" value="40" step=".01" maxlength="8" /></h2>
  <div class="sldcon">
    <input class="inputRange" id="range" type="range" min="0" max="1000" value="40" step=".01" />
  </div>
</div>

Upvotes: 2

Related Questions