Add class on click using knockout.js

3,718 views
Skip to first unread message

jay.moo...@gmail.com

unread,
Jun 11, 2013, 2:24:43 PM6/11/13
to knock...@googlegroups.com
I want to add a class to a button when clicked but knockout.js seems to have hijacked the element so I cannot use jquery on click?

What is the method for using knockout.js to add a class to a button when clicked?

<button type="button" class="btn btn-large btn-flat" data-bind="click: function (data, event) { setTypeFilter('LI', data, event) }">LI</button>

Ryan Rahlf

unread,
Jun 11, 2013, 8:57:14 PM6/11/13
to knock...@googlegroups.com, jay.moo...@gmail.com
Hi Jay,

It looks like the code you posted should work...depending on where setTypeFilter is defined and what it does.  I would say though, that the code you posted may not be adhering to "best practices".  Here are a couple suggestions:

In general, your code will be more flexible and easy to maintain if you put your logic in your view models and keep it out of your declarative data binding statements.  Anytime you find yourself writing "data-bind" and following that by declaring a function, or using an assignment or operator, you should ask yourself if you'd be better served moving that code into your view model or custom binding; the answer is usually "yes".  For example, if you're performing some calculation and outputing the result as the text of a span like this:

<span data-bind="text: function(){ return $data.itemCount() + $parent.offset() + ' items total' }"></span>

you'd probably want to refactor that to be 

<span data-bind="text: itemTotal"></span>

and move all that logic and string concatenation into a function of your view model (in this example, a ko.computed called "itemTotal").


Also, if you're using Knockout to bind your view to your data, you usually don't want to be using jQuery's event handlers like "click" or "on" for the parts of the page managed by knockout - that's knockout's job.  Your knockout view models don't just model your data, the model the state of the user interface.  In your example, it sounds like you want to provided a different appearance to a button when it's "on" versus when it's "off".  Clicking this button probably also causes some other change in the UI aside from changing the look of the button; it changes the state of something on the page.  This can be modeled in your view model.

var viewModel = function(){
    var self = this;
    self.isActive = ko.observable(false);
    self.toggleActive = function(data, event){
        self.isActive(!self.isActive());//toggle the isActive value between true/false
    }
}

<button data-bind="click: toggleActive, css : {'activeStyle' : isActive}">Toggle Active</button>

I've created a jsFiddle for you to check out here : http://jsfiddle.net/rrahlf/amMup/

I hope that helps and gives some insight into a few best practices.  Happy coding!


-Ryan Rahlf
___________________
@Ryanthem
Reply all
Reply to author
Forward
0 new messages