Home > Back-end >  jQuery UI Range Slider, before change event or get value without changing?
jQuery UI Range Slider, before change event or get value without changing?

Time:03-12

I'm using jQuery UI Range slider https://jqueryui.com/slider/#range and I want to click between the two points and get the value of where I clicked, without initiating a change event. So the two points wouldn't move. There isn't a before change event.

$("#slider-range").slider({
    range: true,
    min: min,
    max: max,
    step: 1,
    values: [start, end],
    create: function( event, ui ) {
        update_tooltips(0);
    },
    change: function( event, ui ) {
        var index = ui.handleIndex;
        var seconds = ui.value;
    }
});

How do I accomplish this?

CodePudding user response:

There isn't a before change event.

No, but you were on the right track. I expermiented with all the available methods, and found a few things:

  • if you click on the slider track, the sequence of events is .start(), .slide(), .stop(), .change();

  • All methods receive the event as a paramter, and in the .start() method, we can identify if the click was on a handle by inspecting the event.originalEvent.target;

  • The event target info is different by the time we reach the .slide() method, AFAICT we can no longer find out what was originally clicked at this point. So we have to track what was clicked before we get here;

  • The slide() docs say:

    The value provided in the event as ui.value represents the value that the handle will have as a result of the current movement. Canceling the event will prevent the handle from moving

    So this is the key - we can get the clicked value, but we can still cancel the actual change. It doesn't describe how to cancel the event, but I tried return false; and that does the trick;

Putting all this together:

let min = 0, max = 100;
let start = 20, end = 80;

// Add a variable to track where the click was
let clickOnHandle;

$("#slider-range").slider({
    range: true,
    min: min,
    max: max,
    step: 1,
    values: [start, end],
    create: function( event, ui ) {
        console.log('create');
    },
    start: function(event, ui) {
        // Add a start handler, where we can investigate what was clicked
        console.log('start');
                
        // If this was a click on a handle, it will have this class. 
        // Track that boolean result with our variable.
        clickOnHandle = $(event.originalEvent.target).hasClass('ui-slider-handle');
    },
    stop: function(event, ui) {
        console.log('stop');
    },
    slide: function(event, ui) {
        // Add a slide handler
        console.log('slide', ui.value);
        
        // If the click was not on a handle, we can bail out and stop
        // the actual change from happening, while still getting the
        // clicked value.
        if (! clickOnHandle) {
            $('#clicked').text(ui.value);
            return false;
        }
        
        // If this was a real change, update the display
        $('#value').text(ui.value);
    },
    change: function(event, ui) {
        console.log('change');
    }
});
<link href="https://code.jquery.com/ui/1.13.1/themes/base/jquery-ui.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.13.1/jquery-ui.min.js"></script>

<div id="slider-range"></div>

<div>
    <p>Current Value: <span id="value">20</span></p>
    <p>Clicked Value: <span id="clicked"></span></p>
</div>

  • Related