balexandre
balexandre

Reputation: 75133

jQueryMobile: how to work with slider events?

I'm testing the slider events in jQueryMobile and I must been missing something.

page code is:

<div data-role="fieldcontain">
    <label for="slider">Input slider:</label>
    <input type="range" name="slider" id="slider" value="0" min="0" max="100"  />
</div>

and if I do:

$("#slider").data("events");

I get

blur, focus, keyup, remove

What I want to do is to get the value once user release the slider handle

and having a hook to the keyup event as

$("#slider").bind("keyup", function() { alert('here'); } );

does absolutely nothing :(

I must say that I wrongly assumed that jQueryMobile used jQueryUI controls as it was my first thought, but now working deep in the events I can see this is not the case, only in terms of CSS Design.

What can I do?

jQuery Mobile Slider source code can be found on Git if it helps anyone as well a test page can be found at JSBin


As I understand, the #slider is the textbox with the value, so I would need to hook into the slider handle as the generated code for this slider is:

<div data-role="fieldcontain" class="ui-field-contain ui-body ui-br">
    <label for="slider" class="ui-input-text ui-slider" id="slider-label">Input slider:</label>
    <input data-type="range" max="100" min="0" value="0" id="slider" name="slider" class="ui-input-text ui-body-null ui-corner-all ui-shadow-inset ui-body-c ui-slider-input" />
    <div role="application" class="ui-slider  ui-btn-down-c ui-btn-corner-all">
        <a class="ui-slider-handle ui-btn ui-btn-corner-all ui-shadow ui-btn-up-c" href="#" data-theme="c" role="slider" aria-valuemin="0" aria-valuemax="100" aria-valuenow="54" aria-valuetext="54" title="54" aria-labelledby="slider-label" style="left: 54%;">
            <span class="ui-btn-inner ui-btn-corner-all">
                <span class="ui-btn-text"></span>
            </span>
        </a>
    </div>
</div>

and checking the events in the handler anchor I get only the click event

$("#slider").next().find("a").data("events");

Fix

From Ivan answer, we just need:

<div data-role="fieldcontain">
    <label for="slider">Input slider:</label>
    <input type="range" name="slider" id="slider" value="0" min="0" max="100"  />
</div>

and then

$(document).bind("pagecreate", function(event, ui) {

    $('#slider').siblings('.ui-slider').bind('tap', function(event, ui){ makeAjaxChange($(this).siblings('input')); });
    $('#slider').siblings('.ui-slider a').bind('taphold', function(event, ui){ makeAjaxChange($(this).parent().siblings('input')); 

});

function makeAjaxChange( elem ) { 
    alert(elem.val()); 
}

Thank you Ivan for the heads up.

Upvotes: 12

Views: 36586

Answers (9)

grigb
grigb

Reputation: 1171

<input type="range" id="player-slider" value="25" min="0" max="100"/>

$( "#player-slider" ).bind( "change", function(event, ui) {
    alert ("changed!");
});

Upvotes: 1

keyur ajmera
keyur ajmera

Reputation: 63

Best and easy way you can check below link. you will get code for all mobile devices.

http://trentrichardson.com/2011/11/11/jquery-ui-sliders-and-touch-accessibility/

Upvotes: 0

Cristianpark
Cristianpark

Reputation: 186

Try this code:

$( "#slider-1").on('slidestop', function( event ) {
   var slider_value=$("#slider-1").slider().val();
   alert('Value: '+slider_value);
});

I hope this work for you

Upvotes: 9

JonnyReeves
JonnyReeves

Reputation: 6209

Based on @VTWood's solution; here's a generic 'fix' for all jQuery-Mobile 1.1 sliders so they dispatch start and stop events at the appropriate times. You just need to drop this code into your page once to patch up all future sliders.

$(document).on({
    "mousedown touchstart": function () {
        $(this).siblings("input").trigger("start");
    },
    "mouseup touchend": function () {
        $(this).siblings("input").trigger("stop");
    }
}, ".ui-slider");

In a nutshell, it binds an event listener to the document object which listens for both mousedown and touchstart events triggered from .ui-slider elements. Once triggered the handler function will find the input element which sits alongside the .ui-slider control that was clicked and trigger a start event. You can consume this like so:

$("#my-slider").on("start", function () { 
    console.log("User has started sliding my-slider!");
});

$("#my-slider").on("stop", function (event) {
    var value = event.target.value;
    console.log("User has finished sliding my slider, its value is: " + value);
});

Upvotes: 2

 $('#slider').next().children('a').bind('taphold', function () {
        $('#slider').live("change", function (event, ui) {
          //do these.....
        });
    });

Upvotes: 0

Aldo Reyes
Aldo Reyes

Reputation: 514

If you want to just catch the event when the slider is released (most probably to optimize ajax requests).

This worked for me:

var slider = $('#my_slider');
//as the answer from @nskeskin you have to remove the type range from your input on the html code
slider.slider({create:function(){
    //maybe this is too much hacking but until jquery provides a reference to this...
    $(this).next().children('a').bind('vmouseup', yourOnChangeCallback);
}
});

Also this prevents that you add events when the control is not yet initialized (or created), so waiting for the create event is a bit more correct I think.

Upvotes: 0

Anssi Moilanen
Anssi Moilanen

Reputation: 125

I found out that there's some issues in using Ivan's solution. If you drag the slider, pause for a while (not lifting the mouse button) and keep on dragging the slider the taphold -event won't be triggered anymore.

By adding the vmouseup and mouseup events in to the slider div you get an improvement but the slider still fails to trigger the event if the mouse cursor is moved away from above the slider.

Upvotes: 1

VTWoods
VTWoods

Reputation: 11

I found a much simpler solution to this problem. Using this code, you can retrofit start and stop events onto the slider.

$('.ui-slider').live('mousedown', function(){$('#'+id).trigger('start');});
$('.ui-slider').live('mouseup', function(){$('#'+id).trigger('stop');});
$('.ui-slider').live('touchstart', function(){$('#volumeSlider').trigger('start');});
$('.ui-slider').live('touchend', function(){$('#volumeSlider').trigger('stop');});

Upvotes: 1

Ivan Hušnjak
Ivan Hušnjak

Reputation: 3503

My solution to your problem is to hookup handlers on tap and taphold events. Tap is hooked on div element of slider, while taphold is hooked on a element (slider control button).

HTML markup of slider:

<div class="ui-field-contain ui-body ui-br" data-role="fieldcontain" id="element-boravak3">
     <label class="ui-input-text ui-slider" id="boravak3-label" for="boravak3">strop</label>
    <input class="ui-input-text ui-body-null ui-corner-all ui-shadow-inset ui-body-c ui-slider-input" name="boravak3" id="boravak3" value="0" min="0" max="100" data-type="range">
<!-- this is code that jQMobile generates -->
    <div role="application" class="ui-slider  ui-btn-down-c ui-btn-corner-all">
        <a class="ui-slider-handle ui-btn ui-btn-up-c ui-btn-corner-all ui-shadow" href="#" data-theme="c" role="slider" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0" aria-valuetext="0" title="0" aria-labelledby="boravak3-label" style="left: 0%;">
            <span class="ui-btn-inner ui-btn-corner-all">
                <span class="ui-btn-text"></span>
            </span>
        </a>
    </div>
</div>

JS:

$('#' + id).slider();
$('#' + id).siblings('.ui-slider').bind('tap', function(){ makeAjaxChange($(this).siblings('input')); });
$('#' + id).siblings('.ui-slider a').bind('taphold', function(){ makeAjaxChange($(this).parent().siblings('input')); });

Function makesAjaxChange(elem) makes the update to the server. There is one other thing to note here, changing value in input field does not updates server so you have to bind function to change event of input element. Also you must pay attention that by doing this every slider control move will trigger input element change so you have to workaround that too.

This is why jQuery Mobile is NOT jQuery UI for mobile devices. You dont have these things sorted out and must do them yourself.

I hope this helps.

EDIT: I forgot to explain why tap on div.ui-slider and taphold on a.ui-slider-handle. div.ui-handler tap is for click/tap event when user just clicks or taps a finger on slidebar. a.ui-slider-handle tabhold is after user was moving with mouse or finger left/right down the slidebar and released it.

Ivan

Upvotes: 8

Related Questions