EN
JavaScript - drag element from one container to other one
21
points
In this short article, we would like to show how in JavaScript write simple logic that lets' drag some elements from one place to another.
Using the below Dragger
class we are able to create few independent draggable workspaces - items are draggable only between indicated groups.
Note: presented solution doesn't work on touched screens - mouse needed.
Simple usage:
var workspace = document.querySelector('.workspace');
var dragger = new Dragger(workspace);
dragger.addDropzone(workspace.querySelector('.dropzone-1')); // place to put draggable item
dragger.addDropzone(workspace.querySelector('.dropzone-2')); // place to put draggable item
dragger.addDropzone(workspace.querySelector('.dropzone-3')); // place to put draggable item
dragger.addDropzone(workspace.querySelector('.dropzone-4')); // place to put draggable item
dragger.addDraggable(workspace.querySelector('.draggable-1')); // draggable item
dragger.addDraggable(workspace.querySelector('.draggable-2')); // draggable item
dragger.enable();
Practical example:
// ONLINE-RUNNER:browser;
<!doctype html>
<html>
<head>
<script>
var counter = 0;
function checkDraggable(draggable) {
return draggable.$$_TYPE_$$ == 'DRAGGABLE'
};
function checkDropzone(dropzone, selection) {
return dropzone.$$_TYPE_$$ == 'DEROPZONE' && dropzone.$$_ID_$$ == selection.$$_ID_$$;
};
function Dragger(workspace) {
var id = ++counter;
var enabled = false;
var selection = null;
var onDrag = function(e) {
// nothing here ...
};
var onDrop = function(e) {
if (selection) {
var dropzone = e.target;
if (checkDropzone(dropzone, selection)) {
dropzone.classList.remove('active');
dropzone.classList.add('default');
dropzone.appendChild(selection);
}
}
};
var onDragstart = function(e) {
var draggable = e.target;
if (checkDraggable(draggable)) {
draggable.classList.remove('default');
draggable.classList.add('active');
selection = draggable;
}
};
var onDragend = function(e) {
if (selection) {
var draggable = e.target;
if (checkDraggable(draggable)) {
draggable.classList.remove('active');
draggable.classList.add('default');
selection = null;
}
}
};
var onDragover = function(e) {
e.preventDefault();
};
var onDragenter = function(e) {
if (selection) {
var dropzone = e.target;
if (checkDropzone(dropzone, selection)) {
dropzone.classList.remove('default');
dropzone.classList.add('active');
}
}
};
var onDragleave = function(e) {
if (selection) {
var dropzone = e.target;
if (checkDropzone(dropzone, selection)) {
dropzone.classList.remove('active');
dropzone.classList.add('default');
}
}
};
this.addDraggable = function(handle) {
if (handle.$$_TYPE_$$) {
throw new Error('Element already in use.');
}
handle.draggable = true;
handle.$$_ID_$$ = id;
handle.$$_TYPE_$$ = 'DRAGGABLE';
handle.classList.add('default');
};
this.removeDraggable = function(handle) {
if (handle.$$_TYPE_$$ == 'DRAGGABLE') {
handle.draggable = false;
delete handle.$$_ID_$$;
delete handle.$$_TYPE_$$;
handle.classList.remove('default');
}
else
throw new Error('Element is not draggable.');
};
this.addDropzone = function(handle) {
if (handle.$$_TYPE_$$) {
throw new Error('Element already in use.');
}
handle.$$_ID_$$ = id;
handle.$$_TYPE_$$ = 'DEROPZONE';
handle.classList.add('default');
};
this.removeDropzone = function(handle) {
if (handle.$$_TYPE_$$ == 'DEROPZONE') {
delete handle.$$_ID_$$;
delete handle.$$_TYPE_$$;
handle.classList.add('default');
}
else
throw new Error('Element is not dropzone.');
};
this.enable = function() {
if (enabled == true) {
return;
}
workspace.addEventListener('drag', onDrag, false);
workspace.addEventListener('drop', onDrop, false);
workspace.addEventListener('dragstart', onDragstart, false);
workspace.addEventListener('dragend', onDragend, false);
workspace.addEventListener('dragover', onDragover, false);
workspace.addEventListener('dragenter', onDragenter, false);
workspace.addEventListener('dragleave', onDragleave, false);
enabled = false;
};
this.disable = function() {
if (enabled == false) {
return;
}
workspace.removeEventListener('drag', onDrag, false);
workspace.removeEventListener('drop', onDrop, false);
workspace.removeEventListener('dragstart', onDragstart, false);
workspace.removeEventListener('dragend', onDragend, false);
workspace.removeEventListener('dragover', onDragover, false);
workspace.removeEventListener('dragenter', onDragenter, false);
workspace.removeEventListener('dragleave', onDragleave, false);
enabled = true;
};
}
</script>
</head>
<body>
<style>
.list > * + * {
margin: 10px 0 0 0;
}
.draggable {
width: 200px;
height: 20px;
text-align: center;
}
.draggable.default {
background: white;
opacity: 1.0;
}
.draggable.active {
background: orange;
opacity: 0.5;
}
.dropzone {
padding: 10px;
background: #fbea68;
width: 200px;
height: 20px;
}
.dropzone.default {
border: 3px solid #FFFFFF;
}
.dropzone.active {
border: 3px dotted #c5b858;
}
</style>
<div style="display: flex">
<div class="workspace list">
<div class="item dropzone">
<div class="item draggable">
Drag me down!
</div>
</div>
<div class="item dropzone"></div>
<div class="item dropzone"></div>
<div class="item dropzone"></div>
</div>
<div class="workspace list">
<div class="item dropzone">
<div class="item draggable">
Drag me down!
</div>
</div>
<div class="item dropzone"></div>
<div class="item dropzone"></div>
<div class="item dropzone"></div>
</div>
</div>
<script>
// Usage example:
/*
var workspace = document.querySelector('.workspace');
var dragger = new Dragger(workspace);
dragger.addDropzone(workspace.querySelector('.dropzone-1')); // place to put item
dragger.addDropzone(workspace.querySelector('.dropzone-2')); // place to put item
dragger.addDropzone(workspace.querySelector('.dropzone-3')); // place to put item
dragger.addDropzone(workspace.querySelector('.dropzone-4')); // place to put item
dragger.addDraggable(workspace.querySelector('.draggable-1')); // draggable item
dragger.addDraggable(workspace.querySelector('.draggable-2')); // draggable item
dragger.enable();
*/
//NOTE: Below code lets' to enable items dragging on all detected workspaces.
function prepareDropzones(dragger, workspace) {
var dropzones = workspace.querySelectorAll('.dropzone');
for (var j = 0; j < dropzones.length; ++j) {
dragger.addDropzone(dropzones[j]);
}
}
function prepareDraggables(dragger, workspace) {
var draggables = workspace.querySelectorAll('.draggable');
for (var j = 0; j < draggables.length; ++j) {
dragger.addDraggable(draggables[j]);
}
}
function prepareWorkspace(workspace) {
var dragger = new Dragger(workspace);
prepareDropzones(dragger, workspace);
prepareDraggables(dragger, workspace);
dragger.enable();
}
function prepareWorkspaces() {
var workspaces = document.querySelectorAll('.workspace');
for (var i = 0; i < workspaces.length; ++i) {
prepareWorkspace(workspaces[i])
}
}
prepareWorkspaces();
</script>
</body>
</html>