Module-documentation

version 1.0.0
module: drag-drop version 0.0.1
size-min gzipped: 3.03 kb (incl. dependencies: 17.73 kb)
dependencies: polyfill/polyfill-base.js, js-ext/lib/function.js, js-ext/lib/object.js, utils, event
maintanance: Marco Asbreuk
home


all modules

Drag and Drop

Drag and Drop is a module which makes draggable items without any initialisation: just plain HTML. The code that takes care of this is loaded once and uses event-delegation to perform its task. You can set attributes on the HtmlElements and they will act as draggables, or dropzones. Of coarse these functionality can be given afterwards using javascript: you can set attributes yourself, or use Plugin's on the HtmlElements.

Because HTML defines the drag and drop behaviour, drag-drop is perfectly suited for serverside rendering.

This module extends the module drag, be sure you read that documentation first. You can find drag-related documentation at that module: this documentation is about the specific drop-features provided by this module.

Drag and Drop is done using the event-dom module which uses event delegation. Therefore it is very efficient, flexible and has no memoryleaks when dom-nodes are removed.

Getting Started

With nodejs:

The module drag-drop is a typical browser-module.

In the browser:

For browser-usage, ITSA has a predefined loaderfiles. Once included, a global ITSA object with default features is available. For customized loaderfiles, read: Customized build.

<script src="/itsabuild-min.js"></script>
<script>
    var DD = ITSA.DD;
    DD.init();
</script>
When using your own customized build-file, this module-requirement needs to be invoked with the window-object.

Features

This module brings Drag and Drop to a higher level:

Inherited from the drag-module:

The Basics

Drag and Drop consist of two different parts: drag and drop. Both parts are related to HtmlElements: draggable nodes or dropzone nodes that act as a container where the draggable items can be dropped into. The draggable features are deliverd by the drag-module and extended with copy-support. The functionalities of the dropzones are made operational by setting the appropriate attributes the the dropzone-HtmlElements.

HtmlElements can act as a dropzone where draggable items can be dropped inside. Dropzones are defined with the attribute dropzone="true | move | copy". The type of dropzone determines wheter it accepts only copyable items, movable items, or both. As you can see later on, a dropzone can be limites to accept special emitters as well.

Not only do you need to define dropzones, you also need to tell the draggable items that they should go into a specific dropzone. This should be done by setting the attribute dd-dropzone="css-selector" on the draggable item:

<div plugin-dd="true" dd-dropzone=".drop-container">drag me</div>
<div class="drop-container" dropzone="true"></div>

Dropzones

Effect-allowed

A dropzone should be defined as a dropzone by specifying the attribute dropzone in one of these ways:

The property determines whether movable or copyable items are accepted and is called: effect-allowed. The origin of the draggable will determine this, because the draggable needs to be set up as well.

Constrain to Emitters

Beside the effect-allowed, a dropzone can be setup to accept only one -or multiple- specific emitters. The dropzone-attribute can be extended like this:

<div dropzone="true emittername=someEmitter">

where effect-allowed could be any of the previous mentioned wethods, or even left away. There are no spaces allowed inside the emitter-definition.

Of course, the emitter-definition of the draggable HtmlElement should be defined inside the draggable Element as well.

Multiple emitters are posible by separated them with a comma:

<div dropzone="true emittername=someEmitter1,someEmitter2">

Dropzone HTML-attributes

dropzone

Should contain a effect-allowed and/or an emitter as explained above.

Dropzone Plugin

When this module gets imported, it defines the node-plugin: ITSA.Plugins.NodeDropzone. Define a HtmlElement a dropzone or remove dropzone-features can be done using this plugin.

Define a dropzone

document.getElement('#someNode').plug(ITSA.Plugins.dz);

Define a dropzone with options

document.getElement('#someNode').plug(
    ITSA.Plugins.dz,
    {
        move: true,
        copy: true,
        emitter: 'someEmitter1,someEmitter2'
    }
);

Preparing the draggables

The draggable HtmlElements could be set up in a way that they tell the system what dropzones they could be dropped. Only when you set this up, they can be dropped inside a dropzone. This definition can be made at every draggable HtmlElement, or delegated as explained here.

In order to be able to drop a draggable, either the attribute dd-dropzone or dd-emitter should be set on the draggable (or its delegated container).

<div plugin-dd="true" dd-dropzone=".container">drag me</div>

or

<div plugin-dd="true" dd-emitter="redItem">drag me</div>

HTML-attributes

Beside the attribute dd-draggable, dd-handle and dd-emitter -which are defined by the drag-module- you can define the next additional attributes on the draggables. Like shown above, at least dd-dropzone or dd-emitter is required:

<div plugin-dd="true" dd-dropzone".container" >drag me</div>

dd-draggable

dd-handle

Should equal a css-selector of a descendant that should act as a handle where the draggable can be picked up.

dd-dropzone

Css-selector that specifies the dropzone where the draggable HtmlElement could go to.

dd-effect-allowed

Which effects (copy or move) is allowed on the draggable HtmlElement.

dd-emitter

Which emitterName the draggable HtmlElement should have (will overrule the UI-emitterName). The emitterName will be used within the events emittername:dd-drag and emittername:dd-drop

dd-dropzone-movable

Whether the draggable HtmlElement can be moved inside a dropzone (once it gets there)

Draggable attributes by plugin

The node-plugin: ITSA.Plugins.nodeDD can be used as explained here. However, using drag-drop, you can define more options at when plugin (which are all optional):

Define draggable with options

Example

document.getElement('#someNode').plug(
    ITSA.Plugins.dd,
    {
        draggable: true,
        handle: 'h1',
        dropzone: true
        emitter: 'blueItem'
        'effect-allowed': 'move'
        'dropzone-movable': true
    }
);

dd-dropzone or dd-emitter

As explained above, the draggable must have specified at least dd-dropzone or dd-emitter. Also, both can be set up. The difference is this:

Delegate draggable attributes

The same way as draggable containers can delegate dd-attributes to their draggables, dropzones can do this as well. This way the draggable that are moves inside a dropzone can take over the dropzone-specific draggable-attributes. If the dropzone has no delegated attributes, and the draggable element comes from within a delegated container, the draggable will keep the inline attributes from the delegate container.

A dropzone that can delegate to its draggabels could look like this:

<div plugin-dd dd-dropzone="true" dd-draggable="div" dd-handle="h1">
    <div><h1>drag me</h1></div> <!-- draggable item that is part of the dropzone -->
    <div><h1>drag me</h1></div> <!-- draggable item that is part of the dropzone -->
    <div><h1>drag me</h1></div> <!-- draggable item that is part of the dropzone -->
    <div><h1>drag me</h1></div> <!-- draggable item that is part of the dropzone -->
    <div><h1>drag me</h1></div> <!-- draggable item that is part of the dropzone -->
</div>

Move or copy

Items can be moved or copied, where copying can only be done when the draggable has dd-dropzone or dd-emitter defined. The move/copy behaviour is determined by the draggable be setting dd-effect-allowed:

<div plugin-dd="true" dd-dropzone="true" dd-effect-allowed="copy">I will copy</div>

or

<div plugin-dd="true" dd-dropzone="true" dd-effect-allowed="move">I will move</div>

or

<div plugin-dd="true" dd-dropzone="true" dd-effect-allowed="all">I will move or copy</div>

Any draggable that is defined with dd-effect-allowed="all" will change its behaviour when the Ctrl-key (or cmd-key on a Mac) is pressed. These keys can be pressed before, or during dragging.

In case multiple items are copied, the eventobject will have the property e.relativeDragNodes, which is a NodeList that holds the HtmlElements that corresponds with the e.relative list, but is a list with draggable Elements.

Monitoring dropzones

Dropzones can be monitored by subscribing to all separate dropzone-events, or by subscribing to the dropzone-over-event and make use of e.dropzone which is a Promise. If you are familiar with Promises, the latter is highly preferable.

Events

The dropzone comes with 3 events, which all share the same eventobject as that was emitted by the *:dd-event. This means: changing the eventobject in a specific subscriber, makes it available in later subscribers (of other events) during this specific drag-cycle.

Note that the attribute dd-emitter (on the draggable HtmlElement) determines the emitterName. When not set, all events have the UI emitterName and could be listened to without the emitter-prefix.

*:dropzone-over

When a draggable HtmlElement comes over a dropzone. The event will only be emitted if the draggable has the rights to be dropped in the specific dropzone. In case the attribute dd-emitter is not set on the draggable HtmlElement, this event has the UI emitterName (and could be listened to by just listening to the dropzone-over-event).

*:dropzone-out

When a draggable HtmlElement leaves a valid dropzone. In case the attribute dd-emitter is not set on the draggable HtmlElement, this event has the UI emitterName (and could be listened to by just listening to the dropzone-out-event).

*:dropzone-drop

When a draggable item is dropped inside a dropzone (where it has the rights to be dropped). In case the attribute dd-emitter is not set on the draggable HtmlElement, this event has the UI emitterName (and could be listened to by just listening to the dropzone-drop-event).

The eventobject

The eventobject has the following properties:

Notice that e.target refers to the dropzone-Element, whereas e.dragNode refers to the draggable node. In case of copying, there will be e.sourceNode and e.dragNode, because there are twoe HtmlElements involved.

When moving or coying multiple draggables at once, you can inspect e.relatives (and e.relativeDragNodes when copying).

Promises

You can also subscribe to only one event: dropzone-over-event and use e.dropzone (which is a Promise) to monitor further action. This Promise gets resolved when the draggable gets out of the dropzone, or when the draggable is dropped inside the dropzone. The Promise resolves with one argument: onDropzone which is a boolean that tells whether the draggable was dropped.

    ITSA.Event.after('dropzone-over', function(e) {
        var dropId = e.dropTarget.getId();

        e.dropzone.then(
            function(onDropzone) {
                if (onDropzone) {
                    // dropped
                }
                else {
                    // moved outside dropzone without droppping
                }
            }
        );
    });

Change dropbehaviour

The default-function of dd-drop, is defined as doing this:

You can overrule this behaviour by creating a before-subscriber at the dd-drop event and prevent its default behaviour. When define your own behaviuor, you might need two specific methods of DD:

Example:

absorbItem = function(e) {
    e.preventDefault();
    // note that we have to remove both the nodes: original e.target
    // as well as the draggable: e.copyTarget.
    // also note that, when dragging multiple draggables, we have to handle e.relatives
    // which is a hash containing all draggable nodes as well as their originals.
    e.target.remove();
    e.dragNode.remove();
    e.dropTarget.append('<br>'+e.target.getText()+' added');
    ITSA.DD._emitDropzoneDrop(e); // fire thr dropzone-drop event
};

ITSA.Event.before(
    'dd-drop',
    absorbItem
);

Classes

Draggable items are marked with classes, so dragging is easy to style.

Draggable HtmlElements

The first two classes are made avaiable by the drag-module. The last three are extra classes provided by this module.

dd-dragging

On every HtmlElement during dragging

dd-master

The master Element that is dragged. Will only be available when multiple Elements are beging dragged.

dd-copysource

Whenever an HtmlElement gets copied, this class appears on the original HtmlElement.

dd-copy

Whenever an HtmlElement gets copied, this class appears on the draggable HtmlElement.

dd-above-dropzone

Set on both the original element as well as the draggable element whenever the draggable HtmlElement comes above a valid dropzone.

Dropzone HtmlElements

dropzone-awake

Set on any dropzone that registeres a droppable HtmlElement begin moved inside its region.

API Docs