I'm having a weird issue with dragging and dropping in html5.
Panel A has a list of the type of elements you can drag. Panel B is where the elements are dragged. Panel C and D are other places you can drag elements, and you can drag and rearrange elements between Panels B, C and D.
My issue is that I'm able to drag an element and drop it INSIDE of another element that's inside one of the panels, which I don't want the user to be able to do. The child elements of those panels don't have any kind of javascript or drag-related properties attached to them, and yet they are currently allowing elements to be dragged inside them.
I've tried attaching "ondrop='return false;'" and "ondragover='return false;'", but neither has worked.
Surely there is a way to turn off the 'allow dragging into' property on an element?
Here's my code:
<div id="elem-002" draggable="true" ondragstart="drag(event)">content</div>
The main panel:
<div id="panel-b" ondrop="drop(event)" ondragover="allowDrop(event)">
<div id="elem-001" draggable="true" ondragstart="drag(event)">content</div>
</div>
The JS:
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("Text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
}
Said another way: I'm able to drag my "elem-002" directly into "elem-001", an element that was already dragged in. This causing nesting of elements that I don't want to occur. How can I prevent this?
Now HTML 5 came up with a Drag and Drop (DnD) API that brings native DnD support to the browser making it much easier to code up. HTML 5 DnD is supported by all the major browsers like Chrome, Firefox 3.5 and Safari 4 etc.
HTML Drag and Drop interfaces enable applications to use drag-and-drop features in browsers. The user may select draggable elements with a mouse, drag those elements to a droppable element, and drop them by releasing the mouse button.
Basically you have to set the correct ev.dataTransfer.dropEffect
in allowDrop
. For your draggable
elements it should be "none"
(dropping is not allowed), and for everything else (or any other element where dropping is allowed) to "all"
Further reading of dropEffect
Live example:
window.allowDrop = function(ev) {
ev.preventDefault();
if (ev.target.getAttribute("draggable") == "true")
ev.dataTransfer.dropEffect = "none"; // dropping is not allowed
else
ev.dataTransfer.dropEffect = "all"; // drop it like it's hot
};
window.drag = function(ev) {
ev.dataTransfer.setData("id", ev.target.id);
};
window.drop = function(ev) {
ev.preventDefault();
var id = ev.dataTransfer.getData("id");
var dragged = document.getElementById(id);
ev.target.appendChild(dragged);
dragged.className += " dropped";
};
.drag {
display: inline-block;
padding: 5px;
background: rgba(0, 0, 0, 0.2);
margin: 2px;
}
.dropzone {
background: #ccc;
padding: 5px;
margin-top: 10px;
}
<div id="first" class="drag" draggable="true" ondragstart="drag(event)">1</div>
<div id="second" class="drag" draggable="true" ondragstart="drag(event)">2</div>
<div class="dropzone" ondrop="drop(event)" ondragover="allowDrop(event)"><div id="third" class="drag dropped" draggable="true" ondragstart="drag(event)">3</div></div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With