How to make something draggable

I’m using Copilot to create a flowchart canvas using VueFlow. It looks like it has no problem adding nodes, but no matter how much I prompt it, copilot has no idea how to make nodes draggable… even though it tells me that it has. I’m basically burning through tokens at this point.

I’m at the point where I need to figure out how to make the nodes draggable on my own, or make this part of the project in Lovable… which nailed the entire thing on the first prompt.

Is there a way that I can make an element Draggable in WeWeb without coding it? Or has anyone found a way to get Copilot to actually do what it says its doing?

Yeah you can use fixed positioning and bind an element to the coordinates of your mouse which can be tracked by using a on mouse move workflow.

I did something like this for a draggable calculator. I decided not to use WeWeb’s events, because it’s not the native event. I’m using a WeWeb’s variable though.

const instance = context.thisInstance;
const _document = wwLib.getFrontDocument();
const _window = wwLib.getFrontWindow();

let position = variables["021e20a3-86d0-443a-9a9d-26d6045901d2"];

const calculatorHeight = _document.getElementById("calculator").offsetHeight;

// Mouse down => Start grabbing and store offset inside the div
instance.addEventListener("mousedown", (e) => {
  const latestPosition = variables["021e20a3-86d0-443a-9a9d-26d6045901d2"];

  const rect = instance.getBoundingClientRect();
  const offsetX = e.clientX - rect.left;
  const offsetY = e.clientY - rect.top;

  wwLib.wwVariable.updateValue("021e20a3-86d0-443a-9a9d-26d6045901d2", {
    ...latestPosition,
    isGrabbing: true,
    active: true,
    offsetX,
    offsetY,
  });
});

// Mouse up => Stop grabbing
_document.addEventListener("mouseup", (e) => {
  const latestPosition = variables["021e20a3-86d0-443a-9a9d-26d6045901d2"];

  wwLib.wwVariable.updateValue("021e20a3-86d0-443a-9a9d-26d6045901d2", {
    ...latestPosition,
    isGrabbing: false,
  });
});

// Mouse move => Drag while grabbing
_document.addEventListener("mousemove", (e) => {
  const latestPosition = variables["021e20a3-86d0-443a-9a9d-26d6045901d2"];
  
  if (latestPosition.isGrabbing) {
    wwLib.wwVariable.updateValue("021e20a3-86d0-443a-9a9d-26d6045901d2", {
      ...latestPosition,
      x: e.clientX - (latestPosition.offsetX || 0),
      y: _window.innerHeight - e.clientY - calculatorHeight + (latestPosition.offsetY || 0),
    });
  }
});
1 Like

Hey @Broberto Just wondering why you decided to go with the native listeners in this case?

1 Like

Because I wanted to have a full control. WeWeb’s events aren’t the real events. They’re proxies with fewer options.

1 Like

Where would you put this code? I’ve figured out how update the position of the element using the mouse position but not in realtime, your code makes sense, I’m just not sure where it goes, is it in a formula under the logic tab¡

It depends on your setup a lot. I for example have an onMounted workflow with a JS action in it. I also have an unmount event to detach the listeners when the element gets conditionally unrendered to avoid memory leaks. It really depends on whatever setup you’re running.

1 Like

This topic was automatically closed after 75 days. New replies are no longer allowed.