Search code examples
javascriptjqueryhtmlinputhtml-input

Change value of range slider dynamically


I have some divs with an input[type="text"] and an input[type="range"] inside.

<div class="box">
    <input type="text" value="10">
    <input type="range" min="0" value="0" max="18" step="1">
</div>
<div class="box">
    <input type="text" value="10">
    <input type="range" min="0" value="0" max="18" step="1">
</div>

With the help of some jQuery the range sliders have uneven steps and the value of the text input fields change while moving the slider.

If you enter a number in an input field, the number changes to the nearest step/value.

stepVal = [10, 35, 50, 90, 100, 135, 155, 170, 190, 220, 230, 250, 270, 290, 310, 320, 350, 365, 400];
$('.box').each(function() {
  $(this).on('input', 'input[type="range"]', function() {
    $(this).prev('input[type=text]').val(stepVal[this.value]);
  });
  $(this).on('blur', 'input[type="text"]', function() {
    var textVal = $(this).val();
    var closestVal = stepVal.reduce(function(prev, curr) {
      return (Math.abs(curr - textVal) < Math.abs(prev - textVal) ? curr : prev);
    });
    $(this).val(closestVal);
    $(this).next('input[type=range]').val(closestVal);
  });
});

The problem is that the range slider moves only to the end or to the middle but not to the entered step/value. Any ideas how to solve this problem?


Solution

  • Your problem is that you are setting the wrong value to the range, when you enter a value in the input text.

    Because you are setting the value to the closestVal while it should be the respective index of closestVal, that's why it gets only to the middle when closestValue is 10 and to the end for other values which are higher than the max.

    Solution:

    You need to change this:

    $(this).next('input[type=range]').val(closestVal);
    

    To get the index of this value from your stepVal array, when you enter a value in the input.

    $(this).next('input[type=range]').val(stepVal.indexOf(closestVal));
    

    Demo:

    stepVal = [10, 35, 50, 90, 100, 135, 155, 170, 190, 220, 230, 250, 270, 290, 310, 320, 350, 365, 400];
    $('.box').each(function() {
      $(this).on('input', 'input[type="range"]', function() {
        $(this).prev('input[type=text]').val(stepVal[this.value]);
      });
      $(this).on('blur', 'input[type="text"]', function() {
        var textVal = $(this).val();
        var closestVal = stepVal.reduce(function(prev, curr) {
          return (Math.abs(curr - textVal) < Math.abs(prev - textVal) ? curr : prev);
        });
        $(this).val(closestVal);
        $(this).next('input[type=range]').val(stepVal.indexOf(closestVal));
      });
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div class="box">
        <input type="text" value="10">
        <input type="range" min="0" value="0" max="18" step="1">
    </div>
    <div class="box">
        <input type="text" value="10">
        <input type="range" min="0" value="0" max="18" step="1">
    </div>