Using jQuery Isotope plugin with AngularJS

5,373 views
Skip to first unread message

Jack Bruno

unread,
Dec 22, 2012, 8:34:25 PM12/22/12
to ang...@googlegroups.com
Hello,

I am having some trouble integrating the jQuery Isotope plugin with AngularJS. http://isotope.metafizzy.co/ I found the following topic and tried to mimic it but with no luck 

I started with a simple example of using Isotope without AngularJS

From there I setup a simple AngularJS app to populate the items

When I create a directive to apply isotope to the items the items are hidden

Can someone please take a look and see if I am doing something wrong when I create my directive?

Thanks,
Jack

Wayne Hoover

unread,
Dec 23, 2012, 12:02:52 PM12/23/12
to ang...@googlegroups.com
Hello, I also use isotope in an angularjs project.

Basically need to wait for angular to finish updating the dom and then apply the isotope plugin to the container. What is happening in your code is that isotope is running before angular updates the dom so when isotope runs there is no dom content to run it on so you don't see anything.

The only way I have figured out to fix this is to just to wrap your call to isotope in $timeout: http://jsfiddle.net/CLPxP/

There could be other ways you could do this if you had some variable to $watch on, but in this case I don't think thats doable. There is more detail about what you want to do here: https://github.com/angular/angular.js/issues/734. Thats a bit outdated but reading that it seems like the only thing you can do is $timeout because you can never really know when angular is done updating the dom.

Then again I might be totally wrong and there might be some zen way of doing what you want, if anyone else know a better way than using $timeout please let us know. But for now I guess the zen way is just to use $timeout :)

Wayne Hoover

unread,
Dec 23, 2012, 12:24:27 PM12/23/12
to ang...@googlegroups.com
Also I should note, you don't really need to instantiate isotope in a directive. You can get what you want by just calling isotope outside of angularjs, in normal jquery fashion: http://jsfiddle.net/BDGyR/

If later I add items to the isotope container, i'll broadcast up to the directive from my controller. Like this:

http://jsfiddle.net/KJ6Vp/

This is how I do it in my project. Notice we still need $timeout :)

Jack Bruno

unread,
Dec 23, 2012, 8:11:36 PM12/23/12
to ang...@googlegroups.com
Wayne,

Thanks for the reply. I am still having trouble getting this to work with an ajax request using $http. I am starting to understand a little more about how AngularJS works so I am going to play with it a bit. I will post my findings/questions.

Jack
Message has been deleted

macf...@gmail.com

unread,
Dec 24, 2012, 7:02:58 AM12/24/12
to ang...@googlegroups.com
Played a bit with it myself. I avoid ng-repeat while using jQuery plugins (even though it might be possible). Here's a fiddle http://jsfiddle.net/macfee/UwqKT/2/
Feel free to comment on it. Any hints for improvement style-wise etc are appreciated (as I am quite new to angular).
Max

jack....@pearson.com

unread,
Dec 26, 2012, 12:21:54 PM12/26/12
to ang...@googlegroups.com, macf...@gmail.com
Still no luck getting this to work. It is just not waiting for the repeat to finish before trying to apply the isotope plugin. Max your example might work, I will give it a try but I would rather not put that much html in my javascript. The real content is larger than the jsfiddle example I gave.

Jack

macf...@gmail.com

unread,
Dec 27, 2012, 4:19:46 AM12/27/12
to ang...@googlegroups.com, macf...@gmail.com, jack....@pearson.com
Actually there isn't any html in the javascript apart from the directive and directives are the proper place to do DOM manipulations. This fiddle even works when simulating a long running external database request: http://jsfiddle.net/macfee/UwqKT/6/
Max

Jack Bruno

unread,
Dec 28, 2012, 1:28:33 AM12/28/12
to ang...@googlegroups.com, macf...@gmail.com, jack....@pearson.com
Max,

Looking down the road I think you are right on how to go about this. I created a service to get the data using $http, and setup the controller to poll the data every 15 seconds. Using your example I think I am close, it works the first time but after that isotope only sees one item at a time and stacks them. Any ideas?


Jack

macf...@gmail.com

unread,
Dec 28, 2012, 11:36:48 AM12/28/12
to ang...@googlegroups.com, macf...@gmail.com, jack....@pearson.com
My two cents:

1. I think you have to get your items into the scope of your directive ( scope: { items: '=isoRepeat' })
2. It looks as if you want to add items. Then you have to tell isoope about (elem.isotope( 'insert', $items), see isotope docs) and initialize it.
3. I hacked the data service to generate different items and unique ids (not necessary)


Max

jack....@pearson.com

unread,
Dec 28, 2012, 1:04:07 PM12/28/12
to ang...@googlegroups.com, macf...@gmail.com, jack....@pearson.com
Close, but I actually need the data to update, not append - there may be new items but for the most part it will just be replacing what is already there with updated statuses. After the update I need isotope to run.

macf...@gmail.com

unread,
Dec 29, 2012, 6:22:22 AM12/29/12
to ang...@googlegroups.com, macf...@gmail.com, jack....@pearson.com
Shouldn't be too hard to fix, should it? How about removing the changed items using .isotope('remove', $items, cb) and inserting these items with .isotope('insert', $items, cb)?

.

jack....@pearson.com

unread,
Dec 29, 2012, 1:32:11 PM12/29/12
to ang...@googlegroups.com, macf...@gmail.com, jack....@pearson.com
OK. This is the solution I am going with. The key was to use the isotope remove not the jquery remove. I for simplicity I just remove all the elements and re-add them, maybe later I will look into only removing the changed items.


Thanks for the help Max!

Jack

pathso...@gmail.com

unread,
Jan 2, 2013, 1:12:36 PM1/2/13
to ang...@googlegroups.com, macf...@gmail.com, jack....@pearson.com
I was banging my head agains't my desk last night, this post has helped thanks guys. I have an additional question. How would one add an ng-click="" to each items being dynamically generated? From my understanding Angular doesn't reference the DOM the same when doing it this way rather than an ng-repeat. Let me know if this doesn't make sense and I'll try and explain better.

Thank you

Wayne Hoover

unread,
Jan 2, 2013, 3:52:27 PM1/2/13
to ang...@googlegroups.com, macf...@gmail.com
Interesting solution Max. Do you avoid ng-repeat because then you have more control over the DOM?

Jack, good solution. A tip: instead of watching the reference to the array and checking array.length in the function, just watch on array.length: http://jsfiddle.net/Brm9c/

-Wayne

On Saturday, December 29, 2012 12:32:11 PM UTC-6, jack....@pearson.com wrote:
OK. This is the solution I am going with. The key was to use the isotope remove not the jquery remove. I for simplicity I just remove all the elements and re-add them, maybe later I will look into only removing the changed items.


Thanks for the help Max!

Jack
Message has been deleted

jack....@pearson.com

unread,
Jan 2, 2013, 4:13:11 PM1/2/13
to ang...@googlegroups.com, macf...@gmail.com
Wayne,

Thanks. For my particular use case the data will almost always have the same length, but the data may change. So, I cannot watch the length, do you know of a better way for my situation?

Jack

jack....@pearson.com

unread,
Jan 2, 2013, 4:14:10 PM1/2/13
to ang...@googlegroups.com, macf...@gmail.com, jack....@pearson.com, pathso...@gmail.com
I have not looked at using directives inside of the html generated by a directive. I will need to do that soon, so I would be interested in the answer as well.

Jack

Wayne Hoover

unread,
Jan 2, 2013, 5:53:22 PM1/2/13
to ang...@googlegroups.com, macf...@gmail.com, jack....@pearson.com, pathso...@gmail.com
To hangle a click I would create a template and bind to the repeated element with ng-click:


Notice i'm using ng-repeat again, not the forEach manual DOM insertion like Max used. This allows me to use angulars native sortBy filter instead of using Isotopes and it allows me to bind to the repeated element as I show above (though I still have to use $timeout to get it to sort correctly, it seems like whenever I use ng-repeat with jquery plugins I have to use the $timeout hack, if anyone sees a solution let me know). 

If you wanted to use Max's method of avoiding ng-repeat, you might be able to do what you want with $compile ( http://docs.angularjs.org/api/ng.$compile ), maybe Max can work that out :)

pathso...@gmail.com

unread,
Jan 5, 2013, 1:58:21 PM1/5/13
to ang...@googlegroups.com, macf...@gmail.com, jack....@pearson.com, pathso...@gmail.com
Hey I got it to work with a scope function inside the directive, how would one call a method inside a controller though? I have a list of items with an ng-click='delete(item') button, but the delete() method is inside my ctrl. The 'hello world' log example you have has the method inside the directive. Thanks again!

Andrew Del Prete

unread,
Jan 5, 2013, 2:05:37 PM1/5/13
to ang...@googlegroups.com
I figured it out. I needed to assign a controller to the directive.

controller: myCtrl,
template: html

Thanks everyone for your help!

Jack Bruno

unread,
Jan 8, 2013, 12:31:23 AM1/8/13
to ang...@googlegroups.com, pathso...@gmail.com
Thanks for the update. I ended up moving away from isotope for performance reasons. It actually turned out to be much easier to just use built in angular filtering and sorting.

Jack

Shardul Pendse

unread,
May 2, 2014, 7:01:22 AM5/2/14
to ang...@googlegroups.com
Hello All,

hey guys. I am using  angularJs from last  5 months. I am stuck at 1 point. I have grid structure 3 * 3. 
When i click on particular grid that div should get expanded and all other div should re size according to the its parent size. i have created jsFiddle for it. I have tried to implement isotopes and angular. Using angular ans isotopes is not a good idea. So can we do it angular Js. Please Guys help me. 


Thank You
Shardul Pendse



Tristan Guigue

unread,
Jan 5, 2015, 5:45:53 AM1/5/15
to ang...@googlegroups.com
Hi,

I built a native AngularJS library that is inspired by isotope. It avoids all the issues related to trying to make jQuery and AngularJS play nice together.

If anyone is interested, take a look: http://tristanguigue.github.io/angular-dynamic-layout/

Tristan
Reply all
Reply to author
Forward
0 new messages