Paweł Reszka
Paweł Reszka

Reputation: 1557

Binding to class in knockout.js

I want to bind class of LI/DIV. I'm using knockout.js. I don't know how to make it works. This is my code:

<div id="users-list2" class="span8">
        <div class="tabbable">
            <!-- Only required for left/right tabs -->
            <ul class="nav nav-tabs" data-bind="foreach: conversations">
                <li data-bind="click: function () { $root.tabClick(username); }, attr:{ 'class': cls}" style="float:left"> 
                <a class="user-box-name" 
                     data-bind="text: username, attr:{ 'href':'#'+ username }, event: { contextmenu: $root.closeTab }"></a>
                </li>
            </ul>
            <div class="tab-content" data-bind="foreach: conversations">
                <div data-bind="attr:{ 'id': username, 'class': 'tab-pane ' + cls}">
                    <div id="chat-list" class="span12" data-bind="foreach: messages">
                        <ul>
                            <li>
                                <div class="chat-listitem-username" data-bind="text: username">
                                </div>
                                <div class="chat-listitem-message" data-bind="html: content">
                                </div>
                                <div class="chat-listitem-timestamp" data-bind="text: timestamp.toLocaleTimeString()">
                                </div>
                            </li>
                        </ul>
                    </div>
            </div>

and viewModel:

chatR.conversation = function (username) {
var self = this;
self.messages = ko.observableArray();
self.username = username;
self.test = function (x) { alert(x.username) };
self.cls = "";
}

I want to change cls to "active" when specific tab is clicked and change all others cls to "". It's not working. What am I doing wrong? Classes like "tabbable" and "nav" are defined by bootstrap.js.

EDIT: This is how I want to chnage cls:

self.tabClick = function (username) {
    self.currentConversation = username;
    for (i = 0; i < self.conversations().length; i++) {
        if (self.conversations()[i].username == username) {
            self.conversations()[i].cls = "active";
        }
        else {
            self.conversations()[i].cls = "";
        }
    }
}

EDIT2: Changes from comment work, but I have another problem. Li has class "active" but DIC gets:

<div id="aaa_1" class="tab-pane function d(){if(0<arguments.length)
{if(!d.equalityComparer||!d.equalityComparer(c,arguments[0]))d.H(),c=arguments[0],d.G();return this}b.r.Va(d);return c}" 
data-bind="attr:{ 'id': username, 'class':'tab-pane '+cls}">

What is wrong here?

Upvotes: 3

Views: 5750

Answers (3)

sdkljhdf hda
sdkljhdf hda

Reputation: 1407

Knockout has special binding for classes, a css binding (http://knockoutjs.com/documentation/css-binding.html).

Example:

<div data-bind='css: {classname: bla() == "something"}'>...</div>

Upvotes: 0

Ravi Y
Ravi Y

Reputation: 4376

Posting the details as an answer.

First Step was to make the cls property an observable and change the code to and change your code accordingly self.conversations()[i].cls("active"); or self.conversations()[i].cls("");

For the second as in edit.

You need output the value of cls and not cls as a whole

So change this

<div data-bind="attr:{ 'id': username, 'class': 'tab-pane ' + cls}">

to

<div data-bind="attr:{ 'id': username, 'class': 'tab-pane ' + cls()}">

Upvotes: 2

Jarek Mazur
Jarek Mazur

Reputation: 2072

Answer to edit 2: instead of

'tab-pane ' + cls 

use

'tab-pane ' + cls()

Upvotes: 1

Related Questions