TUTORIAL - How to drag/move any Weweb element freely on the canvas

Hi everyone :wave:, D here. In today’s tutorial we will looking at how to create a ‘drag and drop’ & ‘dropzone’ functionalities for any element we want in Weweb. I saw a lot of posts asking about draggable elements and when I was building my own project I needed one and had to make it for myself, so I wanna share how anyone can do it with one little code.

THE PROBLEM - I have this screen element would love to be able to drag from one place to another, OR I wanna drag an element and DO something on dropping it

THE SOLUTION -

  1. We are gonna use three variables along with one JavaScript snippet to achieve our functionality.
  2. Create three variables call them x-position, y-position and drag_is_on (you can call them anything you want tbh)
  3. Now create a global workflow call it start_draggable. Add a custom javascript action to it and add this code (make sure you replace the values in braces):
// Function to save the emitted mouse position on moving it 
function saveMouseMovement(event) {
    {variable x-position} = event.clientX;
    {variable y-position} = event.clientY;
    {variable drag_is_on) = true;
}

// Function to remove the mouse movement tracking via a double click
function stopTracking() {
    document.removeEventListener('mousemove', saveMouseMovement);
    document.removeEventListener('dblclick', stopTracking);
    {variable drag_is_on) = false;
}

// Add event listener for mouse movement
document.addEventListener('mousemove', saveMouseMovement);

// Add event listener for double click event to stop tracking
document.addEventListener('dblclick', stopTracking);

  1. Now to allow any element to be ‘draggable’ freely across the canvas. You need to go to the position property of the element and set it to ‘fixed’. Now you will see 4 new options appear ‘top’, ‘left’ ‘right’ ‘bottom’. Set ONLY TOP and LEFT, bind them to the y-position and x-position variables you made.
    So:
    x-position == left
    y-position == top

  2. Now for good UX, you can place a small icon in the top left corner of the widget and change the cursor settings of the icon from ‘auto’ to ‘grab’ (this will let your users know that the element is draggable when they hover over it)

  3. Add a workflow to your icon that will execute the workflow start_draggable which you made in step 2

Voila! that’s it! You will be able to now drag that element anywhere you like on the screen :rocket:

  1. If you wanna stop the drag just double click and the drag will stop.

HOW TO ADD a ‘dropzone’ feature?
So for this you can set up the second element that will serve as the ‘drop zone’

On that element you start your workflow, but change the trigger in your weweb editor FROM on-click TO on-mouse enter

Now when you begin the drag, drag it to your dropzone, double-click so the drag will end (the dropzone action will trigger by itself once your mouse enters it!

That’s it folks. A super effective way to drag and drop any element you want, and trigger dropzone actions too.

See you in the next tutorial :rocket:

PS, you can use the ‘drag_is_on’ boolean variable to change a UI element color (e.g. the drag icon) to visually let your users know when they have drag enabled or disabled

ADDITIONAL NOTES FOR ELEMENTS ALREADY SET IN PLACE IN YOUR UI
if you have an element that ALREADY exists, AND is visible on a page, and you wanna be able to click on that element and be able to drag it anywhere (ideally that’s a longer process and requires code, as you ought to inherently edit the element’s property -
BUT one no-code way I suggest is simple - create two EXACT copies of your element - one with a normal positioning, and the ‘draggable’ variant with ‘fixed’ positioning. Hide the draggable variant by default (since drag_is_on = false, set it’s visibility to drag_is_on. Now when your user clicks on the normal element (whose visibiliy is opposite of drag_is_on) trigger the start_draggable workflow. What will visually happen is that the normal element variant will disappear and the draggable variant will appear at your mouse position and be immediately draggable. So to the end user it will appear like they clicked on a card and it became draggable) If you wanna do something on drop, then use the dropzone tutorial above, and if you wanna change the UI position on drop back to your normal layout then you gotta use the ‘watch position’ feature of Weweb so as to snap it into place (but I STRONGLY suggest you just use the Kanban Component instead for that use case)…

3 Likes

What’s the use case for this? Haha any practical examples? trying hard to imagine haha a video would do wonders!

1 Like

Or just use the Kanban stack, that’s the preferred way to handle drag and drop in WeWeb.

I feel like you need to learn and play a little with WeWeb. Your efforts are appreciated, don’t get me wrong, but this is not really either NoCode, neither practical. You just end up confusing the people here, by posting answers and tutorials with code, that can simply be made with NoCode.

Custom JS breaks (doesn’t work well with) the Vue’s state as it is two separate things, and WeWeb is built on Vue, so most likely, this is just gonna cause people to have even more troubles, as they will run into bugs, even if they were able to implement this.

I repeat, I don’t want you to feel like this kind of efforts is not welcome, I appreciate it big time, I like your energy man, but sometimes, these kind of code answers, might confuse no-coders who haven’t seen a line of code in their life, especially when this is already handled by WeWeb.

Also, a tip, for document, it’s heavily suggested (especially by @aurelie) to use the WeWeb’s directives for selecting Window, Document etc, which can be found on the forum (look for wwLib. methods).

@Broberto From what I understand, the tutorial is not really about drag & drop into specific area, its to move freely your elements and make them behave like windows you would have on your desktop.

Of course, for usecase where you need to drag&drop items into specific zone, use our kanban/stack elements!

1 Like

Hey, glad we could clear up this misunderstanding bro. And it was great talking to you man.
Like I explained, I am not manipulating the DOM directly using JS like you worried about. And thanks to @Alexis for clarifying the use case here : allowing for freely draggable canvas elements.

My use case was a POC of a collaboration app for Scientists that allows them make group video calls. I needed the video calls to be going on in one ‘window’ while the collaborating scientists are using the whiteboard in the main UI to brainstorm.

There are a number of other use cases in collaboration where you need elements to be able to freely move around and be placed anywhere, not snap-into-place like Kanban is for.

Hence the tutorial. Cheers man :clinking_glasses:

3 Likes

Thanks for helping me find the right words to describe the feature @Alexis :grinning:

1 Like

Hey, great question. See my own use case I describe here

Made a video so you could see it.

3 Likes

@AgentD this is really awesome. I have a follow up question:

I would like to emulate the drag UX of iMessage - so, I have a header area on the modal - and use the HOVER STATE to trigger that workflow. So, when your move your cursor over the header - I trigger the start_draggable global workflow (easy enough) - but can you help me with the JS (and/or workflow triggers) to change the stopTracking from double click to when I no longer have hover state active for the header??

@Mark_Pederson

You see this highlighted part. That’s the stop function. And you can see 'dblclick' in the removeEventListener line that’s the trigger.

So if you want it that the trigger will stop once the mouse exits the element you can change it to ‘mouseleave’.

You can read the Docs here on the various types of values it can take MouseEvent - Web APIs | MDN

@Mark_Pederson

Then change this to 'mouseleave' too.

Love this tutorial! Super helpful

1 Like

Trying to move a modal, but the mentioned “fixed” option is not available in the list of positions. Any ideas or other options.

Your other post already got the answer. You should convert your modal to a Div or to a container. Those have the fixed property and can be moved around like in the tutorial.