List reorder animation with angularjs
Asked Answered
T

2

18

I'm working on a project in angularjs that has a list of objects which update in real time and will be reordered with each update. I want to animate these objects moving smoothly from their starting to their end positions, so for example when the list reorder is:

A         C
B   ->    A
C         B

A and B will each move down one spot, and C will move up two spots, twice as quickly. This is easily done when you are manipulating the DOM manually - if you are moving the list element by changing it's style.top, you just put

transition-duration: 0.5s, 0.5s;
transition-property: top;

into the CSS for the element and it happens automatically. However, this trick won't work if you are using ngRepeat to display your list, because (as far as I can tell) angular actually recreates the DOM elements making up the list to do an update, rather than moving the DOM elements around.

Unfortunately, I've found it really difficult to reproduce this functionality with angular animations. The problem that I'm running into is that angular move animations seem to be unaware of each element's starting position. With the ngAnimate directive you can have angular automatically set a css class on your element when it moves, to simulate it fading in or out for example. But you have no information on where the element used to be, so you can't move it smoothly from it's old position - it just gets teleported to the new spot, and you have to make it dance around there. As far as I can tell, this is also true for javascript animations - angular teleports it into place and then passes it to your function, without any history information.

Is there a way within angular to have a smooth reordering animation as described above, without ditching the framework and handling the DOM manipulation yourself?

Tentacle answered 30/8, 2013 at 1:31 Comment(4)
Take a look at this question. Plus, you can always write a custom directive to perform any DOM manipulation you may need.Darryl
Thanks, that's perfect! I'm a little embarrassed I couldn't find that question when I searched... :-)Tentacle
Why not just use classes and transitions? Simply append an order class to the elements and as the class changes/updates they'll transition to the appropriate position.Illmannered
look into the track by clause of ng-repeat. I think as long as you have a unique property for each list item to track by, it won't rewrite the DOM except for when it's needed.Bounds
B
7

I think I've accomplished what you're looking for here: http://codepen.io/daleyjem/pen/xbZYpY

By using track by, I'm able to keep the DOM elements from being recreated, and can then manipulate their position.

<div ng-repeat="item in items | orderBy:sorter track by item.id" class="item" jd-script>
    {{ item.id }}: {{ item.last_name }}, {{ item.first_name }}
</div>
Bounds answered 8/12, 2014 at 17:14 Comment(0)
H
-1

I think this is what you are looking for : http://www.nganimate.org/angularjs/ng-repeat/move

Heptode answered 15/2, 2014 at 8:44 Comment(1)
That doesn't show how to animate the reordering of items; it only shows adding and removing items.Torero

© 2022 - 2024 — McMap. All rights reserved.