Using knockout js with jquery ui sliders

后端 未结 4 1627
时光取名叫无心
时光取名叫无心 2020-12-01 14:50

I\'m trying to figure out if knockout js would work nicely for the following problem:

I have multiple sliders that I want to link to textboxes.

When the tex

相关标签:
4条回答
  • 2020-12-01 15:31

    @John Earles and @Michael Kire Hansen: thanks for your wonderful solutions!

    I used the advanced code from Michael Kire Hansen. I tied the "max:" option of the slider to a ko.observable and it turned out that the slider does not correctly update the value in this case. Example: Lets say the slider is at value 25 of max 25 und you change the max value to 100, the slider stays at the most right position, indicating that it is at the max value (but value is still 25, not 100). As soon as you slide one point to the left, you get the value updated to 99.

    Solution: in the "update:" part just switch the last two lines to:

    $(element).slider("option", allBindingsAccessor().sliderOptions);
    $(element).slider("value", value);
    

    This changes the options first, then the value and it works like a charm.

    0 讨论(0)
  • 2020-12-01 15:39

    Here is an example: http://jsfiddle.net/jearles/Dt7Ka/

    I use a custom binding to integrate the jquery-ui slider and use Knockout to capture the inputs and calculate the net amount.

    --

    UI

    <h2>Slider Demo</h2>
    
    Savings: <input data-bind="value: savings, valueUpdate: 'afterkeydown'" />
    <div style="margin: 10px" data-bind="slider: savings, sliderOptions: {min: 0, max: 100, range: 'min', step: 1}"></div>
    
    Spent: <input data-bind="value: spent, valueUpdate: 'afterkeydown'" />
    <div style="margin: 10px" data-bind="slider: spent, sliderOptions: {min: 0, max: 100, range: 'min', step: 1}"></div>
    
    Net: <span data-bind="text: net"></span>
    

    View Model

    ko.bindingHandlers.slider = {
      init: function (element, valueAccessor, allBindingsAccessor) {
        var options = allBindingsAccessor().sliderOptions || {};
        $(element).slider(options);
        $(element).slider({
            "slide": function (event, ui) {
                var observable = valueAccessor();
                observable(ui.value);
            },
            "change": function (event, ui) {
                var observable = valueAccessor();
                observable(ui.value);
            }
        });
        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
            $(element).slider("destroy");
        });
      },
      update: function (element, valueAccessor) {
        var value = ko.unwrap(valueAccessor());
        if (isNaN(value)) {
            value = 0;
        }
        $(element).slider("value", value);
      }
    };
    
    var ViewModel = function() {
        var self = this;
    
        self.savings = ko.observable(10);
        self.spent = ko.observable(5);
        self.net = ko.computed(function() {
            return self.savings() - self.spent();
        });
    }
    
    ko.applyBindings(new ViewModel());
    
    0 讨论(0)
  • 2020-12-01 15:41

    Thanks so much for the help, I needed to use a range slider in my scenario so here is an extension to @John Earles and @Michael Kire Hansen

    ko.bindingHandlers.sliderRange = {
    init: function (element, valueAccessor, allBindingsAccessor) {
        var options = allBindingsAccessor().sliderOptions || {};
        $(element).slider(options);
        ko.utils.registerEventHandler(element, "slidechange", function (event, ui) {
            var observable = valueAccessor();
            observable.Min(ui.values[0]);
            observable.Max(ui.values[1]);
        });
        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
            $(element).slider("destroy");
        });
        ko.utils.registerEventHandler(element, "slide", function (event, ui) {
            var observable = valueAccessor();
            observable.Min(ui.values[0]);
            observable.Max(ui.values[1]);
        });
    },
    update: function (element, valueAccessor, allBindingsAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        if (isNaN(value.Min())) value.Min(0);
        if (isNaN(value.Max())) value.Max(0);
    
        $(element).slider("option", allBindingsAccessor().sliderOptions);
        $(element).slider("values", 0, value.Min());
        $(element).slider("values", 1, value.Max());
    }
    };
    

    and then the HTML to accompany it

    <div id="slider-range" 
                 data-bind="sliderRange: { Min: 0, Max: 100 }, 
                                    sliderOptions: { 
                                        range: true,
                                        min: 0,
                                        max: 100,
                                        step: 10,
                                        values: [0, 100]
                                    }"></div>
    
    0 讨论(0)
  • 2020-12-01 15:48

    I know it's some days ago but I made a few adjustments to John Earles code:

    ko.bindingHandlers.slider = {
    init: function (element, valueAccessor, allBindingsAccessor) {
        var options = allBindingsAccessor().sliderOptions || {};
        $(element).slider(options);
        ko.utils.registerEventHandler(element, "slidechange", function (event, ui) {
            var observable = valueAccessor();
            observable(ui.value);
        });
        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
            $(element).slider("destroy");
        });
        ko.utils.registerEventHandler(element, "slide", function (event, ui) {
            var observable = valueAccessor();
            observable(ui.value);
        });
    },
    update: function (element, valueAccessor, allBindingsAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        if (isNaN(value)) value = 0;
        $(element).slider("option", allBindingsAccessor().sliderOptions);
        $(element).slider("value", value);
    }
    };
    

    The reason for this is that if you use options that change (fx another observable) then it won't affect the slider even if you wanted it to do so.

    0 讨论(0)
提交回复
热议问题