Implementing Isotope with Knockout JS

Knockout is a javascript MVVM (model view view-model) library which provides an excellent data binding mechanism at the client side. Isotope is an amazing javascript layout library.

I have used Isotope library in php pages before and it was a breeze. So naturally I thought it was a cake walk to implement Isotope anywhere. However, when I tried implementing it inside the Knockout framework, that was clearly not the case and I had some good learning on the way.

The problem

Both Isotope and Knockout works by manipulating the DOM. Knockout dynamically converts the binding definitions to DOM elements when data binding is executed. Isotope adds css classes to each DOM element so that it can find those elements later and manipulate them.

However, when Isotope runs, Knockout has not yet created the elements for proper initialization. Isotope doesn’t re-evaluate the elements and hence doesn’t know about the elements it needs to manipulate. After looking for quite a while for a solution, this jsfiddle and this post came to the rescue.

Custom bindings to the rescue

In Knockout, you can create your own custom bindings apart from the standard bindings defined in the Knockout library. There are 2 hooks defined for each binding – ‘init’ and ‘update’.

Let’s see an example:

Here, the ‘init’ hook is called when the binding is first applied to an element. The ‘update’ hook will be called when the binding is first applied to an element and again whenever the associated observable changes value.

For this custom binding to be called, it needs to be declared in the html or the view from where the binding takes place.

Here, the name of the binding is ‘customBinding’.

So, using this custom binding, the isotope can be initialized for each item in the binding list as it is added to the view.

Then, inside the view, invoke the custom binding:

Here, ‘isotope’ is the name of the custom binding. Parameters ‘container’ and ‘itemSelector’ are passed to the custom binding for initializing the isotope. Since it’s applied inside the ‘foreach’ loop, this will be called each time an item is inserted or removed.

Voila! Now immediately after Knockout adds each item dynamically, the custom binding will add the attributes required by Isotope to each element, thereby allowing Isotope to manipulate and resize the elements later.