Draggable aurelia-dialog

I use the aurelia-dialog extensively across my project. However, I can’t work out how to make it draggable. All I want to do is to be able to drag it out of the way of the main page where it is invariably obscuring information that I need for the dialog.

All the draggable tutorials I’ve looked at refer to drag-destination, implying that I need to predefine the container that I am dragging into.

I’m just looking to emulate the behaviour of regular windows.

Could someone please point me in the right direction?

Thanks
Jeremy

Use something like hammerjs and adjust the position on Pan.

I just took a quick look at hammertime. I guess I would want to create a custom attribute to add to the dialog? I don’t even know where to start!

Do you have any example code that could give me a pointer in the right direction?

I also noticed on their home page that if you drag the white box, when you release the mouse it returns to its starting place. I want the dragged content to remain where I dragged it to. Is this possible?

Thanks

Check this out:

Of particular interest is probably the draggable.js custom attribute:

import { customAttribute, inject, TaskQueue } from "aurelia-framework";

@customAttribute("draggable")
@inject(Element)
export class Draggable {
  constructor(element) {
    this.element = element;
  }

  attached() {
    const manager = new Hammer.Manager(
      this.element.querySelector("ai-dialog-header")
    );
    manager.add(
      new Hammer.Pan({ direction: Hammer.DIRECTION_ALL, threshold: 0 })
    );
    manager.on("pan", e => this.pan(e));
  }

  pan(e) {
    // if there is no top set, dialog is still positioned relative
    if (!this.element.style.top) {
      const { x, y } = this.element.getBoundingClientRect();
      this.element.style.top = y + "px";
      this.element.style.left = x + "px";
      this.element.style.marginTop = "0";
      this.element.style.position = "absolute";
    } else {
      const top = parseFloat(this.element.style.top.replace(/px/, ""));
      const left = parseFloat(this.element.style.left.replace(/px/, ""));

      this.element.style.top = top + e.srcEvent.movementY + "px";
      this.element.style.left = left + e.srcEvent.movementX + "px";
    }
  }
}
3 Likes

Oh - that’s brilliant!

Thank you so much for your help!!

Just to follow up.

I put the attribute on all my dialogs, and the usability of the site went up 100%!

Again, many thanks

1 Like