0

I've got a jQuery UI slider. When the user uses a slider, the slider updates an attr variable in the div tag of the slider

$(".slider").each(function() {
var value = parseInt($(this).attr('data-init-value'), 10);
var amin = parseInt($(this).attr('data-min'), 10);
var amax = parseInt($(this).attr('data-max'), 10);
console.log(value, " ", amin, " ", amax)
$(this).empty().slider({
    value : value,
    min : amin,
    max : amax,
    range : "min",
    animate : true,
    slide : function(event, ui) {
        $(this).attr('data-value', ui.value);
    }
});

});

The example div tag in the html:

<div class="slider" data-min="200" data-max="600" data-init-value="300" data-bind="attr: { 'data-value': someValue }"></div>

When the slider is changed the data-value is updated in the <div> but the js variable doesn't change. (in other, trivial binding cases - like text: - it works.)

How to bind this action?

4spir
  • 1,174
  • 2
  • 15
  • 31
  • Could you try triggering .change() after you're done setting it? So `$(this).attr('data-value', ui.value).change();` I know `.val("value")` doesn't trigger the change event (which is what knockout listens to) so I'm guessing attr() doesn't, either. (Or you could do what Lasse suggested below, and update the knockout variable, instead). – Colin DeClue Apr 03 '13 at 18:41

2 Answers2

3

I suggest you do this the other way around. Bind the value of the slider to an observable property on your viewmodel, and then bind the attribute to that observable.

Then you can always access the most recent value of the slider directly through the viewmodel, and the UI will stay up to date as well.

And further, if you want to subscribe to the update event of that observable, you can bind to that as well. Here is an example from the documentation:

myViewModel.personName.subscribe(function(newValue) {
    alert("The person's new name is " + newValue);
});

And finally, this might as well be a possible duplicate of: Identify the attribute change event in KnockoutJS?

-- Update to answer comments

Given the following viewmodel:

var viewModel = {
    mySliderValue: ko.observable(0)
};

Then, in your slider callback, you could do something like this:

viewModel.mySliderValue(value);

And then, in your view, having the following attr binding:

data-bind="attr: { 'data-value': mySliderValue }"

... will cause the UI to update when the observable changes its value.

PS. I suggest you no longer delete this thread since my answer is starting to deviate more and more from the one I linked to.

Community
  • 1
  • 1
Lasse Christiansen
  • 10,205
  • 7
  • 50
  • 79
  • how can i bind the value of the slider to an observable property on my viewmodel? – 4spir Apr 03 '13 at 18:57
  • ok, thats great, but i've got numerous sliders and i want to bind them to diffrent variables, so each slider should be binded to a different variable, and the method above works only if i list all my variables in the js at slider initialization at `slide : function(){...}`. i think that it's more dinamic to use the data-bind with attr isn't it? – 4spir Apr 03 '13 at 19:18
  • First of all, if this works and solves your problem, I'm happy about that and I'll be glad if you would accept the answer :) Secondly, I don't quite understand the question you are asking in your most recent comment - you mention you have multiple sliders - what is the problem in binding each of them to their own observable? – Lasse Christiansen Apr 03 '13 at 19:22
  • let us assume that we have n sliders with n variables that have to be binded. the variables were pushed into an array, and the sliders were also generated from a server-side script. how would you handle that with bind? – 4spir Apr 03 '13 at 19:22
  • As far as I can tell, that is another question :) The current question assumes the existence of one slider, quote: "I've got a jQuery UI slider", so I believe what you are asking now, belongs in a new question. And again, if the above solved your problem, please accept it :) – Lasse Christiansen Apr 03 '13 at 19:25
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/27508/discussion-between-zeal-and-lasse-christiansen-sw-lasse) – 4spir Apr 03 '13 at 19:27
  • i can't accept your answer because you ignored the abstraction in the slider's initialization code. sorry. – 4spir Apr 03 '13 at 19:51
0

The way to do it is to register an event handler.

o.utils.registerEventHandler(element, "slidechange", function (event, ui) {
   var observable = valueAccessor();
   observable(ui.value);
});

JSFiddle for full example: http://jsfiddle.net/snLk8/3/

4spir
  • 1,174
  • 2
  • 15
  • 31