Reputation: 19700
I have a bit of javascript:
function ViewModel() {
var self = this;
self.highlight = ko.observable(true);
}
ko.applyBindings(new ViewModel());
And the html that complements it:
<div data-bind="css: { highlighted: highlight }, click: highlight( !highlight() )">
random string
</div>
What I'm trying to achieve:
What I'm getting:
true
, yet the css class starts deactivated (if I change the initial value to false
, the css class is activated: which seems as if I've somehow triggered the click bind when I haven't yet clicked anything)I'd rather not make a new corresponding click function inside ViewModel. I'm looking if possible for a bit of code I can place solely inline within the data-bind.
Here's the code on JSFiddle: http://jsfiddle.net/4wt4x/1/
Can anyone explain what's happening and what I'm doing incorrectly?
Upvotes: 21
Views: 19379
Reputation: 2105
Another option is to use a reusable custom function extension (custom function is used instead of extender because there are no parameters and it looks cleaner):
ko.observable.fn.toggleable = function () {
var self = this;
self.toggle = function () {
self(!self());
};
return self;
};
Usage
self.highlight = ko.observable(true).toggleable();
Html
<div data-bind="css: { highlighted: highlight }, click: highlight.toggle">
random string
</div>
Upvotes: 7
Reputation: 91
If you really want to do it inline:
<div data-bind="click: highlight.bind($root, !highlight()), css: { highlighted: highlight } ">
random string
</div>
where highlight is the boolean observable.
Upvotes: 4
Reputation: 4541
I know it's an old question, but maybe could help someone. If you need to use toggle in a lot of places, maybe some custom binding sugar could help you:
Binding:
ko.bindingHandlers.toggleClick = {
init: function (element, valueAccessor) {
var value = valueAccessor();
ko.utils.registerEventHandler(element, "click", function () {
value(!value());
});
}
};
Usage:
<div data-bind="css: { highlighted: highlight }, toggleClick: highlight">
random string
</div>
Example:
This approach keeps some of my views very cleaner. Hope it helps.
Upvotes: 44
Reputation: 4821
Your click: highlight( !highlight() )
is incorrect. Click is going to try to execute a function, and when the binding was initialized, highlight would have returned whatever its value was and that is what click is going to try to execute (true
or false
in your case). You need to do something like this:
In your javascript, place in your model:
self.toggleHighlight = function () { self.highlight(!self.highlight()) };
Then change the binding to say click: toggleHighlight
Like so: http://jsfiddle.net/KDypD/1/
You may need to adjust your highlight initial value as well to reflect how you want the page to show up initially.
Upvotes: 22