Drag And Drop

Overview

Use the GamefaceDnD library to enable drag and drop in Prysm. Add the library to the end of the body to make sure that all draggable elements were loaded.

<script src="drag_and_drop.js"></script>

This adds support for the standard drag events:

EventOn Event HandlerFires when
dragondraga draggable element is dragged
dragendondragenda drag operation ends
dragenterondragentera dragged item enters a valid drop target
dragleaveondragleavea dragged item leaves a valid drop target
dragoverondragovera dragged item is dragged over valid drop target
dragstartondragstartthe user starts dragging an item
dropondropa dragged item is dropped into a valid drop target

Usage

To enable drag and drop events call the enableDrag method from the GamefaceDnD library:

    GamefaceDnD.enableDrag(document.querySelector('myContainer'));

To make an element within the drag-enabled container draggable set its draggable attribute to true:

<div draggable="true" class="image"></div>

To make an element a valid drop target add global handlers for ondragenter and ondragover which cancel the default behavior by returning false from attribute-defined event listeners:

<div ondragover="return false" ondragenter="return false">

or by calling the preventDefault method of the event:

<script>
    function onDragOver(event) {
        event.preventDefault();
    }

    function onDragEnter(event) {
        event.preventDefault();
    }
</script>
<div ondragover="onDragOver()" ondragenter="onDragEnter()">

After you’ve defined the draggable items and the valid dropzones you can define what should happen when a drag event occurs:

let dragged;

document.addEventListener("dragstart", function (event) {
    // store a reference to the dragged element
    dragged = event.target;
});

If you want to add an effect when the dragged element enters or leaves a dropzone add event handlers for dragenter and dragleave:

document.addEventListener("dragenter", function (event) {
    // highlight potential drop target when the draggable element enters it
    if (event.target.classList.contains('dropzone')) {
        event.target.classList.add('over-dropzone');
    }
});

document.addEventListener("dragleave", function (event) {
    // reset background of potential drop target when the draggable element leaves it
    if (event.target.classList.contains('dropzone')) {
        event.target.classList.remove('over-dropzone');
    }
});

Using the DataTransfer object

You can use the dataTransfer property of the drag event object to add or read data related to the drag and drop operation. The differences to the standard DataTransfer object are:

  1. DataTransfer.files is not supported
  2. DataTransferItem.kind supports string only
  3. DataTransferItem.getAsFile() is not supported
  4. DataTransfer.setDragImage() is not supported

You can add data to the DataTransferItemList:

function dragstart_handler(event) {
    // Add this element's id to the drag payload so the drop handler will
    // know which element to add to its tree
    var dataList = event.dataTransfer.items;
    dataList.add(event.target.id, "text/plain");
    // Add some other items to the drag payload
    dataList.add("<p>... paragraph ...</p>", "text/html");
    dataList.add("http://www.example.org", "text/uri-list");
}

After that you can read them:

function drop_handler(event) {
    const data = event.dataTransfer.items;
    // Loop through the dropped items and log their data
    for (var i = 0; i < data.length; i++) {
        if ((data[i].kind == 'string') && (data[i].type.match('^text/plain'))) {
            // This item is the target node
            data[i].getAsString(function (stringResult) {
                event.target.appendChild(document.getElementById(stringResult));
            });
        } else if ((data[i].kind == 'string') && (data[i].type.match('^text/html'))) {
            // Drag data item is HTML
        } else if ((data[i].kind == 'string') && (data[i].type.match('^text/uri-list'))) {
            // Drag data item is URI
        }
    }
}

You can also use the setData and getData methods directly from the DataTransfer.

The only dropEffect that is currently supported is move.