2012-10-12 37 views
11

Tôi đang cố gắng tìm hiểu xem loại trực tiếp js sẽ làm việc độc đáo cho các vấn đề sau đây:Sử dụng loại trực tiếp js với thanh trượt ui jquery

Tôi có nhiều thanh trượt mà tôi muốn liên kết đến textbox.

Khi hộp văn bản được thay đổi, thanh trượt tương ứng phải cập nhật giá trị mới và ngược lại.

Khi thay đổi giá trị thanh trượt hoặc hộp văn bản, chức năng cần được gọi là sử dụng đầu vào từ tất cả các hộp văn bản để tính toán kết quả.

Tôi có giải pháp jQuery nhanh chóng và dơ bẩn của mình here.

Bạn có dễ dàng đạt được kết quả tương tự một cách thanh lịch hơn bằng cách sử dụng jpg loại trực tiếp không?

Tôi đoán tôi sẽ cần phải tạo một handler tùy chỉnh ràng buộc như nó thực hiện trong jQuery UI datepicker change event not caught by KnockoutJS

+0

Bạn có thể sử dụng thư viện này: http://gvas.github.io/knockout-jqueryui/slider.html –

Trả lời

36

Dưới đây là một ví dụ: http://jsfiddle.net/jearles/Dt7Ka/

tôi sử dụng một tùy chỉnh ràng buộc để tích hợp các thanh trượt jquery-ui và sử dụng Knockout để nắm bắt các đầu vào và tính toán số tiền ròng.

-

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> 

Xem Mẫu

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

Cảm ơn! Cách thanh lịch hơn jQuery của tôi sln – woggles

+0

Tôi thấy rằng nó cũng giới hạn đầu vào của hộp văn bản đến phạm vi của các thanh trượt ... tuyệt vời :) Có cách nào để ngăn chặn người dùng nhập bất cứ điều gì nhưng số? Khi một ký tự được đặt, nó sẽ xuất ra NaN – woggles

+0

Tôi đã cập nhật mã của mình ở trên, và fiddle, để kiểm tra số trước khi cập nhật. Nếu NaN nó đặt lại giá trị thành 0. –

9

Tôi biết đó là vài ngày trước, nhưng tôi đã thực hiện một vài điều chỉnh để mã John 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); 
} 
}; 

Lý do cho thi s là nếu bạn sử dụng các tùy chọn thay đổi (fx một quan sát khác) thì nó sẽ không ảnh hưởng đến thanh trượt ngay cả khi bạn muốn nó làm như vậy.

2

@John Earles và @Michael Kire Hansen: cảm ơn các giải pháp tuyệt vời của bạn!

Tôi đã sử dụng mã nâng cao từ Michael Kire Hansen. Tôi gắn tùy chọn "max:" của thanh trượt vào một ko.observable và nó bật ra rằng thanh trượt không cập nhật chính xác giá trị trong trường hợp này. Ví dụ: Cho phép nói thanh trượt có giá trị 25 của tối đa 25 und bạn thay đổi giá trị tối đa thành 100, thanh trượt ở vị trí phù hợp nhất, cho biết giá trị đó ở giá trị lớn nhất (nhưng giá trị vẫn là 25, không phải 100). Ngay sau khi bạn trượt một điểm sang bên trái, bạn nhận được các giá trị được cập nhật đến 99.

Giải pháp: trong "update:" phần chỉ chuyển hai dòng cuối cùng để:

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

thay đổi này các tùy chọn đầu tiên, sau đó giá trị và nó hoạt động như một sự quyến rũ.

+0

Tôi đã cập nhật câu trả lời của mình với bản sửa lỗi này, cảm ơn :) –

0

Cảm ơn rất nhiều sự giúp đỡ, tôi cần phải sử dụng một thanh trượt phạm vi trong kịch bản của tôi vì vậy đây là một phần mở rộng để @ John Earles và @ 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()); 
} 
}; 

và sau đó là HTML để đi cùng với nó

<div id="slider-range" 
      data-bind="sliderRange: { Min: 0, Max: 100 }, 
           sliderOptions: { 
            range: true, 
            min: 0, 
            max: 100, 
            step: 10, 
            values: [0, 100] 
           }"></div> 
Các vấn đề liên quan