Некорректная работа input

Нашёл в интернете кусочек кода, который из input type="range" выводит цифровое значение в input type="text". Если двигать ползунок - меняется значение в input type="text", если менять значение в input type="text", то ползунок двигается. Для input text так-же есть 2 кнопки, + и -, которые по единице меняют значение в input-е. Всё условно работает, только одна загвоздка. При смене числа, ползунок в input type="range" не двигается, хоть и значение в input type="text" меняется кнопками.

В чём проблема?

function fun1() {
  var rng = document.getElementById("r1"); //rng - это ползунок
  var i1 = document.getElementById("i1"); // i1 - input
  i1.value = rng.value;
}

function fun2() {
  var rng = document.getElementById("r1"); //rng - это ползунок
  var i1 = document.getElementById("i1"); // i1 - input
  rng.value = i1.value;
}
const counter = function() {
  const btns = document.querySelectorAll(".counter-button");

  btns.forEach((btn) => {
    btn.addEventListener("click", function() {
      const direction = this.dataset.direction;
      const inp = this.parentElement.querySelector(".counter-input");
      const currentValue = +inp.value;
      let newValue;

      if (direction === "plus") {
        newValue = currentValue + 1;
      } else {
        newValue = currentValue - 1 > 0 ? currentValue - 1 : 0;
      }

      inp.value = newValue;
    });
  });
};
counter();
<div class="panel">
  <div class="ip-range d-flex">
    <input type="range" id="r1" value="5" max="20" oninput="fun1()" />
    <div style="display: flex; width: auto">
      <div class="range-button">
        <button class="counter-button" data-direction="minus">
                            - 
        </button>
        <input class="counter-input" type="text" oninput="fun2()" id="i1" />
        <button class="counter-button" data-direction="plus">
                             +
        </button>
      </div>
    </div>
  </div>
</div>


Ответы (2 шт):

Автор решения: Dmitry

Если долго не копаться, то и вот так сойдет. Выбрать по селектору range и давать ему значения при нажатии на кнопки

function fun1() {
  var rng = document.getElementById("r1"); //rng - это ползунок
  var i1 = document.getElementById("i1"); // i1 - input
  i1.value = rng.value;
}

function fun2() {
  var rng = document.getElementById("r1"); //rng - это ползунок
  var i1 = document.getElementById("i1"); // i1 - input
  rng.value = i1.value;
}
const counter = function() {
  const btns = document.querySelectorAll(".counter-button");

  btns.forEach((btn) => {
    btn.addEventListener("click", function() {
      const direction = this.dataset.direction;
      const inp = this.parentElement.querySelector(".counter-input");
      const currentValue = +inp.value;
      const sl = document.querySelector("#r1");
      let newValue;

      if (direction === "plus") {
        newValue = currentValue + 1;
        sl.value = newValue;
      } else {
        newValue = currentValue - 1 > 0 ? currentValue - 1 : 0;
        sl.value = newValue
      }

      inp.value = newValue;
    });
  });
};
counter();
<div class="panel">
  <div class="ip-range d-flex">
    <input type="range" id="r1" value="5" max="20" oninput="fun1()" />
    <div style="display: flex; width: auto">
      <div class="range-button">
        <button class="counter-button" data-direction="minus">
                            - 
        </button>
        <input class="counter-input" type="text" oninput="fun2()" id="i1" />
        <button class="counter-button" data-direction="plus">
                             +
        </button>
      </div>
    </div>
  </div>
</div>

→ Ссылка
Автор решения: Leonid

Добавил в функцию counter() искусственный вызов ONINPUT, а в тег самого input type="text" attribute value="5".

function fun1() {
  var rng = document.getElementById("r1"); //rng - это ползунок
  var i1 = document.getElementById("i1"); // i1 - input
  i1.value = rng.value;
}

function fun2() {
  var rng = document.getElementById("r1"); //rng - это ползунок
  var i1 = document.getElementById("i1"); // i1 - input
  rng.value = i1.value;
}
const counter = function() {
  const btns = document.querySelectorAll(".counter-button");

  btns.forEach((btn) => {
    btn.addEventListener("click", function() {
      const direction = this.dataset.direction;
      const inp = this.parentElement.querySelector(".counter-input");
      const currentValue = +inp.value;
      let newValue;

      if (direction === "plus") {
        newValue = currentValue + 1;
      } else {
        newValue = currentValue - 1 > 0 ? currentValue - 1 : 0;
      }

      inp.value = newValue;
      inp.dispatchEvent(new Event('input')); // ДОБАВИЛ СЮДА ВЫЗОВ ONINPUT
    });
  });
};
counter();
<div class="panel">
  <div class="ip-range d-flex">
    <input type="range" id="r1" value="5" max="20" oninput="fun1()" />
    <div style="display: flex; width: auto">
      <div class="range-button">
        <button class="counter-button" data-direction="minus">
                            - 
        </button>
        <input class="counter-input" type="text" value="5" oninput="fun2()" id="i1" />
        <button class="counter-button" data-direction="plus">
                             +
        </button>
      </div>
    </div>
  </div>
</div>

А можно просто поменять на input type="number" и никаких функций counter и кнопок не надо.

function fun1() {
  var rng = document.getElementById("r1"); //rng - это ползунок
  var i1 = document.getElementById("i1"); // i1 - input
  i1.value = rng.value;
}

function fun2() {
  var rng = document.getElementById("r1"); //rng - это ползунок
  var i1 = document.getElementById("i1"); // i1 - input
  rng.value = i1.value;
}
<div class="panel">
  <div class="ip-range d-flex">
<input type="range" id="r1" value="5" max="20" oninput="fun1()" />
<div style="display: flex; width: auto">
  <div class="range-button">
    <input class="counter-input" type="number" value="5" step="1" oninput="fun2()" id="i1" />

  </div>
</div>
  </div>
</div>

Можно обойтись вообще одними короткими инструкциями в самих инпутах:

<input type="range" style="display: block" id="r1" value="5" max="20" oninput="document.getElementById('i1').value = this.value" />
<input class="counter-input" type="number" min="0" max="20" value="5" oninput="document.getElementById('r1').value = this.value" step="1" id="i1" />

→ Ссылка