2012-10-12 37 views
11

我试图找出如果淘汰赛JS会很好地工作以下问题:使用淘汰赛JS与jQuery UI的滑块

我有我要链接到文本框多个滑块。

当文本框被更改时,相应的滑块必须更新为新值,反之亦然。

在更改滑块值或文本框时,需要调用一个函数,该函数使用来自所有文本框的输入来计算结果。

我有我的快速和肮脏的jQuery解决方案here

使用knockout js以更优雅的方式实现相同的结果会很容易吗?

我想我需要创建一个像它的自定义绑定处理程序jQuery UI datepicker change event not caught by KnockoutJS

+0

您可以使用此库:http://gvas.github.io/knockout-jqueryui/slider.html –

回答

36

这里做的是一个例子:http://jsfiddle.net/jearles/Dt7Ka/

我用一个自定义绑定到淘汰赛整合了jQuery UI的滑块和使用捕获输入并计算净额。

-

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> 

视图模型

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) { 
    var value = ko.utils.unwrapObservable(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()); 
+1

谢谢!比我的jQuery sln更优雅​​ – woggles

+0

我看到它也限制了文本框的输入到滑块的范围...真棒:)有没有办法阻止用户输入除数字之外的任何内容?当一个字符被放置它它输出NaN – woggles

+0

我已经更新我的代码上面,并提琴,更新前检查数字。如果NaN将值重置为0. –

9

我知道这是前几天,但我做了一些调整,以约翰Earles代码:

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); 
} 
}; 

之所以这样s是如果你使用改变的选项(fx另一个可观察的),那么即使你想这样做,它也不会影响滑块。

2

@John Earles和@Michael Kire Hansen:谢谢你的精彩解决方案!

我使用了Michael Kire Hansen的高级代码。我将滑块的“max:”选项绑定到ko.observable,结果在这种情况下滑块不能正确更新值。示例:假设滑块的最大值为25,并且您将最大值更改为100,则滑块停留在最右边的位置,表示它处于最大值(但值仍然是25,而不是100)。只要你滑动一个指向左边,你得到的值更新为99

解决方案: 中的“更新”部分的最后两行只需切换到:

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

这种变化首先是选项,然后是价值,它就像魅力一样。

+0

我已更新我的答案与此修复程序,谢谢:) –

0

非常感谢您的帮助,我需要在我的情况下使用一系列滑块所以这里是一个扩展@约翰Earles和@迈克尔基雷汉森

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()); 
} 
}; 

,然后将HTML陪它

<div id="slider-range" 
      data-bind="sliderRange: { Min: 0, Max: 100 }, 
           sliderOptions: { 
            range: true, 
            min: 0, 
            max: 100, 
            step: 10, 
            values: [0, 100] 
           }"></div>