Sunday, October 2, 2011

How to use jQuery UI's Button with knockoutjs

I've been wanting to use jQuery UI's Button / Buttonset  action on a set of radio buttons into a series of buttons with knockoutjs.  However, it doesn't work reliably.

The reason has to with that the radio buttons and check boxes do not implement an onchange event in a way that is consistent with how knockoutjs updates the checked status on the html events.  The radio buttons and check boxes only call the the onchange event handler after the onclick handler is complete.

So when knockout updates the value by changing the checked attribute, the onchange event is doesn't fire. And the Button / Buttonset functions that need the onchange event to update the label are never called.

In the fiddle below, I have written a custom data binder called "buttonset" that corrects this problem. The code below is based on the "checked" binding in knockoutjs 1.3ctp.  I've added a dependency on jQuery with this code.  If you are using a different framework, all new code is in one spot, so it would be easy to modify.

It does it by updating the status of the labels similar to how the jQuery UI's functions work.  You can see it's operation in fiddle below.

To use it, replace "checked" data-bind with "buttonset".  Otherwise, operation is identical.