Knockout: Change css class based on value of observable

10,822

Solution 1

You cannot pass value into computed in such way. It is better to add this computed to Notification view model and use self.availability property:

function Notification(root, sip, availability, note) {
    var self = this;

    self.sip = ko.observable(sip);
    self.availability = ko.observable(availability);
    self.note = ko.observable(note);

    self.availabilityCssClass = ko.computed(function() {
        var availability = self.availability();

        if (["Busy", "DoNotDisturb", "BeRightBack"].indexOf(availability) != -1) return "leftStatusCellColorOrange";
        else if (["Away", "Offline"].indexOf(availability) != -1) return "leftStatusCellColorRed";
        else return "leftStatusCellColorGreen";
    });
};

Your if statement wasn't correct, so I fixed the logic. Here is working fiddle: http://jsfiddle.net/vyshniakov/Jk7Fd/

Solution 2

You just need to make availabilityCssClass a function. As you've written it, it's not a computed observable since it has no observable dependencies.

self.availabilityCssClass = function (value) {
    var availability = value;
    if (availability === "Busy" || "DoNotDisturb" || "BeRightBack")
        return "leftStatusCellColorOrange";
    else if (availability === "Away" || "Offline")
        return "leftStatusCellColorRed";
    else
        return "leftStatusCellColorGreen";
};
Share:
10,822
mupersan82
Author by

mupersan82

Updated on June 22, 2022

Comments

  • mupersan82
    mupersan82 about 2 years

    I use foreach on an observable array:

    <div id="mainRight" data-bind="foreach: notifications">
        <div class="statusRow">
            <div class="leftStatusCell">
                <div class="leftStatusCellColor" data-bind="css: availabilityCssClass($data.availability)"></div>
            </div>
            <div class="topRightStatusCell" data-bind="text: sip"></div>
            <div class="bottomtRightStatusCell ellipsisSingleline" data-bind="text: note"></div>
        </div>
    </div> <!== end mainRight ==>
    

    As you can see, I pass the current value of availability to the function availabilityCssClass, which compares the value to some predefined strings. Depending on the matching string, it returns a class name.

    self.availabilityCssClass = ko.computed(function (value) {
        var availability = value;
        if (availability === "Busy" || "DoNotDisturb" || "BeRightBack")
            return "leftStatusCellColorOrange";
        else if (availability === "Away" || "Offline")
            return "leftStatusCellColorRed";
        else
            return "leftStatusCellColorGreen";
    });
    

    This is my model. The data comes from an external data source.

    function Notification(root, sip, availability, note) {
        var self = this;
    
        self.sip = ko.observable(sip);
        self.availability = ko.observable(availability);
        self.note = ko.observable(note);
    };
    
    self.notifications = ko.observableArray();
    

    However, it doesnt work as is. When the computed function is not commented out, the foreach does not iterate over the data and the div is empty. But I can see that the viewModel is not empty.