# How to animate on item list replacement

**URL:** <https://forums.fusetools.com/t/how-to-animate-on-item-list-replacement/2248>\
**Category:** How-to Discussions\
**Created:** [May 14, 2016, 4:15am UTC](https://forums.fusetools.com/t/how-to-animate-on-item-list-replacement/2248 "2016-05-14T04:15:19Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sahal\_Zain](https://avatars.discourse-cdn.com/v4/letter/s/d2c977/32.png) [@Sahal\_Zain](https://forums.fusetools.com/u/Sahal_Zain)\
**Post date:** [May 14, 2016, 4:15am UTC](https://forums.fusetools.com/t/how-to-animate-on-item-list-replacement/2248/1 "2016-05-14T04:15:19Z")

</div>

Hi,

I’m trying to create some kind of list re-arragement / ordering with swipe gesture, so far it’s working as workaround without native drag n drop list order/sort. But in this solution, what is lack is the animation when the item is switched. There are several alternative way that I could think of that but I don’t know how to achieve that

1. Triggering animation layout when the item position in the list has changed (listening to replaceAt)
2. Triggering remove and add event for replaceAt method in the list
3. Adding a method to add an item in the list for specific index (such as splice) (so I could use removeAt and addAt instead of replace)
4. Add an animation trigger detecting when the property in an item has changed

Here is the code I’m working with. Currently I use the replaceAll method `items.replaceAll(items.toArray());` to re arrange the list within the layout, but the layout animation won’t work as expected and add / remove animation would make the animation looks wierd.

Any suggestion are welcome 🙂

Thanks

```auto
<App Theme="Basic">
  <Panel>

  <JavaScript>
  var Observable = require("FuseJS/Observable");
  var col = Observable(3);
  var items = Observable();

  for(var i = 0;i<10;i++){
    var o = new Item(i);
    items.add(setup(o,i));
  }

  function Item(id){
    var d = (10000000 + id * 100000);
    this.color = '#' + d.toString(16);
    this.id = id;
  }

  function setup(item,n){
     item.pos = Observable(n);

     item.right = Observable(function(){
       if((item.pos.value + 1)%col.value===0||(item.pos.value + 1)>=items.length)return false
       else return true;
     })

     item.left = Observable(function(){
       if((item.pos.value + 1 )%col.value===1)return false
       else return true;
     })

     item.top = Observable(function(){
       if((item.pos.value +1) - col.value <= 0)return false
       else return true;
     })

     item.bottom = Observable(function(){
       if((item.pos.value +1) + col.value > items.length)return false
       else return true;
     })

     return item;
  }

  function switchPos(currentPos,targetPos){
     var targetItem = items.getAt(targetPos);
     var currentItem = items.getAt(currentPos);
     targetItem.pos.value = currentPos;
     currentItem.pos.value = targetPos;
     items.replaceAt(targetPos, currentItem);
     items.replaceAt(currentPos , targetItem);
     items.replaceAll(items.toArray());
     return currentItem;
  }

  function addItem(arg){
    var len = items.length;
    var newItem = new Item(len);
    items.add(setup(newItem,len));
  }

  function swipeRight(arg){
    var n = items.indexOf(arg.data);
    var r = switchPos(n, n + 1);
  }

  function swipeLeft(arg){
    var n = items.indexOf(arg.data);
    switchPos(n, n - 1);
  }

  function swipeDown(arg){
    var n = items.indexOf(arg.data);
    switchPos(n, n + col.value);
  }

  function swipeUp(arg){
    var n = items.indexOf(arg.data);
    switchPos(n, n - col.value);
  }

  module.exports = {
    items: items,
    col : col,
    addItem : addItem,
    swipeRight : swipeRight,
    swipeLeft : swipeLeft,
    swipeUp : swipeUp,
    swipeDown : swipeDown
  };

  </JavaScript>

    <Panel Alignment="Top">
     <ColumnLayout ColumnCount="{col}" />
     <Each Items="{items}">
     <Panel ux:Name="panelBox">
          <DoubleClicked Handler="{addItem}"/>
          <LayoutAnimation>
            <Move RelativeTo="PositionChange" X="1" Y="1" Duration="0.5" Easing="Linear" />
          </LayoutAnimation>

          <Viewbox>
             <Rectangle ux:Name="box" Margin="3" Fill="{color}" Width="200" Height="200">
                <Circle ux:Name="circ" Width="50" Height="50" Fill="#fff" Opacity="0.5">
                  <Text Value="{id}" Alignment="Center" FontSize="24" />
                </Circle>
             </Rectangle>
          </Viewbox>

          <WhileTrue Value="{left}">
             <SwipeGesture ux:Name="swipeL" Direction="Left" Length="100" Type="Active"/>
          </WhileTrue>
          <WhileTrue Value="{right}">
             <SwipeGesture ux:Name="swipeR" Direction="Right" Length="100" Type="Active"/>
          </WhileTrue>
          <WhileTrue Value="{top}">
             <SwipeGesture ux:Name="swipeU" Direction="Up" Length="100" Type="Active"/>
          </WhileTrue>
          <WhileTrue Value="{bottom}">
             <SwipeGesture ux:Name="swipeD" Direction="Down" Length="100" Type="Active"/>
          </WhileTrue>

         <SwipingAnimation Source="swipeR">
            <BringToFront/>
            <Move X="1" RelativeTo="Size" RelativeNode="panelBox" />
          </SwipingAnimation>
         <SwipingAnimation Source="swipeL">
            <BringToFront/>
            <Move X="-1" RelativeTo="Size" RelativeNode="panelBox" />
         </SwipingAnimation>
         <SwipingAnimation Source="swipeU">
           <BringToFront/>
           <Move Y="-1" RelativeTo="Size" RelativeNode="panelBox" />
         </SwipingAnimation>
         <SwipingAnimation Source="swipeD">
           <BringToFront/>
           <Move Y="1" RelativeTo="Size" RelativeNode="panelBox" />
         </SwipingAnimation>

         <Swiped Source="swipeR">
             <Callback Handler="{swipeRight}"/>
         </Swiped>
         <Swiped Source="swipeL">
             <Callback Handler="{swipeLeft}"/>
         </Swiped>
         <Swiped Source="swipeU">
             <Callback Handler="{swipeUp}"/>
         </Swiped>
         <Swiped Source="swipeD">
             <Callback Handler="{swipeDown}"/>
         </Swiped>

       </Panel>
     </Each>
    </Panel>
  </Panel>
</App>

```

---

<div class="post-metadata">

**Author:** ![Anders\_Lassen](https://yyz1.discourse-cdn.com/flex035/user_avatar/forums.fusetools.com/anders_lassen/32/522_2.png) [@Anders\_Lassen](https://forums.fusetools.com/u/Anders_Lassen)\
**Post date:** [May 14, 2016, 4:59am UTC](https://forums.fusetools.com/t/how-to-animate-on-item-list-replacement/2248/2 "2016-05-14T04:59:52Z")

</div>

Hi Sahal,

Animating reorder is a tricky use case, and I can’t think of any easy way to do it from just UX/JS.

We need Uno-level tweaks to accommodate this use case, so unless you want to hack around with that, you will have to wait for a fix/example from the community or the Fuse team.

One solution could be to mod the `Each` operator so it can detect rearrangements and handle them differently from add/remove pairs. Then you could be able to use `LayoutAnimation` for this case.

Even more fancy, it would be cool to have a `DraggableReorder` behavior similar to `Draggable` which would let you simply encapsulate all of this magic.

In any case, these features don’t exist yet (as of 0.12/0.20) but I’m filing a ticket for this and we will look into it later.

---

<div class="post-metadata">

**Author:** ![Sahal\_Zain](https://avatars.discourse-cdn.com/v4/letter/s/d2c977/32.png) [@Sahal\_Zain](https://forums.fusetools.com/u/Sahal_Zain)\
**Post date:** [May 14, 2016, 8:13am UTC](https://forums.fusetools.com/t/how-to-animate-on-item-list-replacement/2248/3 "2016-05-14T08:13:33Z")

</div>

Hi Anders,

Thanks for the insight. I was planning to try some hacking, and digging up the generated android source code and found out the undocumented observable API from the assets folder, turns out you have `insertAt` method , the last ingridient I need

```auto
/* ----- Observable ------

    Message API:

    set(value) - Set a single value (at index 0)
    newAt(index, value) - New value at the given index
    newAll(array) - Assume all values dirty. Array length must be != 1 (use set() for length == 1)
    add(value) - Add to end of list
    remove(object, index) - Remove object at index
    insertAt(index, value) - Insert value at index
*/

```

And then I finish my code with this

```auto

function switchPos(currentPos,targetPos,direction){
     var targetItem = items.getAt(targetPos);
     var currentItem = items.getAt(currentPos);
     targetItem.pos.value = currentPos;
     currentItem.pos.value = targetPos;

     currentItem.moveX.value = currentItem.moveY.value = 0;
     if(direction==='right'){
        targetItem.moveX.value = 0.5;
        targetItem.moveY.value = 0;
     }
     if(direction==='left'){
        targetItem.moveX.value = -0.5;
        targetItem.moveY.value = 0;
     }
     if(direction==='up'){
        targetItem.moveY.value = -0.5;
        targetItem.moveX.value = 0;
     }
     if(direction==='down'){
         targetItem.moveY.value = 0.5;
         targetItem.moveX.value = 0;
     }

     items.removeAt(currentPos);
     items.insertAt(currentPos,targetItem);
     items.removeAt(targetPos);
     items.insertAt(targetPos,currentItem);

     return currentItem;
  }

```

and put the add animation in the UX

```auto
<AddingAnimation>
                <Move RelativeTo="Size" X="{moveX}" Y="{moveY}" Duration="0.5" Easing="CubicIn"/>
            </AddingAnimation>

```

It’s not the perfect solution, but at least I’m happy with this while waiting for the real `DraggableReoder` to come 🙂

[https://github.com/zean00/fuse-swipeorder-sample](https://github.com/zean00/fuse-swipeorder-sample)

Thanks for the quick response

---

<div class="post-metadata">

**Author:** ![Juanlu](https://avatars.discourse-cdn.com/v4/letter/j/47e85d/32.png) [@Juanlu](https://forums.fusetools.com/u/Juanlu)\
**Post date:** [November 20, 2016, 12:38am UTC](https://forums.fusetools.com/t/how-to-animate-on-item-list-replacement/2248/4 "2016-11-20T00:38:51Z")

</div>

Any news about DraggableReorder?

---

<div class="post-metadata">

**Author:** ![Anders\_Lassen](https://yyz1.discourse-cdn.com/flex035/user_avatar/forums.fusetools.com/anders_lassen/32/522_2.png) [@Anders\_Lassen](https://forums.fusetools.com/u/Anders_Lassen)\
**Post date:** [November 20, 2016, 1:11am UTC](https://forums.fusetools.com/t/how-to-animate-on-item-list-replacement/2248/5 "2016-11-20T01:11:19Z")

</div>

Juanlu: Nope, sorry. It hasn’t reached the top of our priority list yet.

This is something that could just as well be a community package though (doesn’t have to be built into the core platform), so nothings stopping you or someone else from giving it a go in Uno code.

---

<div class="post-metadata">

**Author:** ![Uldis](https://yyz1.discourse-cdn.com/flex035/user_avatar/forums.fusetools.com/uldis/32/657_2.png) [@Uldis](https://forums.fusetools.com/u/Uldis)\
**Post date:** [October 12, 2017, 9:21am UTC](https://forums.fusetools.com/t/how-to-animate-on-item-list-replacement/2248/6 "2017-10-12T09:21:10Z")

</div>

Heads up!

We now have a [Drag to reorder](https://www.fusetools.com/examples/list-reordering) example on the site.
