react-sortablejs icon indicating copy to clipboard operation
react-sortablejs copied to clipboard

Swap plugin is off by 1, possible off by 1 error

Open DerrykBoyd opened this issue 5 years ago • 9 comments

When using the swap plugin, after a sort the moved item is placed in the wrong location in the array. This happens on the examples page as well. This is the behaviour:

Swap Item 1 and item 2 Item 1 moves to 3rd spot (expected 2) Item 2 moves to 1st spot (correct) Item 3 moves to 2nd spot (expected no move)

DerrykBoyd avatar Jan 25 '20 07:01 DerrykBoyd

@dboydgit Thank you for this! I will have to investigate this further. Apoloigies for the delay.

waynevanson avatar Feb 06 '20 01:02 waynevanson

@dboydgit Thank you for this! I will have to investigate this further. Apoloigies for the delay.

@waynevanson: Have you perhaps found anything so far? I've been trying to dig to see if I can solve this, but it still has me stumped! I also noticed that on Firefox v72 there's a slight shake added after a swap, as if the list is reorganising/adjusting. This isn't visible under Chrome v80.

Deadmano avatar Feb 18 '20 03:02 Deadmano

@waynevanson i am facing the same issue while using Swap plugin in react sortable. Has it been fixed ? if not, is there any temporary fix we can make on our side ?

pg07codes avatar May 12 '20 06:05 pg07codes

Is there any temporary fix for this bug or any work around? Thanks!

sageavaa avatar Jun 24 '20 20:06 sageavaa

Bump, having the same problem

ralcar avatar Jul 23 '20 18:07 ralcar

I used this workarund:

<ReactSortable
          list={this.state.list}
          setList={() => {}}
          onUpdate={(ev) => this.setList(ev)}
          swap
        >

Then on setList I use the event's oldIndex and newIndex to make the swap in the array

luiskcs89 avatar Nov 24 '20 20:11 luiskcs89

So i actually managed to get the right implementation by modifying the response from @luiskcs89 a little bit.

The sortable component and the mapping function

<ReactSortable 
      group="TeamMembers" list={test} 
      setList={() => { }} 
      onUpdate={(ev) => updateSwap(ev)} 
      swap={true} 
      swapClass={"text-success"} c
      hosenClass={"sortable-chosen"}>

      {test.map((item, index) => (
        <div className="bg-white p-3 mb-3" key={index}>{item.name}</div>
      ))}

</ReactSortable>

The updateSwap function

function updateSwap(event) {

  const items = Array.from(test);
  //swap items at index
  items[event.newIndex] = test[event.oldIndex];
  items[event.oldIndex] = test[event.newIndex];

  setTest(items);
};

And lastly my test State

const [test, setTest] = useState([{ id: 1, name: "Player 1" }, { id: 2, name: "Player 2" }, { id: 3, name: "Player 3" }, { id: 4, name: "Player 4" }, { id: 5, name: "Player 5" }]);

you could initially set the state in useEffect with API data for example. I'm gonna use this until the library fixes the swap indexing

kevinbevers avatar Dec 16 '20 12:12 kevinbevers

Is there a plan to work on this issue?

I have found out that the first setList is correct and the following update is one index off.

marcelmokos avatar Feb 22 '21 12:02 marcelmokos

@kevinbevers is it working for you I am trying the solution without success.

Edit: it is working with

<ReactSortable 
  group="TeamMembers" list={test} 
  setList={() => { }} 
  onSwap={(ev) => updateSwap(ev)} 
  swap={true} 
  swapClass={"text-success"} c
  hosenClass={"sortable-chosen"}
>
  {test.map((item, index) => (
    <div className="bg-white p-3 mb-3" key={index}>{item.name}</div>
  ))}
</ReactSortable> 

marcelmokos avatar Feb 22 '21 12:02 marcelmokos