Search code examples
javascriptjqueryruby-on-railsdominteractjs

Correctly restore a draggable element to it's starting position


I'm using InteractJs library in a Rails 6 app. I've implemented it's drag and drop events.
The drag and drop functionality is working fine. The problem that I'm facing is if I drop an element out of the dropzone and place it to it's original(starting) position, it get's positioned there, but if I try to drag that element again it appears on the position where the previous dragging ended and not where it was restored to, this is the problem that I'm looking to solve

Below is my code for the events

var dragMoveListener = function (event) {
  var target, x, y;
  target = event.target;
  x = (parseFloat(target.getAttribute("data-x")) || 0) + event.dx;
  y = (parseFloat(target.getAttribute("data-y")) || 0) + event.dy;
  target.style.webkitTransform = target.style.transform =
    "translate(" + x + "px, " + y + "px)";
  target.setAttribute("data-x", x);
  return target.setAttribute("data-y", y);
};

window.dragMoveListener = dragMoveListener;

interact('*[data-draggable="true"]').draggable({
  inertia: false,
  autoScroll: true,
  onmove: dragMoveListener,
});

const restoreToOriginalPosition = (event) => {
  // this restores the element to it's original position but the next time I attempt to drag it, it appears on the position where the previous dragging ended
  event.relatedTarget.style.transform = "translate(0px, 0px)";
};

$(document).on("turbolinks:load", function () {
  interact("#dropzone").dropzone({
    accept: '*[data-draggable="true"]',
    overlap: 0.75,

    ondropactivate: function (event) {
      // ...
    },

    ondrop: function (event) {
      const product_id = event.relatedTarget.attributes["data-product-id"].value;
      // my use case is to remove the element from DOM if it's dropped into the dropzone, otherwise restore to it's starting position
      $(event.relatedTarget).remove();
      addToCart(product_id); //it's definition is not relevant here
    },

    ondropdeactivate: function (event) {
      restoreToOriginalPosition(event);
    },
  });
});

In the ondrop event listener I've attempted to restore the element to it's original position on the page. See the function restoreToOriginalPosition which successfully puts the element to it's original position.


Solution

  • I had to remove/reset the data-x and data-y attributes of the draggable element.

    const restoreToOriginalPosition = (event) => {
      event.relatedTarget.removeAttribute("data-x");
      event.relatedTarget.removeAttribute("data-y");
      event.relatedTarget.style.transform = "translate(0px, 0px)";
    };
    

    This solved the problem.