Thursday, May 10, 2012

Jquery UI slider how to make a box follow the handler?


I am trying to create a div that should follow the handler as it is seen here: http://m1.dk/Priser/#tab:#calc,#abb



My JSfiddle: http://jsfiddle.net/z3xV3/2/



I also want to make a calculation on the UI value that should appear in the box.



Here is a illustration what I want to achieve: enter image description here



HTML:




<div id="slider"></div>
<input id="sliderValue" />



Jquery:




$(document).ready(function() {


// Pris slider
$("#slider").slider({value:'',min: 0,max: 150,step: 1, range: 'min',
slide: function( event, ui ) {
$( "#amount" ).html( ui.value + ' timer');
}
});

$( "#amount" ).val( "$" + $( "#slider" ).slider( "value" ) );


});


Source: Tips4all

6 comments:

  1. I hope that's the effect you're looking for: http://jsfiddle.net/z3xV3/11/

    JS

    $(document).ready(function() {

    $("#slider").slider({value:'', min: 0, max: 150, step: 1, range: 'min'});

    var thumb = $($('#slider').children('.ui-slider-handle'));
    setLabelPosition();

    $('#slider').bind('slide', function () {
    $('#sliderValue').val($('#slider').slider('value'));
    setLabelPosition();
    });

    function setLabelPosition() {
    var label = $('#sliderValue');
    label.css('top', thumb.offset().top + label.outerHeight(true));
    label.css('left', thumb.offset().left - (label.width() - thumb.width())/ 2);
    }

    });


    HTML

    <div id="slider"></div>
    <input id="sliderValue" />


    CSS

    #sliderValue {
    position:absolute;
    width: 50px;
    }


    Best regards!

    ReplyDelete
  2. I have modifiered your jsfiddle example: http://jsfiddle.net/Dr5UR/

    $("#amount").val("$" + $("#slider").slider({
    slide: function(event, ui) {
    $('#sliderValue').css('left', event.clientX).val(ui.value);
    }
    }));


    I make use of the slide event of the slider.

    The slide event got two arguments:


    event

    This object contains several informations about the event itself. The time of triggering, the key which has been pressed or the coordinates of the mouse at the moment of triggering. The clientX property contains the position we need to set to the moving object.
    ui

    The ui object comes from jQuery UI itself. It basicly just contains the value. Additionally it contains the anchor which is used for dragging too. But you can't use its position, cause the slide event takes effect before the anchor takes its new position.




    The #slideValue input needs to have position: absolute;, cause I work with the left position attribute in CSS. You could also set the margin-left value, without need to set the position to absolute.

    ReplyDelete
  3. It's actually quite easy (and very useful) to turn this into a simple jQuery plugin. Like so:

    JSFiddle: http://jsfiddle.net/PPvG/huYRL/

    Note that I've added support for moving the slider by entering a value into the #sliderValue.

    [ Code sample removed ]

    You could also choose to remove #sliderValue from the HTML and let the plugin create it for you. In that case, you would rewrite the plugin so it would be called on the slider, instead of on #sliderValue. In my opinion, that would be a much neater solution.

    Update

    Based on your comments (and re-reading your question), I've rewritten the plugin example.

    If I understand correctly, you want to do some calculations based on the value of the slider and display the result of those calculations in the label below the slider handle. The following should make that really easy.

    JSFiddle: http://jsfiddle.net/PPvG/q5qg7/

    HTML

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


    Plugin

    (function($) {

    $.fn.sliderLabel = function(options) {

    var settings = $.extend({
    marginTop: 2,
    // Margin between the slider handle and the label (in pixels)
    callback: function(value) {
    return 'Value: ' + value;
    }
    }, options);

    return this.each(function() { // <- maintains chainability
    var slider = $(this);
    var handle = slider.children('.ui-slider-handle');
    var data = slider.data('sliderLabel');

    if (handle.length === 0) {
    // $(this) isn't a slider (it has no handle)
    console.log('[SliderLabel] Error: sliderLabel() can only be called on a slider.');
    return;
    }

    if (data === undefined) {
    // First time sliderLabel() is called on this slider
    data = {
    label: $('<div class="ui-slider-label" />').css('position', 'absolute'),
    callback: settings.callback
    };

    data.label.insertAfter(slider);

    function updateLabel() {
    var value = slider.slider('value');
    var labelText = data.callback(value);

    data.label.html(labelText);
    data.label.css('top', handle.offset().top + handle.outerHeight() + settings.marginTop);
    data.label.css('left', handle.offset().left - ((data.label.width() - handle.width()) / 2));
    }

    updateLabel();
    slider.bind('slide', updateLabel);

    } else {
    // sliderLabel() was called before; just update the callback:
    data.callback = settings.callback;
    updateLabel();
    }

    // Save (or update) the data inside the slider:
    slider.data('sliderLabel', data);
    });
    }
    })(jQuery);


    Usage

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

    $("#slider").sliderLabel({
    callback: function(value) {
    return value + '%';
    }
    });


    As you can see, the plugin is now called on the slider itself. You can now provide the plugin with a callback, which allows you to do some calculations and return a correctly formatted label (HTML is allowed).

    In the example above, the callback simply takes the value that is passed to the callbackand appends '%'.

    ReplyDelete
  4. It would be nice to take a look at alternative solutions with jQuery plugins such as:


    http://craigsworks.com/projects/qtip2/demos/#ui-slider
    http://www.filamentgroup.com/lab/update_jquery_ui_slider_from_a_select_element_now_with_aria_support/

    ReplyDelete
  5. Taking your jsfiddle.

    HTML:

    <div id="slider"></div>
    <input id="sliderValue" />


    CSS:

    #sliderValue{width:50px;}

    Jquery:

    $(document).ready(function() {


    // Pris slider
    $("#slider").slider({value:'',min: 0,max: 150,step: 1, range: 'min',
    slide: function( event, ui ) {
    $( "#sliderValue" ).val( ui.value + ' timer');
    var offset = $(this).find('a').css("left");
    $("#sliderValue").css("margin-left", offset);
    }
    });

    $( "#sliderValue" ).val($( "#slider" ).slider( "value" ));


    });

    ReplyDelete
  6. You can just: http://jsfiddle.net/z3xV3/21/

    $(document).ready(function() {
    $("#slider").slider({
    value:0,
    min: 0,
    max: 150,
    step: 1,
    range: 'min',
    slide: function( event, ui ) {
    var offsetLeft = $(this).find(".ui-slider-handle").offset().left;
    $( "#sliderValue" )
    .val( ui.value + ' timer')
    .css({
    "position": "absolute",
    "left": offsetLeft
    });
    }
    });
    });


    The slide callback is called every time you move your handle:

    offsetLeft is the offset of the handle.

    $( "#sliderValue" ) is your input.

    ReplyDelete