How to cancel a dragging operation in vuedraggable programmatically

124 views Asked by At

When dragging, if currently dragged element is over a (fixed) non-movable element, it should do some checking to find the closest available element to be swapped with. After that I would like to cancel the dragging even if mouse button is not released.

How to programmatically cancel the dragging when some condition is met in the move event ?

<draggable
  :list="fields"
  item-key="id"
  handle=".draggable"
  :move="draggableOnMove"
>
// template
</draggable>
const draggableOnMove = (e: any) => {
  const context = e.draggedContext;
  const related = e.relatedContext;

  // Disallow to move the fixed element
  if (related.element.value?.fixed) {
    // Swap with closest non fixed element
    let swappableIndex = context.futureIndex + 1;
    while (fields.value[swappableIndex].value?.fixed) {
      swappableIndex++;
    }
    fieldsComposable.swap(context.index, swappableIndex);

    // how to cancel a dragging here after elements has been swapped manually <----
  };
};
1

There are 1 answers

0
berkobienb On
  1. Define a variable to track whether dragging should be canceled.
  2. Use the beforeMove event to check your condition and set the cancel flag if necessary.
  3. In the move event, check the cancel flag, and if it's set, prevent further dragging.

Here's how you can implement this in your code:

<template>
  <div>
    <draggable
      :list="fields"
      item-key="id"
      handle=".draggable"
      :move="draggableOnMove"
      @beforeMove="beforeDraggableMove"
    >
      <!-- Your template content here -->
    </draggable>
  </div>
</template>

<script>
import draggable from 'vuedraggable';

export default {
  components: {
    draggable,
  },
  data() {
    return {
      fields: [], // Your data here
      cancelDrag: false, // Flag to control dragging cancellation
    };
  },
  methods: {
    draggableOnMove(evt) {
      if (this.cancelDrag) {
        return false; // Prevent further dragging
      }
      // Your move logic here
    },
    beforeDraggableMove(evt) {
      const context = evt.draggedContext;
      const related = evt.relatedContext;

      // Disallow to move the fixed element
      if (related.element.value?.fixed) {
        // Swap with closest non-fixed element
        let swappableIndex = context.futureIndex + 1;
        while (this.fields[swappableIndex]?.fixed) {
          swappableIndex++;
        }
        // Perform the swap
        this.fields.splice(context.index, 1, this.fields[swappableIndex]);
        this.fields.splice(swappableIndex, 1, context.dragged);

        // Set the cancel flag to stop dragging
        this.cancelDrag = true;
      }
    },
  },
};
</script>