skip to Main Content

I have a simple dual slider as seen below.

The left slider can not push the right slider any more to the right as intended, but the right slider pushes the left slider to the left and I don’t know how to prevent this.

What am I missing?

      // Elements for the sliders and display
      const minSlider = document.getElementById("minL");
      const maxSlider = document.getElementById("maxL");
      const rangeDisplay = document.getElementById("rangeDisplay");

      // Update the display and enforce slider constraints
      function updateSliders() {
        let minL = parseInt(minSlider.value);
        let maxL = parseInt(maxSlider.value);

        // Prevent the minSlider from exceeding maxSlider's value
        if (minL > maxL) {
          minSlider.value = maxL;
          minL = maxL;
        }

        // Update the displayed range
        rangeDisplay.textContent = `${minL} - ${maxL}`;
      }

      // Attach input event listeners for live updating
      minSlider.addEventListener("input", updateSliders);
      maxSlider.addEventListener("input", updateSliders);

      // Initial display update
      updateSliders();
  .slider-container {
      position: relative;
      width: 100%;
      max-width: 400px;
      height: 20px;
  }

  #minL, #maxL {
      position: absolute;
      width: 100%;
      pointer-events: none;
  }

  #minL::-webkit-slider-thumb, #maxL::-webkit-slider-thumb {
      pointer-events: auto;
      height: 18px;
      width: 18px;
      background-color: #333;
      cursor: pointer;
  }
    <div id="controls">
      <label>Range: <span id="rangeDisplay">0 - 70</span></label>
      <div class="slider-container">
        <input type="range" id="minL" min="0" max="360" value="0" step="1">
        <input type="range" id="maxL" min="0" max="360" value="70" step="1">
      </div>
    </div>
  </body>
</html>

3

Answers


  1. You have the code for min > max

    But I don’t see any check for the other way around?
    To do the opposite you need to be checking for when the max slider is less than the min slider and adjust the max slider to equal the min slider in that case. Try adding this code.

    // Prevent the maxSlider from beingl less than the minSlider's value
    if (maxL < minL) {
      maxSlider.value = minL;
      maxL = minL;
    }
    

    I’m pretty sure your problem is because the minSlider can’t be more than the max slider so if the max slider goes under the min slider than the min slider is moving to the left to be less than it.

    Edit: I think the order of operations matters too because whichever one goes first is going to get the priority. I’m guessing the real solution is probably to check which slider is being adjusted at the moment and prioritize the other one.

    Login or Signup to reply.
  2. You need to adapt the logic based on which slider you are currently updating

    Right now your code just sets the value of minSlider to the value of maxSlider, but this only works if you change minSlider, so you need to do the opposite job when you change maxSlider.

    That’s why you need to identify which slider is changing and then set the right value for that slider.

    // Elements for the sliders and display
          const minSlider = document.getElementById("minL");
          const maxSlider = document.getElementById("maxL");
          const rangeDisplay = document.getElementById("rangeDisplay");
    
          // Update the display and enforce slider constraints
          function updateSliders(evt) {
            const sliderID = evt.target.id;
            let minL = parseInt(minSlider.value);
            let maxL = parseInt(maxSlider.value);
    
            // Prevent the minSlider from exceeding maxSlider's value
            if (minL > maxL) {
              if (sliderID === 'minL') {
                 minSlider.value = maxL;
                 minL = maxL;
              }
              else {
                 maxSlider.value = minL;
                 maxL = minL;
              }
            }
            
            console.log(sliderID, minL, maxL);
    
    
            // Update the displayed range
            rangeDisplay.textContent = `${minL} - ${maxL}`;
          }
    
          // Attach input event listeners for live updating
          minSlider.addEventListener("input", updateSliders);
          maxSlider.addEventListener("input", updateSliders);
    
          // Initial display update
          updateSliders();
    .slider-container {
          position: relative;
          width: 100%;
          max-width: 400px;
          height: 20px;
      }
    
      #minL, #maxL {
          position: absolute;
          width: 100%;
          pointer-events: none;
      }
    
      #minL::-webkit-slider-thumb, #maxL::-webkit-slider-thumb {
          pointer-events: auto;
          height: 18px;
          width: 18px;
          background-color: #333;
          cursor: pointer;
      }
    <div id="controls">
          <label>Range: <span id="rangeDisplay">0 - 70</span></label>
          <div class="slider-container">
            <input type="range" id="minL" min="0" max="360" value="0" step="1">
            <input type="range" id="maxL" min="0" max="360" value="70" step="1">
          </div>
        </div>
      </body>
    </html>
    Login or Signup to reply.
  3. You can not just apply the "opposite" condition for the other direction here – you need to first of all take into account, which of the sliders you are currently dragging.

    One simple way to do that in this instance, would be to check the ID of the event target, whether that is minL or maxL.

    function updateSliders(e) – I added the e parameter here, so that your function takes the event object instance as parameter.

    And since you are also calling updateSliders(); for the initial display, where no Event instance will get passed, I a also checking whether e even exists, before trying to access its target.

    // Elements for the sliders and display
          const minSlider = document.getElementById("minL");
          const maxSlider = document.getElementById("maxL");
          const rangeDisplay = document.getElementById("rangeDisplay");
    
          // Update the display and enforce slider constraints
          function updateSliders(e) {
            let minL = parseInt(minSlider.value);
            let maxL = parseInt(maxSlider.value);
    
            // Prevent the minSlider from exceeding maxSlider's value
            if (e && e.target.id == "minL" && minL > maxL) {
              minSlider.value = maxL;
              minL = maxL;
            }
            // Prevent the maxSlider from going below minSlider's value
            if (e && e.target.id == "maxL" && maxL < minL) {
              maxSlider.value = minL;
              maxL = minL;
            }
    
            // Update the displayed range
            rangeDisplay.textContent = `${minL} - ${maxL}`;
          }
    
          // Attach input event listeners for live updating
          minSlider.addEventListener("input", updateSliders);
          maxSlider.addEventListener("input", updateSliders);
    
          // Initial display update
          updateSliders();
    .slider-container {
          position: relative;
          width: 100%;
          max-width: 400px;
          height: 20px;
      }
    
      #minL, #maxL {
          position: absolute;
          width: 100%;
          pointer-events: none;
      }
    
      #minL::-webkit-slider-thumb, #maxL::-webkit-slider-thumb {
          pointer-events: auto;
          height: 18px;
          width: 18px;
          background-color: #333;
          cursor: pointer;
      }
    <div id="controls">
          <label>Range: <span id="rangeDisplay">0 - 70</span></label>
          <div class="slider-container">
            <input type="range" id="minL" min="0" max="360" value="0" step="1">
            <input type="range" id="maxL" min="0" max="360" value="70" step="1">
          </div>
        </div>
      </body>
    </html>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search