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.
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>
This module brings Drag and Drop to a higher level:
based upon HTML
Move
or Copy
itemsdropzones
where draggable items can be dropped intoemitterNames
for draggable items and specify dropzones to accept specific emittersPromise
to be notified when readyInherited from the drag-module:
constrained
dropzones
where draggable items can be dropped intoemitterNames
for draggable items and specify dropzones to accept specific emittersPromise
to be notified when readymultiple items
at oncehandles
where draggable items can be pickes upDrag 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>
A dropzone should be defined as a dropzone by specifying the attribute dropzone
in one of these ways:
dropzone="move"
dropzone="copy"
dropzone="all"
--> equals move
and copy
dropzone="true"
--> equals move
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.
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">
Should contain a effect-allowed
and/or an emitter
as explained above.
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.
document.getElement('#someNode').plug(ITSA.Plugins.dz);
document.getElement('#someNode').plug(
ITSA.Plugins.dz,
{
move: true,
copy: true,
emitter: 'someEmitter1,someEmitter2'
}
);
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>
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>
Should equal a css-selector
of a descendant that should act as a handle where the draggable can be picked up.
Css-selector that specifies the dropzone
where the draggable HtmlElement could go to.
Which effects (copy
or move
) is allowed on the draggable HtmlElement.
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
Whether the draggable HtmlElement can be moved inside a dropzone (once it gets there)
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):
Example
document.getElement('#someNode').plug(
ITSA.Plugins.dd,
{
draggable: true,
handle: 'h1',
dropzone: true
emitter: 'blueItem'
'effect-allowed': 'move'
'dropzone-movable': true
}
);
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:
dd-dropzone
should be used when you don't need an identification of the draggable.dd-emitter
should be used when you want to identify the draggable to give droppable access.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>
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.
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.
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.
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).
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).
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 has the following properties:
onDropzone
{Boolean} when true
, the draggable is dropped inside the dropzone, otherwise the draggable got outside the dropzone without beging dropped.copy
is made --> e.dragNode is being moved while e.sourceNode stand at its place.before
-subscriber of the dd
-event to inform which nodes are related to the draggable node and should be dragged as well.e.relative
list, but is a list with draggable Elements.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).
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
}
}
);
});
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:
ITSA.DD.restoreDraggables()
--> repositions all draggable items to their original positionITSA.DD._emitDropzoneDrop(e)
fire a dropzone-drop eventabsorbItem = 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
);
Draggable items are marked with classes
, so dragging is easy to style.
The first two classes are made avaiable by the drag-module. The last three are extra classes provided by this module.
On every HtmlElement during dragging
The master Element that is dragged. Will only be available when multiple Elements are beging dragged.
Whenever an HtmlElement gets copied, this class appears on the original HtmlElement.
Whenever an HtmlElement gets copied, this class appears on the draggable HtmlElement.
Set on both the original element as well as the draggable element whenever the draggable HtmlElement comes above a valid dropzone.
Set on any dropzone that registeres a droppable HtmlElement begin moved inside its region.
Table of Contents