1

I have a range slider that display the one value, but i wish to display 2 limits i.e min and max, something like a price range slider and then save the min and max value in database, but currently i have only one value.

There are various sliders made through js, but i am wondering can this code be modified to have both max and min values on a single slider (@fiddle)

<body>
    <form>
        <input type="range" name="amountRange" min="0" max="20" value="0" oninput="this.form.amountInput.value=this.value" />
        <input type="number" name="amountInput" min="0" max="20" value="0" oninput="this.form.amountRange.value=this.value" />
    </form>
</body>

1 Answers1

4

You could create a widget yourself.

Broad idea:

  • Markup and Javscript:
    1. Have two range inputs inside a container for the widget
    2. Use data attributes on the container to hold the two values e.g. data-lbound for storing the lower value and data-ubound to store the higher value
    3. Update the data attributes of the container on input event of the range inputs
    4. Use these data attributes to retrieve the values any time required for form submission or any other use
  • CSS:
    1. Use absolute positioning to position the two range inputs on top of each other inside the container
    2. Stylize the range inputs to have their thumbs moved a little above so that overlapped range inputs do not prevent their usage
    3. If required, hide the slider/bar/track
    4. Create an ::after pseudo-element on the container with its content property set to the data attributes of the container. This will be used to display the current ranges.
    5. Rest is all about beautifying the ranges inputs.

Here is a small demo that I created. (Test it out with Chrome or Firefox) Works with keyboard as well.

Fiddle: http://jsfiddle.net/abhitalks/a1f1k8d0/2/

Snippet:

.multi-range, .multi-range * { box-sizing: border-box; padding: 0; margin: 0; }
.multi-range { 
    position: relative; width: 160px; height: 28px; margin: 16px;
    border: 1px solid #ddd; font-family: monospace;
}
.multi-range > hr { position: absolute; width: 100%; top: 50%; }
.multi-range > input[type=range] {
    width: calc(100% - 16px); 
    position: absolute; bottom: 6px; left: 0;
}
.multi-range > input[type=range]:last-of-type { margin-left: 16px; }
.multi-range > input[type=range]::-webkit-slider-thumb { transform: translateY(-18px); }
.multi-range > input[type=range]::-webkit-slider-runnable-track { -webkit-appearance: none; height: 0px; }
.multi-range > input[type=range]::-moz-range-thumb { transform: translateY(-18px); }
.multi-range > input[type=range]::-moz-range-track { -webkit-appearance: none; height: 0px; }
.multi-range > input[type=range]::-ms-thumb { transform: translateY(-18px); }
.multi-range > input[type=range]::-ms-track { -webkit-appearance: none; height: 0px; }
.multi-range::after { 
    content: attr(data-lbound) ' - ' attr(data-ubound); 
    position: absolute; top: 0; left: 100%; white-space: nowrap;
    display: block; padding: 0px 4px; margin: -1px 2px;
    height: 26px; width: auto; border: 1px solid #ddd; 
    font-size: 13px; line-height: 26px;
}
<div class='multi-range' data-lbound='10' data-ubound='50'>
    <hr />
    <input type='range' 
           min='10' max='45' step='5' value='10' 
           oninput='this.parentNode.dataset.lbound=this.value;'
    />
    <input type='range' 
           min='15' max='50' step='5' value='50' 
           oninput='this.parentNode.dataset.ubound=this.value;'
    />
</div>

Note: The above demo is well, just a demo. It will work perfectly in Chrome and Firefox, but I could not test it in IE/Edge. My feeling is that it will have problems with IE/Edge because the slider thumbs are inline with the track in those browsers. You can further customize and stylize it to work with IE/Edge.

Abhitalks
  • 27,721
  • 5
  • 58
  • 81