1
votes

I'm trying to create a custom tooltip that displays inside the draghandle of a Kendo slider and dynamically updates as the draghandle is moved.

I've been able to do this in the past using plain Kendo by updating the text of the custom tooltip with a slide function, like so:

element.kendoSlider({
    min: 0,
    max: 100,
    tooltip: { 'enabled': false },
    slide: sliderOnSlide,
    tickPlacement: 'none',
    showButtons: false,
    smallStep: 1,
    largeStep: 1
});

var slider = element.data('kendoSlider');

slider.wrapper.find('.k-draghandle').empty().html('<span class="sliderTip">0%</span>');

function sliderOnSlide(e) {
    $('.k-draghandle.draggerOn .sliderTip').empty().text(e.value.toString() + '%');
}

I imagine this can be accomplished more cleanly and reliably with Knockout, but so far I've not been successful. I've attempted to get at the draghandle by using a Knockout custom binding handler:

<input class="slider col" data-bind="kendoSlider: { value: currValue, enabled: enabled, min: 0, max: 100, tickPlacement: 'none', smallStep: 1 }, sliderTip: {}" />

var viewModel = function () {
    this.currValue = ko.observable(0);
    this.enabled = ko.observable(true);
    this.width = ko.observable();
};

ko.bindingHandlers.sliderTip = {
    init: function(element, valueAccessor) {
        var dragger = $(element).closest('.k-slider').find('.k-draghandle');

        dragger.empty().html('<span class="sliderTip">0%</span>');
    } 
};

ko.applyBindings(new viewModel());

I've been able to insert my custom tooltip, but it's not displaying, and I can't figure out how to get it updating dynamically. My attempts to shoehorn my sliderOnSlide function into Kendo-Knockout have been unsuccessful.

Would be delighted to get some help on this one. Here's a JSFiddle I've been experimenting with that contains the code listed above and the corresponding HTML/CSS: http://jsfiddle.net/MontiDesign/DuZK3/17/

2

2 Answers

1
votes

I am not sure exactly how you want it to look/behave, but one option woudl be to create your sliderTip element in the custom binding, then bind to the slide event of the kendoSlider widget that was created on the same element.

Would be something like:

ko.bindingHandlers.sliderTip = {
    init: function(element, valueAccessor, allBindings) {
        var slider = $(element).data("kendoSlider"),
            tip;

        if (slider) {
            tip = $('<span class="sliderTip">0%</span>');
            slider.wrapper.find('.k-draghandle').empty().append(tip);  

            slider.bind("slide", function(e) {
               tip.empty().text(e.value.toString() + "%"); 
            });
        }  
    }
};

Sample: http://jsfiddle.net/rniemeyer/y6a6s/

0
votes

Your code was perfectly fine in fact.

After digging in the CSS with Chrome's debugger (how can you live without it... ?) I've seen that the k-draghandle element has its text-indent property set to -3333px. This explains why anything you put inside does not show up at all.

My fix is to add just one line in your custom binding handler to remove this text-indent:

ko.bindingHandlers.sliderTip = {
    init: function(element, valueAccessor) {
        var dragger = $(element).closest('.k-slider').find('.k-draghandle');   
        dragger.css("text-indent", "0px");
        dragger.empty().html('<div class="sliderTip">' + valueAccessor() + '</div>');
    },
};

Now, I'm not sure about the possible side effects of this, but in your example it works perfectly without damaging the display. But... there certainly is a reason why this indent was put there.

Here is the updated fiddle.