Adam Robertson
Adam Robertson

Reputation: 567

How to load multiple sliders with values and tooltips with noUISlider?

I'm trying to load multiple sliders using noUISlider and it's not working. When using the first slider, the values changes for the second and third. How do I go about refactoring the code for one slider so I can easily add additional sliders with different options?

Here's a fiddle and below is my code.

// noUISlider
        var actSlider = document.getElementById('act-slider');

        noUiSlider.create(actSlider, {
            start: [0, 50],
            connect: false,
            step: 1,
            range: {
                'min': 0,
                'max': 50
            },
            format: {
                to: function (value) {
                    return value + '';
                },
                from: function (value) {
                    return value.replace('', '');
                }
            }
        });

        // Connect bar
        var connectBar = document.createElement('div'),
            connectBase = actSlider.getElementsByClassName('noUi-base')[0],
            connectHandles = actSlider.getElementsByClassName('noUi-origin');

        // Give the bar a class for styling and add it to the slider.
        connectBar.className += 'connect';
        connectBase.appendChild(connectBar);

        actSlider.noUiSlider.on('update', function (values, handle) {

            // Pick left for the first handle, right for the second.
            var side = handle ? 'right' : 'left',
            // Get the handle position and trim the '%' sign.
                offset = (connectHandles[handle].style.left).slice(0, -1);

            // Right offset is 100% - left offset
            if (handle === 1) {
                offset = 100 - offset;
            }

            connectBar.style[side] = offset + '%';
        });

        // Value tooltips
        var tipHandles = actSlider.getElementsByClassName('noUi-handle'),
            tooltips = [];

        // Add divs to the slider handles.
        for (var i = 0; i < tipHandles.length; i++) {
            tooltips[i] = document.createElement('div');
            tooltips[i].className += 'value-tooltip';
            tipHandles[i].appendChild(tooltips[i]);
        }

        // When the slider changes, write the value to the tooltips.
        actSlider.noUiSlider.on('update', function (values, handle) {
            tooltips[handle].innerHTML = values[handle];
        });

Upvotes: 3

Views: 2499

Answers (1)

Lg102
Lg102

Reputation: 4898

You can wrap your slider creation in a function, and call it for all elements where you want a slider created.

noUiSlider also supports tooltips (from version 8.1.0) and connect options, so you don't have to implement those yourself if you don't want to make very specific changes.

As for different options for every slider, there are several ways to do this. I've added an example using data attributes for the step option.

The following code initializes a slider on all elements with a .slider class.

function data ( element, key ) {
    return element.getAttribute('data-' + key);   
}

function createSlider ( slider ) {

        noUiSlider.create(slider, {
            start: [0, 50],
            connect: false,
            step: Number(data(slider, 'step')) || 1,
            range: {
                'min': 0,
                'max': 50
            },
            tooltips: true,
            connect: true,
            format: {
                to: function (value) {
                    return value + '';
                },
                from: function (value) {
                    return value.replace('', '');
                }
            }
        });
}

Array.prototype.forEach.call(document.querySelectorAll('.slider'), createSlider);

Here's a jsFiddle demonstrating this code.

Upvotes: 5

Related Questions