Is there a HTML5 default way for dragging and dropping -multiple- elements into another html element on the same page?
It seems the HTML5 attribute draggable, which applies to one element says: "You can drag me, but you'd need multiple input devices to select another draggable element at the same time."
As a workaround one can add identifiers to selected elements using js and get all selected elements on a certain event and do what we want. But is this really the "correct" way?
When you inspect the drop event there is an interface for multiple files, when handling file drag and drop. And there is also the items property- at least in Chrome.
There are differences across browsers.
In Chrome
The drop event contains the items property
dataTransfer: DataTransfer
items: DataTransferItemList
length: 0
Items seems to be 0, no matter if you dragged an item or not.
In Firefox
The drop event contains the mozItemCount property
dataTransfer: DataTransfer
mozItemCount: 1
mozItemCount seems to be at least 1.
Here is a little demo
Where you can observe your developer tools console:
This source was taken from here: http://www.html5rocks.com/en/tutorials/dnd/basics/
$(function(){
// Copied from: http://www.html5rocks.com/en/tutorials/dnd/basics/
var cols_ = document.querySelectorAll('.column');
var dragSrcEl_ = null;
handleDragStart = function(e) {
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/html', this.innerHTML);
dragSrcEl_ = this;
this.style.opacity = '0.4';
// this/e.target is the source node.
$(this).addClass('moving');
};
handleDragOver = function(e) {
if (e.preventDefault) {
e.preventDefault(); // Allows us to drop.
}
e.dataTransfer.dropEffect = 'move';
return false;
};
handleDragEnter = function(e) {
$(this).addClass('over');
};
handleDragLeave = function(e) {
// this/e.target is previous target element.
$(this).removeClass('over');
};
handleDrop = function(e) {
// this/e.target is current target element.
console.log(e.dataTransfer);
if (e.stopPropagation) {
e.stopPropagation(); // stops the browser from redirecting.
}
// Don't do anything if we're dropping on the same column we're dragging.
if (dragSrcEl_ != this) {
dragSrcEl_.innerHTML = this.innerHTML;
this.innerHTML = e.dataTransfer.getData('text/html');
}
return false;
};
handleDragEnd = function(e) {
// this/e.target is the source node.
this.style.opacity = '1';
[].forEach.call(cols_, function (col) {
$(col).removeClass('over');
$(col).removeClass('moving');
});
};
[].forEach.call(cols_, function (col) {
col.setAttribute('draggable', 'true'); // Enable columns to be draggable.
col.addEventListener('dragstart', this.handleDragStart, false);
col.addEventListener('dragenter', this.handleDragEnter, false);
col.addEventListener('dragover', this.handleDragOver, false);
col.addEventListener('dragleave', this.handleDragLeave, false);
col.addEventListener('drop', this.handleDrop, false);
col.addEventListener('dragend', this.handleDragEnd, false);
});
});
.column {
height: 150px;
width: 150px;
float: left;
border: 2px solid #666666;
background-color: #ccc;
margin-right: 5px;
border-radius: 10px;
box-shadow: inset 0 0 3px #000;
text-align: center;
cursor: move;
margin-bottom: 30px;
}
.column header {
color: #fff;
text-shadow: #000 0 1px;
box-shadow: 5px;
padding: 5px;
background: linear-gradient(left center, rgb(0,0,0), rgb(79,79,79), rgb(21,21,21));
border-bottom: 1px solid #ddd;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}
.column {
transition: transform 0.2s ease-out;
}
.column.over {
border: 2px dashed #000;
}
.column.moving {
opacity: 0.25;
transform: scale(0.8);
}
.column .count {
padding-top: 15px;
font-weight: bold;
text-shadow: #fff 0 1px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div class="cols">
<div class="column">
<header>C</header>
</div>
<div class="column">
<header>B</header>
</div>
<div class="column">
<header>A</header>
</div>
</div>
So it looks like the vendors are preparing for multiple item drag and drop, but there seems no be no default. Please correct me if i'am wrong.
I read these articles to better understand dnd
- https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Drag_and_drop
- http://html5doctor.com/native-drag-and-drop/
Further readings:
dragstartyourself too. - a better oliversetDatain your example. I personally store the data outside (e.g. in a variable). That gives me every freedom and in the end it doesn't really matter where the data comes from. You could usesetDatato send a serialized object or array with ids (JSON.stringify / JSON.parse). - a better oliver