Search code examples
javascriptnouislider

Events get unbound when I destroy slider


I need to update the slider's range and number formatting (format option) depending on user input. Since the format is not among the options I can update with updateOptions method I have to destroy the slider and create a new one. But the events I hooked the original slider to stop working although the docs say that 'events are not unbound when destroying a slider' https://refreshless.com/nouislider/more/ What's wrong with my code? Is there a way to bound the events back?

var slider = document.getElementById('slider');

noUiSlider.create(slider, {
    start: [ 1000000 ],
    step: 1000,
    connect: 'lower',
    range: {
        'min': [  500000 ],
        'max': [ 5000000 ]
    },
   format: rubleFormat
});

//code's getting redundant, I repeat it. Will fix later
function updateSlider(currency) {
  if(currency == 'USD') {
    slider.noUiSlider.destroy();
    noUiSlider.create(slider, {
        start: [ 10000 ],
        step: 100,
        connect: 'lower',
        range: {
            'min': [  5000 ],
            'max': [ 300000 ]
        },
       format: dollarFormat
    });
  }
  else {
    slider.noUiSlider.destroy();
    noUiSlider.create(slider, {
        start: [ 1000000 ],
        step: 1000,
        connect: 'lower',
        range: {
        'min': [  500000 ],
        'max': [ 5000000 ]
        },
      format: rubleFormat
    });
  }
}

Solution

  • Assuming rubleFormat and dollarFormat are instances of wNumb, you can switch out the formatter. Set format to cast to a Number:

    var currentFormatter = rubleFormat;
    
    function updateSlider(currency) {
        currentFormatter = currency === 'USD' ? dollarFormat : rubleFormat;
        slider.noUiSlider.updateOptions({ /* ... */ });
    }
    
    slider.noUiSlider.on('update', function(values, handle){
        input.value = currentFormatter.to(values[handle]);
    });
    
    input.addEventListener('change', function(){
        slider.noUiSlider.set(currentFormatter.from(this.value));
    });
    

    This will be way more performant than rebuilding the slider, too.

    Example.