Adjust the maximum and minimum values on a dual thumb slider

I have implemented a two thumb range slider to define the maximum and minimum values. However, I recently discovered that it is possible for the thumbs to cross over each other - the max value can exceed the min value and vice versa.

I am looking for a solution to prevent the min value from exceeding the max value and ensure that the max value does not go below the min value.

Despite conducting some research, I have not come across any useful JavaScript solutions for this issue. Is there any alternative option available that could help in resolving this matter?

const twoRangeSlider = (() => {
  const rangeCheck = (rangeInputs, rangeMinOutput, rangeMaxOutput) => {
    const rangeMin = rangeInputs[0].min ? rangeInputs[0].min : 0;
    const rangeMax = rangeInputs[0].max ? rangeInputs[0].max : 100;
    let rangeMinValue = parseFloat(rangeInputs[1].value);
    let rangeMaxValue = parseFloat(rangeInputs[0].value);

    rangeMinValue = Math.min(Math.max(rangeMinValue, rangeMin), rangeMaxValue);


    const rangeMinPercentage = Number(
      ((rangeMinValue - rangeMin) * 100) / (rangeMax - rangeMin));
    const rangeMaxPercentage = Number(
      ((rangeMaxValue - rangeMin) * 100) / (rangeMax - rangeMin));


    rangeInputs[0].style.background = `linear-gradient(to right, #000 ${rangeMaxPercentage}%, #c4c8ca ${rangeMaxPercentage}%)`;
    rangeInputs[1].style.background = `linear-gradient(to right,#c4c8ca ${rangeMinPercentage}%, transparent ${rangeMinPercentage}%)`;


  };

  const bindComponent = (item) => {
    const rangeInputs = item.querySelectorAll('.js-two-range-slider-input');
    const rangeMinOutput = item.querySelector('.js-two-range-slider-min-value');
    const rangeMaxOutput = item.querySelector('.js-two-range-slider-max-value');

    item.addEventListener("input", () => {
      rangeCheck(rangeInputs, rangeMinOutput, rangeMaxOutput);
    });

    rangeCheck(rangeInputs, rangeMinOutput, rangeMaxOutput);
  };

  const init = () => {
    const rootEl = document.getElementsByClassName("js-two-range-slider");
    [...rootEl].forEach((item) => bindComponent(item));
  };

  return {
    init
  };
})();

twoRangeSlider.init();
.two-range-slider {
  position: relative;
  height: 4px;
  width: 164px;
  margin-bottom: 50px;
}

.two-range-slider__input {
  position: absolute;
  left: 40%;
  top: 15px;
  box-shadow: 0;
  appearance: none;
  width: 60%;
  height: 3px;
  border-radius: 50px;
  background-color: #000;
  outline: 0;
}

.two-range-slider__value {
  padding: 0px 10px;
  color: #000;
  position: relative;
  top: 19px;
  outline: none;
  width: 50px;
  position: absolute;
  border: 1px solid #ccc;
  box-sizing: border-box;
}

.two-range-slider__input::-webkit-slider-thumb {
  z-index: 2;
  position: relative;
  -webkit-appearance: none;
  appearance: none;
  height: 13px;
  width: 13px;
  border-radius: 50%;
  background: #000;
  cursor: pointer;
}

.two-range-slider__input::-moz-range-thumb {
  z-index: 2;
  position: relative;
  appearance: none;
  width: 25px;
  height: 25px;
  border-radius: 50%;
  border: 0;
  background: #FFFFFF;
  cursor: pointer;
}

.two-range-slider__output {
  display: inline-flex;
  flex-flow: row nowrap;
  justify-content: space-between;
  width: 140%;
  top: -15px;
  margin-left: 0px;
  color: #000;
  position: relative;
}

.range-slider__value {
  padding: 0px 10px;
  color: #000;
  outline: none;
  width: 50px;
}
<div class="two-range-slider js-two-range-slider">
  <input type="range" value="80" min="10" max="100" step="1" class="two-range-slider__input js-two-range-slider-input">
  <input type="range" value="30" min="10" max="100" step="1" class="two-range-slider__input js-two-range-slider-input">

  <div class="two-range-slider__output">
    <p class="minmax">Min</p><input class="two-range-slider__value js-two-range-slider-min-value" type="number" value="30" min="10" max="100" step="1"></input>
    <p class="maxmin">Max</p><input style="right: -5px;" class="two-range-slider__value js-two-range-slider-max-value" type="number" value="80" min="10" max="100" step="1"></input>
  </div>

</div>

Answer №1

I made some modifications to your example in order to better illustrate my point from the previous comment.

const rangeSlider = (() => {

  const bindComponent = (element) => {
    const rangeInputs = element.querySelectorAll('.js-range-slider-input');

    element.addEventListener("input", ({ target }) => {
      const [ right, left ] = rangeInputs;
      if (target == right) {
        left.value = Math.min(+right.value -1, +left.value);
      } else {
        right.value = Math.max(+left.value +1, +right.value);
      }

    });

  };

  const initialize = () => {
    const rootElement = document.getElementsByClassName("js-range-slider");
    [...rootElement].forEach((item) => bindComponent(item));
  };

  return {
    initialize
  };
})();

rangeSlider.initialize();
.range-slider {
  position: relative;
  height: 4px;
  width: 164px;
  margin-bottom: 50px;
}

.range-slider__input {
  position: absolute;
  left: 40%;
  top: 15px;
  box-shadow: 0;
  appearance: none;
  width: 60%;
  height: 3px;
  border-radius: 50px;
  background-color: #000;
  outline: 0;
}

.range-slider__value {
  padding: 0px 10px;
  color: #000;
  position: relative;
  top: 19px;
  outline: none;
  width: 50px;
  position: absolute;
  border: 1px solid #ccc;
  box-sizing: border-box;
}

.range-slider__input::-webkit-slider-thumb {
  z-index: 2;
  position: relative;
  -webkit-appearance: none;
  appearance: none;
  height: 13px;
  width: 13px;
  border-radius: 50%;
  background: #000;
  cursor: pointer;
}

.range-slider__input::-moz-range-thumb {
  z-index: 2;
  position: relative;
  appearance: none;
  width: 25px;
  height: 25px;
  border-radius: 50%;
  border: 0;
  background: #FFFFFF;
  cursor: pointer;
}

.range-slider__output {
  display: inline-flex;
  flex-flow: row nowrap;
  justify-content: space-between;
  width: 140%;
  top: -15px;
  margin-left: 0px;
  color: #000;
  position: relative;
}

.range-slider__value {
  padding: 0px 10px;
  color: #000;
  outline: none;
  width: 50px;
}
<div class="range-slider js-range-slider">
  <input type="range" value="80" min="10" max="100" step="1" class="range-slider__input js-range-slider-input">
  <input type="range" value="30" min="10" max="100" step="1" class="range-slider__input js-range-slider-input">

  <div class="range-slider__output">
    <p class="minmax">Min</p><input class="range-slider__value js-range-slider-min-value" type="number" value="30" min="10" max="100" step="1">
    <p class="maxmin">Max</p><input style="right: -5px;" class="range-slider__value js-range-slider-max-value" type="number" value="80" min="10" max="100" step="1">
  </div>

</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Trouble with jQuery event.keyCode in detecting alphanumeric characters

I recently developed a script that is supposed to detect the key the user clicks and perform an action based on whether it is alphanumeric. However, I am encountering an issue as the script does not seem to be working as expected, and I am not receiving an ...

Is there a way to position labels above their corresponding elements using this customized input style?

My CSS for styled inputs has become too complex, making it difficult to remove and fix certain elements. Specifically, I am facing issues in getting labels positioned above my input fields, select options, and output section. /* Cus ...

How do I select all checkboxes in TypeScript when I only click on one of them?

I'm currently working with a list of checkboxes in my HTML code: <div class="col-sm-12" *ngIf="ControllerModel"> <div *ngFor="let controller of ControllerModel" class="panel col-md-6 col-lg-6 col-xs-6"> <div class="panel-heading" ...

Center a span vertically inside a div as the text within the span grows to occupy the entire div

I am facing an issue with a table that has 25 td's. Each td contains specific elements as shown below: <td> <div> <span> text </span> </div> </td> Additionally, there is a script in place that adj ...

When hovering over the menu, the sub-menu is displayed and the content slides downwards. Is there a way to prevent the content from sliding down and have the sub-menu overlap the

When the main menu is hovered over, a sub-menu appears and the content below the main menu slides down. Check out the code snippet below: HTML: <div id="holderDiv"> <div id="menu"> <a href="#" id="items">Menu 1</a> < ...

The footer section of my website seems to have gone missing in the HTML/CSS coding

I'm having trouble with my website footer not displaying. I've tried using "position: absolute; top: 50px; left:100px;" in my HTML/CSS, but it's not working. Can anyone help me fix this issue? Here is a link to the code I'm working on: ...

Targeting HTML tags, styling names, and class names using CSS

In the markup below, I am trying to target three specific points using CSS. img style*=right class=media-element I attempted to use the code below, which did not work: img[style*="right"][class="media-element"] {margin-left:10px;} However, selecting t ...

What causes the disparity in functionality between CSS's Left 75% and Right 25% properties?

Here is my CSS code snippet: .bloodparam > .highvalue { bottom: 12px; right: 25%; } and .bloodparam > .highvalue { bottom: 12px; left: 75%; } I expected the element to be in the same position with both lines of code, but I'm noticing differe ...

Setting a div's width to cover 100% of the screen's width

I'm currently working on creating a 2 column layout using divs. The left column has a fixed size of 150 px, while the right column should extend to the right boundary of the browser. I've tried using both width:auto and width:100% values for the ...

Fluid Centered UL with Bullet Points

We have received a unique request from one of our clients. They are asking for the content within a specific <ul> to be centered along with the icons. Centering and adding icons are doable, but the challenge lies in centering the <li> elements ...

Notifying the client once a task is finished

For my current project, I am developing an internal web application using Spring MVC. The purpose of this application is to allow users to submit a set of jobs via a RESTful web service. Each job should only take a few seconds to complete, but users may su ...

ReferenceError: _jquery2.default.ajax is not a function" encountered in a React Native application

I have been attempting to use jQuery to retrieve xml data from an internal website. My expo project setup is quite basic and resembles the following: import React from 'react'; import { StyleSheet, Text, View } from 'react-native'; imp ...

show a function written in JavaScript

I’m currently developing an API and looking to demonstrate a JavaScript code example for invoking this API. While writing a test function in JavaScript, I aim to execute and showcase the code for the JavaScript functions. However, my preference is to ha ...

The act of selecting a parent element appears to trigger the selection of its child elements as well

I am attempting to create an accordion using Vanilla JavaScript, but I have encountered an issue. When there is a child div element inside the header of the accordion, it does not seem to work and I'm unsure why. However, if there is no child div elem ...

Customize Vue.js: Disable Attribute Quote Removal for Individual Pages

We have a requirement to turn off the minify.removeAttributeQuotes property for certain pages. This is the content of my vue.config.js: const packageJson = require('./package.json') module.exports = { assetsDir: packageJson.name + &apos ...

JavaScript is experiencing an error where it cannot define a function, rendering it unable to generate a JSON object due to its inability to recognize that the

I've created a JavaScript script function that holds cart items for ordering food. This function takes two parameters: ID and price. Here is a snippet of my script file: <script> function addtocart(mitem, mprice) { var price = ...

Enhance the appearance of specific wordpress usernames by adding a touch of "flair" next to them

I'm looking to add a special "flair" next to specific users on my WordPress website, similar to how YouTube distinguishes verified users. I have the CSS for changing the color on hover, but I need help keeping it positioned correctly. Examples from Y ...

Flowplayer playlist stops after playing the first clip

I am having issues with my flowplayer configuration, as it is not behaving as I expected. After the first video ends, I want the second and subsequent videos to play automatically. Can anyone provide some guidance on how to achieve this? $f("player", "/fl ...

Angular UI and Node backend causing CORS issues

Just diving into the world of node and could use a little assistance. Encountering this error message: Access to XMLHttpRequest at 'http://localhost:3000/api/auth/signin' from origin 'http://localhost:4200' has been blocked by CORS pol ...

Tips for successfully transferring data using a dynamic key in a Semantic UI Vue dropdown

My current challenge involves troubleshooting the semantic-ui-vue dropdown functionality. To view the issue, visit my sandbox link: https://codesandbox.io/s/3qknm52pm5. Within the sandbox environment, there are two dropdown menus labeled as From and To. ...