Shrabanee
Shrabanee

Reputation: 2766

Dynamic binding of multiple classes (Name of the class will come from some observable variable) using knockout css binding

I am trying to use css binding of knockout, to bind multiple classes to one element. Some class names I know and those will be binded based on some conditions (which is working fine). Issue comes when I tried binding an observable variable(which will return me class names based on some conditions).

Here is what I have tried

function vm()
{
  this.st = ko.observable();
  
  var data = true;
  var self = this;
  this.st(data);
  
  this.divColor = ko.pureComputed(function()
		{
    if(data == true)
      {
         return 'yellow';
        }
    else
     {
       return 'green';
       }
       
    });
                                  
  }
.div1
{
  height : 40px;
  width : 50px;
  border : 1px solid black;
  }

.disable 
{
  border : 1px solid red;
  }

.yellow

{
  background-color : yellow;
  }
.green
{
  background-color : green;
  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div class = "div1" data-bind="css : {'disable' : ( st() == 1) , divColor : true'}">
  </div>

Also I have tried

<div class = "div1" data-bind="css :divColor , css : {'disable' : ( st() == 1)}">
      </div>

But none of these is applying class, that 'divColor' is returning, to the element. First approach is adding 'divColor' as a class to the div element.

Any body have tried something like this before?

I don't want to generate the classes, based on condition, from js and bind it, as same 'divColor' is used in multiple places with different classes based on conditions.

Upvotes: 2

Views: 715

Answers (2)

elbecita
elbecita

Reputation: 2664

The only way of achieving what you want that comes to my mind is building the whole string value for the css binding, with all the classes that the element will have (check the snippet code). See that you will need to include also the classes that are static (like div1, otherwise they will be overwritten by the binding value).

function vm() {
  var self = this,
      data = true;
  self.st = ko.observable(data);
  
  self.divColor = ko.pureComputed(function() {
    if(self.st() == true){
      return 'yellow';
    }
    else {
      return 'green';
    }
  });
}

ko.applyBindings(new vm());
.div1
{
  height : 40px;
  width : 50px;
  border : 1px solid black;
}

.disable 
{
  border : 1px solid red;
}

.yellow
{
  background-color : yellow;
}
.green
{ 
  background-color : green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div data-bind="css: (st ? 'disable ' : '') + divColor() + ' div1'"></div>

Upvotes: 1

Nathan Fisher
Nathan Fisher

Reputation: 7941

To apply multiple css classes with knockout you either need to specify each css class separately with its own condition inside an object literal, or have an computed or pure observable return the classes that need to be applied depending on various conditions that you specify.

function vm() {
  var data = true;
  var self = this;
  self.st = ko.observable();

  self.st(data);

  self.divColor = ko.pureComputed(function() {
    if (self.st() == true) {
      return 'yellow disable';
    } else {
      return 'green';
    }

  });
}
ko.applyBindings(new vm());
.div1 {
  height: 40px;
  width: 50px;
  border: 1px solid black;
}
.disable {
  border: 1px solid red;
}
.yellow {
  background-color: yellow;
}
.green {
  background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div class="div1" data-bind="css : {yellow: st, green: !st(), disable : st}">
</div>
<div class="div1" data-bind="css : divColor">
</div>
<label>Has data: <input type="checkbox" data-bind="checked: st" /></label>

Upvotes: 1

Related Questions