Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drag dataTransfer data unavailable in ondragover event

I'm trying to get the hang of html5 drag and drop events.

function rowDragStart(event) {
    let targetRowId = event.target.attributes.row.value;
    event.dataTransfer.setData("text/plain", targetRowId);
}

function rowDragOver(event) {
    event.preventDefault();
    let draggingId = event.dataTransfer.getData('text');
}

For now I'm just trying to put something in the dataTransfer object in dragStart, and retrieve it in dragOver. The problem is it's not present in drag over. I've set breakpoints and these events are getting called, but getData('text') returns empty string, along with every other possibility I can think of.

like image 632
Adam Rackis Avatar asked Dec 02 '16 20:12

Adam Rackis


1 Answers

According to the Event-Summary of the HTML5 Drag&Drop specification, the mode of the Drag data store's dragover event is Protected mode.

Protected mode:

The formats and kinds in the drag data store list of items representing dragged data can be enumerated, but the data itself is unavailable and no new data can be added.

This is for both files and html5 element's drag&drop.

In other words - you can access the types of the dragged elements and the number of elements dragged, but their data is not available until you do the actual drop.

This is by design

Here is an example for the HTML5 elements drag&drop:

function dragstart_handler(ev) {
  console.log("drag start");
  // Change the source element's background color to signify drag has started
  ev.currentTarget.style.border = "dashed";
  // Set the drag's format and data. Use the event target's id for the data 
  ev.dataTransfer.setData("text/plain", ev.target.id);
}

function dragover_handler(ev) {
  console.log("drag over, total types:", ev.dataTransfer.types.length, 'type available:', ev.dataTransfer.types[0]);
  ev.preventDefault();
}

function drop_handler(ev) {
  console.log("drop, total types:", ev.dataTransfer.types.length, 'data dropped:', ev.dataTransfer.getData('text/plain'));
  ev.preventDefault();
  
  // Clear the drag data cache (for all formats/types)
  ev.dataTransfer.clearData();
}
div {
  margin: 0em;
  padding: 2em;
}
#source {
  color: blue;
  border: 1px solid black;
}
#target {
  border: 1px solid black;
}
<div>
  <p id="source" ondragstart="dragstart_handler(event);" draggable="true">
    Select this element, drag it to the Drop Zone and then release the selection to move the element.</p>
</div>
<div id="target" ondrop="drop_handler(event);" ondragover="dragover_handler(event);">Drop Zone</div>
like image 65
Dekel Avatar answered Sep 23 '22 15:09

Dekel