Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

KnockoutJS value toggling in data-bind

Tags:

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:

  1. The css class 'highlighted' to only be activated when var highlight is true
  2. Clicking on the div will toggle the bool value of var highlight
  3. Wanted result: clicking on the div to activate/deactivate its css class

What I'm getting:

  1. The initial value of highlight is 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)
  2. The div's css class does not toggle on click

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?

like image 485
dk123 Avatar asked Feb 14 '13 04:02

dk123


People also ask

How do I assign a value to Knockout observable?

To create an observable, assign the ko. observable function to the variable. A default value can be specified in the constructor of the call. Knockout then converts your variable into a function and tracks when the value changes, in order to notify the UI elements associated with the variable.

What is data bind Knockout?

Knockout's declarative binding system provides a concise and powerful way to link data to the UI. It's generally easy and obvious to bind to simple data properties or to use a single binding.

What is KnockoutJS used for?

KnockoutJS is basically a library written in JavaScript, based on MVVM pattern that helps developers build rich and responsive websites.


2 Answers

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:

http://jsfiddle.net/A28UD/1/

This approach keeps some of my views very cleaner. Hope it helps.

like image 151
Kim Tranjan Avatar answered Sep 28 '22 10:09

Kim Tranjan


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.

like image 33
Los Frijoles Avatar answered Sep 28 '22 08:09

Los Frijoles