Search code examples
javascriptslidernouislider

Prevent overlapping range values on a slider (noUiSlider)


I have a set of 3 ranges on a slider consisting of 30 days and beyond (see CodePen). At the moment, the values between the 3 ranges overlap by one day.

var slider = document.getElementById("slider");
var unconstrainedValues = document.getElementById("unconstrained-values");

noUiSlider.create(slider, {
    start: [0, 7],
    padding: [0, 1],
    connect: [true, true, true],
    range: {
        min: 0,
        max: 31
    },
    pips: {
        mode: "values",
        values: [0, 7, 14, 21, 28, 30],
        density: 3
    },
    step: 1,
    range: {
        min: [0],
        max: [31]
    },
    format: wNumb({
        // https://refreshless.com/wnumb/
        decimals: 0,
        mark: ".",
        thousad: ",",
        prefix: ""
        // suffix: ' p.p.'
    }),
    tooltips: true
});

var nodes = [
    document.getElementById("daily-rate-a"), // 0
    document.getElementById("daily-rate-b"), // 0
    document.getElementById("daily-rate-c") // 0
];

slider.noUiSlider.on("update", function (
    values,
    handle,
    unencoded,
    isTap,
    positions
) {
    nodes[handle].innerHTML = values[handle];
});

// var tooltips = document.querySelectorAll('.noUi-tooltip');
// console.log(tooltips);
// tooltips.forEach(tooltip => tooltip.classList.add('tooltips-active'));

var input1 = document.getElementById("input1");
var input2 = document.getElementById("input2");
var input3 = document.getElementById("input3");
var inputs = document.querySelectorAll(".form-control");

var connect = slider.querySelectorAll(".noUi-connect");
var classes = ["c-1-color", "c-2-color", "c-3-color"];

for (var i = 0; i < connect.length; i++) {
    connect[i].classList.add(classes[i]);
}

slider.noUiSlider.on("update", function (values) {
    unconstrainedValues.innerHTML = values.join(" - ");
});

Current result:

  • 0-15
  • 15-20
  • 20-Infinity

Desired result:

  • 0-15
  • 16-20
  • 21-Infinity

Essentially, the start of the next range should never be the same value as the end of the previous range. (Both 0 in Range A and Infinity in Range C are static and never change.) How do I accomplish this?


Solution

  • Use margin option while creating

    margin: 1
    
    noUiSlider.create(slider, {
        start: [0, 7],
        ...
        margin: 1 // Newly added
        ...
        tooltips: true
    });
    

    Range 3 Implementation

    • option change
    start: [0,16,21]
    connect: [true, true, true, true]
    
    • Event function change in noUiSlider.on
    values[0 ~ 2]
    

    So, a working js/html will be

    <script src=""https://cdnjs.cloudflare.com/ajax/libs/noUiSlider/13.1.3/nouislider.min.js">
    <div class="container">
        <table>
            <tr class="th">
                <td>SEQUENCE</td>
                <td>RATE</td>
                <td>DAYS ACTIVE</td>
            </tr>
            <tr class="daily-rate-a">
                <td>Daily Rate A</td>
                <td><input type="number" placeholder="0.00" required name="price" min="0" value="" step="0.01" title="Currency"></td>
                <td><span class="example-val" id="unconstrained-value-a"></span>
                </td>
            </tr>
            <tr class="daily-rate-b">
                <td>Daily Rate B</td>
                <td><input type="number" placeholder="0.00" required name="price" min="0" value="" step="0.01" title="Currency"></td>
                <td><span class="example-val" id="unconstrained-value-b"></span></td>
            </tr>
            <tr class="daily-rate-c">
                <td>Daily Default<span class="required">*</span></td>
                <td><input type="number" placeholder="0.00" required name="price" min="0" value="" step="0.01" title="Currency"></td>
                <td><span class="example-val" id="unconstrained-value-c"></span></div>
                </td>
            </tr>
        </table>
    
        <h3>Agreement Day Timeline</h3>
    
        <div id="slider"></div>
        <div class="infinity">∞</div>
    </div>
    
    var slider = document.getElementById("slider");
    var unconstrainedValueA = document.getElementById("unconstrained-value-a");
    var unconstrainedValueB = document.getElementById("unconstrained-value-b");
    var unconstrainedValueC = document.getElementById("unconstrained-value-c");
    
    noUiSlider.create(slider, {
        start: [0, 16, 21],
        padding: [0, 1],
        margin: 1,
        connect: [true, true, true, true],
        range: {
            min: 0,
            max: 31
        },
        pips: {
            mode: "values",
            values: [0, 7, 14, 21, 28, 30],
            density: 3
        },
        step: 1,
        range: {
            min: [0],
            max: [31]
        },
        format: wNumb({
            // https://refreshless.com/wnumb/
            decimals: 0,
            mark: ".",
            thousad: ",",
            prefix: ""
            // suffix: ' p.p.'
        }),
        tooltips: true
    });
    
    var nodes = [
        document.getElementById("daily-rate-a"), // 0
        document.getElementById("daily-rate-b"), // 0
        document.getElementById("daily-rate-c") // 0
    ];
    
    var tooltips = document.querySelectorAll('.noUi-tooltip');
    console.log(tooltips);
    tooltips.forEach(tooltip => tooltip.classList.add('tooltips-active'));
    
    var input1 = document.getElementById("input1");
    var input2 = document.getElementById("input2");
    var input3 = document.getElementById("input3");
    var inputs = document.querySelectorAll(".form-control");
    
    var connect = slider.querySelectorAll(".noUi-connect");
    var classes = ["c-1-color", "c-2-color", "c-3-color"];
    
    for (var i = 0; i < connect.length; i++) {
        connect[i].classList.add(classes[i]);
    }
    
    slider.noUiSlider.on("update", function (values) {
        unconstrainedValueA.innerHTML = values[0] + ' - ' + (values[1] - 1);
        unconstrainedValueB.innerHTML = values[1] + ' - ' + (values[2] - 1);
        unconstrainedValueC.innerHTML = values[2] + ' - ' + '∞';
    });