CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-nouislider

Lightweight JavaScript range slider with no dependencies

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

configuration-updates.mddocs/

Configuration Updates

Runtime configuration updates and slider reconfiguration capabilities for dynamic slider behavior modification.

Capabilities

updateOptions()

Updates slider configuration at runtime, allowing dynamic reconfiguration without recreating the slider.

/**
 * Update slider configuration at runtime
 * @param optionsToUpdate - Partial configuration object with options to update
 * @param fireSetEvent - Whether to fire 'set' event after update (default: undefined -> true)
 */
slider.noUiSlider.updateOptions(
    optionsToUpdate: Partial<SliderOptions>, 
    fireSetEvent?: boolean
): void;

Usage Examples:

// Update range dynamically
slider.noUiSlider.updateOptions({
    range: {
        'min': 0,
        'max': 200  // Changed from 100 to 200
    }
});

// Update multiple options
slider.noUiSlider.updateOptions({
    step: 5,
    margin: 10,
    animate: false
});

// Update without triggering events
slider.noUiSlider.updateOptions({
    start: [30, 70]
}, false);

options Property

Access to the current configuration object.

/**
 * Current slider configuration (read-only)
 */
slider.noUiSlider.options: SliderOptions;

Usage Examples:

// Get current configuration
const currentConfig = slider.noUiSlider.options;
console.log('Current range:', currentConfig.range);
console.log('Current step:', currentConfig.step);

// Use current config to make conditional updates
if (currentConfig.step !== 10) {
    slider.noUiSlider.updateOptions({ step: 10 });
}

Updatable Options

Value and Range Options

range

Update the value range and stepping configuration.

// Basic range update
slider.noUiSlider.updateOptions({
    range: {
        'min': -50,
        'max': 150
    }
});

// Complex range with stepping
slider.noUiSlider.updateOptions({
    range: {
        'min': [0, 1],      // Min 0, step 1
        '25%': [25, 5],     // At 25%, value 25, step 5
        '75%': [75, 10],    // At 75%, value 75, step 10
        'max': 100
    }
});

step

Update the step size for value increments.

slider.noUiSlider.updateOptions({
    step: 0.5  // Changed from integer to decimal stepping
});

start

Update initial/current values (will reposition handles).

slider.noUiSlider.updateOptions({
    start: [25, 75]  // Moves handles to new positions
});

Constraint Options

margin

Update minimum distance between handles.

slider.noUiSlider.updateOptions({
    margin: 15  // Handles must be at least 15 units apart
});

limit

Update maximum distance between handles.

slider.noUiSlider.updateOptions({
    limit: 50  // Handles cannot be more than 50 units apart
});

padding

Update padding from slider edges.

// Symmetric padding
slider.noUiSlider.updateOptions({
    padding: 10
});

// Asymmetric padding
slider.noUiSlider.updateOptions({
    padding: [5, 15]  // 5 from start, 15 from end
});

Behavior Options

snap

Toggle snap-to-step behavior.

slider.noUiSlider.updateOptions({
    snap: true  // Enable snapping to step values
});

animate

Toggle animation behavior.

slider.noUiSlider.updateOptions({
    animate: false  // Disable smooth animations
});

UI Options

format

Update value formatting.

// Switch to percentage formatting
slider.noUiSlider.updateOptions({
    format: {
        to: function(value) {
            return value.toFixed(1) + '%';
        },
        from: function(value) {
            return parseFloat(value.replace('%', ''));
        }
    }
});

tooltips

Update tooltip configuration.

// Enable tooltips
slider.noUiSlider.updateOptions({
    tooltips: true
});

// Custom tooltip formatting
slider.noUiSlider.updateOptions({
    tooltips: {
        to: function(value) {
            return '$' + Math.round(value);
        }
    }
});

// Per-handle tooltip configuration
slider.noUiSlider.updateOptions({
    tooltips: [true, false]  // First handle has tooltip, second doesn't
});

pips

Update scale markers.

// Add pips
slider.noUiSlider.updateOptions({
    pips: {
        mode: 'count',
        values: 5,
        density: 3
    }
});

// Remove pips
slider.noUiSlider.updateOptions({
    pips: null
});

Practical Usage Patterns

Dynamic Range Adjustment

// Adjust range based on data availability
function updateSliderRange(minValue, maxValue) {
    slider.noUiSlider.updateOptions({
        range: {
            'min': minValue,
            'max': maxValue
        }
    });
    
    // Ensure current values are within new range
    const currentValues = slider.noUiSlider.get();
    const adjustedValues = currentValues.map(val => {
        const num = parseFloat(val);
        return Math.max(minValue, Math.min(maxValue, num));
    });
    
    slider.noUiSlider.set(adjustedValues);
}

// Usage
updateSliderRange(0, 500);  // Expand range
updateSliderRange(10, 90);  // Contract range

Responsive Configuration

// Adjust configuration based on screen size
function updateSliderForScreenSize() {
    const isMobile = window.innerWidth < 768;
    
    slider.noUiSlider.updateOptions({
        step: isMobile ? 10 : 1,          // Larger steps on mobile
        margin: isMobile ? 20 : 5,        // More margin on mobile
        tooltips: isMobile ? false : true  // No tooltips on mobile
    });
}

// Apply on resize
window.addEventListener('resize', updateSliderForScreenSize);
updateSliderForScreenSize(); // Initial setup

Mode Switching

// Switch between different slider modes
function switchSliderMode(mode) {
    switch (mode) {
        case 'currency':
            slider.noUiSlider.updateOptions({
                format: {
                    to: value => '$' + Math.round(value).toLocaleString(),
                    from: value => Number(value.replace(/[$,]/g, ''))
                },
                step: 100,
                tooltips: true
            });
            break;
            
        case 'percentage':
            slider.noUiSlider.updateOptions({
                format: {
                    to: value => value.toFixed(1) + '%',
                    from: value => parseFloat(value.replace('%', ''))
                },
                step: 0.1,
                tooltips: true
            });
            break;
            
        case 'simple':
            slider.noUiSlider.updateOptions({
                format: {
                    to: value => Math.round(value).toString(),
                    from: Number
                },
                step: 1,
                tooltips: false
            });
            break;
    }
}

Conditional Updates

// Update options based on current state
function updateSliderBasedOnValue() {
    const values = slider.noUiSlider.get();
    const maxValue = Math.max(...values.map(parseFloat));
    
    if (maxValue > 80) {
        // High values - use larger steps and different formatting
        slider.noUiSlider.updateOptions({
            step: 10,
            format: {
                to: value => 'High: ' + Math.round(value),
                from: value => Number(value.replace('High: ', ''))
            }
        });
    } else {
        // Normal values
        slider.noUiSlider.updateOptions({
            step: 1,
            format: {
                to: value => Math.round(value).toString(),
                from: Number
            }
        });
    }
}

// Apply on value changes
slider.noUiSlider.on('change', updateSliderBasedOnValue);

Configuration Persistence

// Save and restore slider configuration
function saveSliderConfig() {
    const config = {
        range: slider.noUiSlider.options.range,
        step: slider.noUiSlider.options.step,
        margin: slider.noUiSlider.options.margin,
        values: slider.noUiSlider.get()
    };
    
    localStorage.setItem('sliderConfig', JSON.stringify(config));
}

function restoreSliderConfig() {
    const saved = localStorage.getItem('sliderConfig');
    if (saved) {
        const config = JSON.parse(saved);
        
        slider.noUiSlider.updateOptions({
            range: config.range,
            step: config.step,
            margin: config.margin,
            start: config.values
        });
    }
}

// Auto-save on changes
slider.noUiSlider.on('change', saveSliderConfig);

Non-Updatable Options

Some options cannot be changed after slider creation and require recreating the slider:

  • connect - Connection configuration
  • direction - Text direction (ltr/rtl)
  • orientation - Physical orientation (horizontal/vertical)
  • behaviour - Interaction behaviors
  • keyboardSupport - Keyboard navigation
  • keyboardPageMultiplier - Keyboard step multipliers
  • keyboardDefaultStep - Default keyboard step
  • cssPrefix - CSS class prefix
  • cssClasses - CSS class names
  • documentElement - Document element reference
// These options require slider recreation
function recreateSliderWithNewBehavior() {
    const currentValues = slider.noUiSlider.get();
    const currentRange = slider.noUiSlider.options.range;
    
    // Destroy current slider
    slider.noUiSlider.destroy();
    
    // Create new slider with different behavior
    noUiSlider.create(slider, {
        start: currentValues,
        range: currentRange,
        behaviour: 'drag-fixed',  // This requires recreation
        connect: true
    });
}

Error Handling

// Some updates may fail if they create invalid configurations
try {
    slider.noUiSlider.updateOptions({
        range: {
            'min': 100,
            'max': 0  // Invalid: min > max
        }
    });
} catch (error) {
    console.error('Invalid range configuration:', error.message);
}

// Values outside new range are automatically adjusted
slider.noUiSlider.updateOptions({
    range: { 'min': 0, 'max': 50 }  // Shrink range
});
// Current values above 50 will be adjusted to 50

Performance Considerations

// Batch updates for better performance
slider.noUiSlider.updateOptions({
    range: { 'min': 0, 'max': 200 },
    step: 5,
    margin: 10,
    format: newFormatter
});

// Instead of multiple separate updates:
// slider.noUiSlider.updateOptions({ range: { 'min': 0, 'max': 200 }});
// slider.noUiSlider.updateOptions({ step: 5 });
// slider.noUiSlider.updateOptions({ margin: 10 });
// slider.noUiSlider.updateOptions({ format: newFormatter });

Install with Tessl CLI

npx tessl i tessl/npm-nouislider

docs

configuration-updates.md

event-handling.md

index.md

slider-creation.md

ui-enhancements.md

value-management.md

tile.json