Javascript Interactjs - Delete div item on drop in dropzone

567 Views Asked by At

Using interactjs I'm trying to delete an item when being dropped in the dropzone that serves as bin. The tricky part here is that the dropzone must be in position:fixed and initially the draggable item is in position:relative. I think this causes the dropzone not to be able to detect when something is being dropped when the draggable is in a different position. I tried to fix this by changing position:absolute to draggable when item is being dragged(on.dragmove) but inevitably, the draggable overlaps the dropzone. How do I make this work?

/**
* 
* 
* ineracjs
* drag and drop
* 
* 
*/
function interactJs(){

var element = document.querySelector('.draggable');

var x = 0; var y = 0

interact(element)
.resizable({
// resize from all edges and corners
edges: { left: true, right: true, bottom: true, top: true },

listeners: {
move (event) {
var target = event.target
var x = (parseFloat(target.getAttribute('data-x')) || 0)
var y = (parseFloat(target.getAttribute('data-y')) || 0)

// update the element's style
target.style.width = event.rect.width + 'px'
target.style.height = event.rect.height + 'px'

// translate when resizing from top or left edges
x += event.deltaRect.left
y += event.deltaRect.top

target.style.transform = 'translate(' + x + 'px,' + y + 'px)'

target.setAttribute('data-x', x)
target.setAttribute('data-y', y)
target.textContent = Math.round(event.rect.width) + '\u00D7' + Math.round(event.rect.height)
}
},
modifiers: [
// keep the edges inside the parent
interact.modifiers.restrictEdges({
outer: 'parent'
}),

// minimum size
interact.modifiers.restrictSize({
min: { width: 100, height: 50 }
})
],

inertia: true
})
.draggable({
modifiers: [
interact.modifiers.snap({
targets: [
interact.snappers.grid({ x: 30, y: 30 })
],
range: Infinity,
relativePoints: [ { x: 0, y: 0 } ]
}),
interact.modifiers.restrict({
restriction: element.parentNode,
elementRect: { top: 0, left: 0, bottom: 1, right: 1 },
endOnly: true
})
],
inertia: true
})
.on('dragmove', function (event) {
x += event.dx
y += event.dy

event.target.style.transform = 'translate(' + x + 'px, ' + y + 'px)';
event.target.style.position = 'absolute';//change position to absolute to match same level position as bin?
})


/**
* 
* 
* delete
* dropzone
* 
*/
var bin = document.querySelector('.element-trash');

interact(bin)
.dropzone({
accept: '.draggable',
// Require a 75% element overlap for a drop to be possible
overlap: 0.75,
ondrop: function (event) {

$(event.target).remove();// remove from DOM

console.log(event.target);
}
})
.on('dropactivate', function (event) {
event.target.classList.add('drop-activated')
})
}interactJs();
.element-trash{
height: 100%;
color: black;
background: gold;
padding: 1%;
width: 120px;
position: fixed;
z-index: 1;
top: 0;
left: 0;
overflow-x: hidden;
transition: 0.5s;
/* padding-top: 60px; */
}
#main{
padding: 0px !important;
margin-left: 120px;
}
#main{
background-color: #eceef0;
}
#main {
transition: margin-left .5s;
height: 100% !important;
/*padding: 16px;*/
}
.draggable {
width: 10%;
min-height: 6.5em;
background-color: #29e !important;
color: white;
border-radius: 0.75em;
padding: 4%;
touch-action: none;
user-select: none;
z-index: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!--ineractjs-->
<script src="https://cdn.jsdelivr.net/npm/interactjs/dist/interact.min.js"></script>

<div class='element-trash'>Drop to delete</div>

<div id='main'>

<div class='draggable'>Drag me</div>

</div>

1

There are 1 best solutions below

0
Grogu On BEST ANSWER

For the dropzone to work, you need to have all required functions that I was obviously missing in my original post. Major brain fart.

functions

ondropactivate
ondragenter
ondragleave
ondrop
ondropdeactivate

working codes

/**
* 
* 
* ineracjs
* drag and drop
* 
* 
*/
var element = document.querySelector('.draggable');

var x = 0; var y = 0

interact(element)
.resizable({
// resize from all edges and corners
edges: { left: true, right: true, bottom: true, top: true },

listeners: {
move (event) {
var target = event.target
var x = (parseFloat(target.getAttribute('data-x')) || 0)
var y = (parseFloat(target.getAttribute('data-y')) || 0)

// update the element's style
target.style.width = event.rect.width + 'px'
target.style.height = event.rect.height + 'px'

// translate when resizing from top or left edges
x += event.deltaRect.left
y += event.deltaRect.top

target.style.transform = 'translate(' + x + 'px,' + y + 'px)'

target.setAttribute('data-x', x)
target.setAttribute('data-y', y)
target.textContent = Math.round(event.rect.width) + '\u00D7' + Math.round(event.rect.height)
}
},
modifiers: [
// keep the edges inside the parent
interact.modifiers.restrictEdges({
outer: 'parent'
}),

// minimum size
interact.modifiers.restrictSize({
min: { width: 100, height: 50 }
})
],

inertia: true
})
.draggable({
modifiers: [
interact.modifiers.snap({
targets: [
interact.snappers.grid({ x: 30, y: 30 })
],
range: Infinity,
relativePoints: [ { x: 0, y: 0 } ]
}),
interact.modifiers.restrict({
restriction: element.parentNode,
elementRect: { top: 0, left: 0, bottom: 1, right: 1 },
endOnly: true
})
],
inertia: true
})
.on('dragmove', function (event) {
x += event.dx
y += event.dy

event.target.style.transform = 'translate(' + x + 'px, ' + y + 'px)';
event.target.style.position = 'absolute';
event.target.style.zIndex = '2';
})
/**
* 
* 
* delete
* dropzone
* 
*/
// enable draggables to be dropped into this
interact('.dropzone').dropzone({
// only accept elements matching this CSS selector
accept: '.draggable',
// Require a 75% element overlap for a drop to be possible
overlap: 0.25,

// listen for drop related events:

ondropactivate: function (event) {
// add active dropzone feedback
event.target.classList.add('drop-active')
},
ondragenter: function (event) {
var draggableElement = event.relatedTarget
var dropzoneElement = event.target

// feedback the possibility of a drop
dropzoneElement.classList.add('drop-target')
draggableElement.classList.add('can-drop')
draggableElement.textContent = 'Dragged in'
},
ondragleave: function (event) {
// remove the drop feedback style
event.target.classList.remove('drop-target')
event.relatedTarget.classList.remove('can-drop')
event.relatedTarget.textContent = 'Dragged out'
},
ondrop: function (event) {
//when dropped delete
$(event.relatedTarget).remove();// remove from DOM
//event.relatedTarget.textContent = 'Dropped'
},
ondropdeactivate: function (event) {
// remove active dropzone feedback
event.target.classList.remove('drop-active')
event.target.classList.remove('drop-target')
}
})
.dropzone {
  border: dashed 4px transparent;
  border-radius: 4px;
  margin: 10px auto 30px;
  padding: 10px;
  transition: background-color 0.3s;
}
.element-trash{
height: 100%;
color: black;
background: gold;
padding: 1%;
width: 120px;
position: fixed;
z-index: 1;
top: 0;
left: 0;
overflow-x: hidden;
transition: 0.5s;
/* padding-top: 60px; */
}

.drop-active {
  border-color: #aaa;
}

.drop-target {
  background-color: #29e;
  border-color: #fff;
  border-style: solid;
}

.drag-drop {
  display: inline-block;
  min-width: 40px;
  padding: 2em 0.5em;
  margin: 1rem 0 0 1rem;
  color: #fff;
  background-color: #29e;
  border: solid 2px #fff;
  touch-action: none;
  transform: translate(0px, 0px);
  transition: background-color 0.3s;
}

.drag-drop.can-drop {
  color: #000;
  background-color: #4e4;
}
.draggable {
background-color: #29e !important;
color: white;
border-radius: 0.75em;
padding: 4%;
touch-action: none;
user-select: none;
margin-left: 120px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!--ineractjs-->
<script src="https://cdn.jsdelivr.net/npm/interactjs/dist/interact.min.js"></script>


<div class="dropzone element-trash">Drop to delete</div>

<div id="yes-drop" class="draggable drag-drop"> Drag Me </div>