Draggable directive and how to make Angular Material dialog draggable

Oleg Varaksin
1 min readMar 28, 2018

In my last post, I wrote about event handling with RxJS. In this post we will use the same technique, but for an Angular directive — a draggable directive. This directive can be applied to any HTML element in order to make this element draggable. It should have the selector draggable and two input properties: dragHandle and dragTarget. The first property defines a CSS selector of an element which is used as drag handle. The second property defines a CSS selector of an element which you want to drag.

I wrote this directive for the Angular Material dialog because the dialog component doesn’t provide a draggable behavior. The directive can be used as follows:

If you don’t specify the dragHandle, the current element is used as drag handle. In the example above, you can drag the dialog by pressing the mouse button when the mouse pointer is over the dialog’s title (header) and moving the mouse. The next example shows how to make the drag handle for the whole dialog.

Let’s write the directive. We will create RxJS streams from three events: mousedown, mousemove, mouseup.

To change the element’s position, I use the CSS3 property transform with translate. This allows to avoid making the element absolute or relative positioned (e.g. position: relative) and manipulating the CSS properties top and left.

Please note two performance boosts:

  • event listeners are registered outside of the Zone.js (zone.runOutsideAngular).
  • CSS3 based position translation happens inside of requestAnimationFrame. Never heard about requestAnimationFrame? Read here.

Have fun!

--

--

Oleg Varaksin

Thoughts on software development. Author of “PrimeFaces Cookbook” and “Angular UI Development with PrimeNG”. My old blog: http://ovaraksin.blogspot.de