1

I wan't to have a conditional css class and a dynamic css class added via the css binding.

Like so:

data-bind="css: {$data.something() : true, open : showOpen()  }"

2 Answers 2

1

Clearest is probably to combine them in one computed:

function ViewModel() {
  var self = this;
  
  self.something = ko.observable("danger");
  self.showOpen = ko.observable(true);
  
  self.cssClass = ko.computed(function() {
    return self.something() + (self.showOpen() ? " open" : "");
  });
}

ko.applyBindings(new ViewModel());
div { padding: 10px; }
.danger { background-color: orange; }
.open { border: 5px solid gray; border-width: 5px 5px 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/2.2.1/knockout-min.js"></script>

<div data-bind="css: cssClass"> my div with class: <code data-bind="text: cssClass"></code> </div>
<hr>
<label><input type="checkbox" data-bind="checked: showOpen"> showOpen</label>
<br>
<input type="text" data-bind="value: something, valueUpdate: 'afterkeydown'">

Allows you to unit test the entire thing, and keeps your view concise.

Sign up to request clarification or add additional context in comments.

Comments

0

I prefer a custom binding like this:

ko.bindingHandlers.klass = {
  init: function (el, val) {
    var prevClass = null
   
    ko.computed(function () {
      if (prevClass)
        $(el).removeClass(prevClass);
      
      var newClass = ko.unwrap(val());
      
      $(el).addClass(newClass);
      prevClass = newClass;
    }, null, {disposeWhenNodeIsRemoved: el})
    
  }
}

var vmo = {
  cssClass: ko.observable('a'),
  toggle: function () { vmo.cssClass(vmo.cssClass() == 'a' ? 'b' : 'a') }
}

ko.applyBindings(vmo);
.a {
  color: red;
}
.b {
  color: blue;
}
.another {
  text-decoration: underline;
}
<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>

<p data-bind='klass: cssClass, css: {another: true}'>Hello</p>
<button data-bind='click: toggle'>Toggle</button>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.