marceljuenemann / angular-drag-and-drop-lists

Angular directives for sorting nested lists using the HTML5 Drag & Drop API
MIT License
2.16k stars 713 forks source link

For "simple" - if you select an item and then drag it, the "generated model" is incorrect, as has duplicates #421

Open IvanReznikov opened 7 years ago

IvanReznikov commented 7 years ago

The old value of the highlighted element isn't deleted.

anujshsdei commented 7 years ago

I am also facing the same issue, as soon I drag the element resultant model contains the duplicate values. Not able to fix this issue. Any help appericated

decherneyge commented 6 years ago

I believe this might be an issue with the $index and splice code. Moved fires after the element is added to the list so if you move an item to a location that is before the original location the index will be incorrect. Not sure how to get the previous index short of stashing it in a draggingStart.

In my case vm.paletteColors is an array of strings.

 function colorPaletteDragStartCallback(event, $index, color){
            vm.previousIndex = $index;
            vm.selectedColor = color;
        }
   function colorPaletteMovedCallback(event, $index){
            var delta = 0;

            //$index = new location of original item
            //1. find first occurrence (FO) of  color
            var firstIndex = vm.paletteColors.indexOf(vm.selectedColor);
            //2. if FO < $index, item moved in front : delta = 1
            //   else, item moved after : delta = 0
            if(firstIndex < $index){
                delta = 1;
            }

            vm.paletteColors.splice($index+delta,1);
        }

It is also worth noting that another way to do this (that can be found in the docs) is to structure your dndlist as an array of objects so that you can add a selected property which gets set during dnd-selected. However according to the docs dnd-selected only fires when an item is clicked and not dragged so I think you would also have to set it during dragging. Then in your moved callback you can filter the list where selected!=true.

satyajeetjadhav commented 6 years ago

@decherneyge I think so too. I use the dnd-inserted callback to capture the destination index. Then I use the dnd-moved callback to figure out the direction in which the item was moved - upwards or downwards.

<ul dnd-list="list" dnd-inserted="setMovedToIndex(index)">
 <li ng-repeat="item in list track by $index" dnd-draggable="item" dnd-moved="updateOrder($index);" dnd-effect-allowed="move">
 function setMovedToIndex(index) {
  movedToIndex = index;
}

function updateOrder(index) {
  movedFromIndex = index;
  if (movedToIndex > movedFromIndex) {
    //item was moved down the list
    movedToIndex = movedToIndex - 1;
    $scope.models.lists.venues.splice(index, 1);
  } else {
   //item was moved up in the list
   $scope.models.lists.venues.splice(index + 1,1); 
  }
mattjegan commented 6 years ago

I can confirm @satyajeetjadhav 's example works well.