Search code examples
javascriptjqueryinteractjs

Javascript Interactjs - Delete div item on drop in dropzone


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>


Solution

  • 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>