Search code examples
javascriptnouislider

noUiSlider - Get current slider in format or via update event


I have multiple sliders which is defined by document.querySelectorAll( '.js-slider' ); on tooltips.format I would like to insert a label above the value, which is defined on the current slide object via data-label.

On init this works fine.

But on update it gets the last initialized slider label, which is obvious :) But can I somehow get the current slider object or id inside the tooltips.format or inside the update event or get a hold of the settings object for the current slider?

var uiSlider = {
init : function() {
    var rangeInputs = document.querySelectorAll( '.js-slider' );
    uiSlider.setup( rangeInputs );
},
setup : function( sliders ) {
    var len = sliders.length,
        slider, min, max, step, value, range, start, postfix, pipValues, label, settings;

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

    while( len-- ) {            
        slider = sliders[len];                  
        min = data( slider,'min' );
        max = data( slider,'max' );
        step = data( slider,'step' );
        value = data( slider, 'value' );
        range = !isNaN( min ) && !isNaN( max ) ? { 'min': min, 'max': max } : { 'min': 0, 'max': 100 };
        start = !isNaN( value ) ? value : 0;
        postfix = slider.getAttribute( 'data-postfix' );
        pipValues = slider.getAttribute( 'data-pipvalues' ) ? slider.getAttribute( 'data-pipvalues' ).split( ',' ) : null;
        label =  slider.getAttribute( 'data-label' );
        settings = {
            start: start,
            step: !isNaN( step ) ? step : 1,
            connect: "lower",
            tooltips: {
                format: function( value, handle, settings ) {

                    var dformat = wNumb({
                        decimals: 0,
                        thousand: ',',
                        prefix: '<span class="noUi-tooltip__label">' + label + '</span>',
                        postfix: ( postfix ? ' ' + postfix : ' $' )
                    }); 

                    return dformat.to( parseFloat( value ) );
                }
            },
            range: range,
            pips: { // Show a scale with the slider
                mode: 'positions',
                values: pipValues ? pipValues : [ 0, 20, 40, 60, 80, 100 ],
                density: 2,
                format: wNumb({
                    decimals: 0,
                    thousand: ','
                })
            },
            format: wNumb({
                decimals: 0
            })
        };

        noUiSlider.create( slider, settings );

    }
}
};

uiSlider.init();

Havent been able to figure this out.

A running Fiddel of the problem can be seen here: Fiddle


Solution

  • This happens because you are sharing a 'label' variable between all sliders.

    If you refactor your code to run all slider initializations in a closure, you can have label variables unique to each slider.

    The simplest way to do this is to forEach on your list of sliders, for example using Array.prototype.forEach.call(sliders, function (slider));

    Your code refactored:

    var uiSlider = {
        init : function() {
            var rangeInputs = document.querySelectorAll( '.js-slider' );
            uiSlider.setup( rangeInputs );
        },
        setup : function( sliders ) {
    
            function data( element , value ){
                return parseFloat( element.getAttribute( 'data-' + value ) );
            }
    
            Array.prototype.forEach.call(sliders, function ( slider ) {
    
                var min = data( slider,'min' ),
                    max = data( slider,'max' ),
                    step = data( slider,'step' ),
                    value = data( slider, 'value' ),
                    range = !isNaN( min ) && !isNaN( max ) ? { 'min': min, 'max': max } : { 'min': 0, 'max': 100 },
                    start = !isNaN( value ) ? value : 0,
                    postfix = slider.getAttribute( 'data-postfix' ),
                    pipValues = slider.getAttribute( 'data-pipvalues' ) ? slider.getAttribute( 'data-pipvalues' ).split( ',' ) : null,
                    label =  slider.getAttribute( 'data-label' );
    
                noUiSlider.create(slider, {
                    start: start,
                    step: !isNaN( step ) ? step : 1,
                    connect: "lower",
                    tooltips: {
                        format: function( value, handle, settings ) {
    
                            var dformat = wNumb({
                                decimals: 0,
                                thousand: ',',
                                prefix: '<span class="noUi-tooltip__label">' + label + '</span>',
                                postfix: ( postfix ? ' ' + postfix : ' $' )
                            }); 
    
                            return dformat.to( parseFloat( value ) );
                        }
                    },
                    range: range,
                    pips: { // Show a scale with the slider
                        mode: 'positions',
                        values: pipValues ? pipValues : [ 0, 20, 40, 60, 80, 100 ],
                        density: 2,
                        format: wNumb({
                            decimals: 0,
                            thousand: ','
                        })
                    },
                    format: wNumb({
                        decimals: 0
                    })
                });
            });
        }
    };
    
    uiSlider.init();
    

    And an updated jsFiddle.