SortableJS / Sortable

Reorderable drag-and-drop lists for modern browsers and touch devices. No jQuery or framework required.
https://sortablejs.github.io/Sortable/
MIT License
29.51k stars 3.69k forks source link

How to prevent duplicates on multidrag #2387

Open MarianVlad74 opened 3 months ago

MarianVlad74 commented 3 months ago

There is a possibility to prevent duplicates on multidrag?

MarianVlad74 commented 3 months ago

I solved by adding elements in an array in put group option and i check for duplictes on onAdd function.

It would be nice if the MultiDrag Plugin had an option like multiDragSkipDuplicates: true.

BirgitPohl commented 1 month ago

Would you show how you solved it? I have a similar issue in regards to unwanted duplicates with simple dragging.

async initMovability() {
    await this.updateComplete;
      const boardColumns = this.shadowRoot!.querySelectorAll('.board-column .board-items');
      boardColumns.forEach(column => {
        Sortable.create(column as HTMLElement, {
          group: 'board',
          animation: 300,
          onEnd: (evt) => {
            const itemEl = evt.item;
            const newState = itemEl.closest('.board-column')?.id as COLUMN_STATE;
            if (!itemEl.dataset.id) {
              throw new Error('"data-set-id" not found, but it\'s required for sorting.')
            }
            if (newState) {
              this._boardCardContext?.updateCardState(itemEl.dataset.id!, newState);
              this.requestUpdate();
            }
          }
        });
      });
  }

So, you say, you added an optional parameter to group and you check on onAdd if there are duplicates and you skip them. My solution was to remove the duplicate from the newList in the onRemove().

async initMovability() {
    await this.updateComplete;

    const boardColumns = this.shadowRoot!.querySelectorAll('.board-column .board-items');

    boardColumns.forEach(column => {
      Sortable.create(column as HTMLElement, {
        group: {
          name: "board",
          pull: true,
          put: true
        },
        animation: 300,

        onAdd: (evt) => {
          const newList = evt.to as HTMLElement;
          const itemEl = evt.item;

          if (!itemEl.dataset.id) {
            throw new Error('Data-set-id not found, but it\'s required for sorting.');
          }

          const newState = newList.closest('.board-column')?.id as COLUMN_STATE;
          if (newState) {
            this._boardCardContext?.updateCardState(itemEl.dataset.id!, newState);
          }
        },

        onRemove: (evt) => {
          // Somehow this ensures that duplicates are removed after moving
          const newList = evt.to as HTMLElement;
          newList.removeChild(evt.item);
        },
      });
    });
  }
MarianVlad74 commented 1 month ago

So, you say, you added an optional parameter to group and you check on onAdd if there are duplicates and you skip them. My solution was to remove the duplicate from the newList in the onRemove().

On the group/put option, i save elemens in to an array

group: {
    put: (to, from, dragEl, event) => {
         // save to arrayName
    },
},

and on onAdd function ...

onAdd: function (e) {
     e.items.forEach(e => {
           if (arrayName.includes(...)) {
               e.remove();
           }
     }
 },