How to drag one div item from a scrollable area and drop it to another scrollable area?

57 Views Asked by At

I want to make a vertical and scrollable list of custom divs and I want to dragged them from it to another div area, droppable one, also with vertical scroll, see image below:

https://i.stack.imgur.com/v1N1j.png

I can't do that with following HTML code:

<div class="container-fluid">
   <div id="sdsds" class="row">  
      <button id="addNewDevice" class="btn btn-primary">New Device</button>
   </div>
   <br>
   <div id="shared-lists" class="row">
      <div id="example2-left" class="list-group col"  style="overflow-y: scroll;height: 23em; max-width: 30%;">
         <div id="parentItem_Device1" class="list-group-item draggable" style="background-color: #ffffff26; border: 3px solid #a1a1a1; margin-bottom: 5px; padding: 0.1rem 0.25rem; position: relative;">
            <div class="row">
               <div class="col-form-label col-lg-6 col-sm-6 col-xs-6 col-md-6 col-xl-9 col-xxl-6">
                  <svg style="cursor: move;" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-grip-vertical" viewBox="0 0 16 16">
                     <path d="M7 2a1 1 0 1 1-2 0 1 1 0 0 1 2 0m3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0M7 5a1 1 0 1 1-2 0 1 1 0 0 1 2 0m3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0M7 8a1 1 0 1 1-2 0 1 1 0 0 1 2 0m3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0m-3 3a1 1 0 1 1-2 0 1 1 0 0 1 2 0m3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0m-3 3a1 1 0 1 1-2 0 1 1 0 0 1 2 0m3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0"></path>
                  </svg>
                  <span id="parentItemName_Device1">Device 1<span> </span></span>
               </div>
               <div class="col-lg-1 col-md-1 col-sm-1 col-xs-1 col-xl-1 col-xxl-1">
                  <a href="javascript:;" id="ww" class="btn btn-sm btn-clean btn-icon" title="Delete">
                     <span class="svg-icon svg-icon-md">
                        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="18px" height="24px" viewBox="0 0 24 24" version="1.1">
                           <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
                              <rect x="0" y="0" width="24" height="24"></rect>
                              <path d="M6,8 L6,20.5 C6,21.3284271 6.67157288,22 7.5,22 L16.5,22 C17.3284271,22 18,21.3284271 18,20.5 L18,8 L6,8 Z" fill="#B5B5C3" fill-rule="nonzero"></path>
                              <path d="M14,4.5 L14,4 C14,3.44771525 13.5522847,3 13,3 L11,3 C10.4477153,3 10,3.44771525 10,4 L10,4.5 L5.5,4.5 C5.22385763,4.5 5,4.72385763 5,5 L5,5.5 C5,5.77614237 5.22385763,6 5.5,6 L18.5,6 C18.7761424,6 19,5.77614237 19,5.5 L19,5 C19,4.72385763 18.7761424,4.5 18.5,4.5 L14,4.5 Z" fill="#000000" opacity="0.3"></path>
                           </g>
                        </svg>
                     </span>
                  </a>
               </div>
            </div>
         </div>
      </div>
      <div id="example2-right" class="list-group col"  style="overflow-y: scroll;height: 23em;">
         <div class="list-group-item tinted treeParent" style="background-color: #78787826; border: 3px solid #a1a1a1; margin-bottom: 5px;">
            <span>DESTINATION 1</span>
            <div id="droppable" class="dropzones">
               <p>Drop here</p>
            </div>
         </div>
         <div class="list-group-item tinted treeParent" style="background-color: #78787826; border: 3px solid #a1a1a1; margin-bottom: 5px;">
            <span>DESTINATION 1</span>                                 
            <div id="droppable2" class="dropzones">
               <p>Drop here</p>
            </div>
         </div>
      </div>
   </div>
</div>

Every time that I've tried to dragged one item I can't do it, because scrollable area didn't let me, see image:

This is my basic jquery draggable / droppable code:

$(".draggable").draggable({
    revert: "false",
    helper: "clone"
});

$('.dropzones').droppable({ 
    drop: function(event, ui) {
        var newClone = $(ui.helper).clone();
        $(this).after(newClone);
    } 
});

And I've used this jquery lib. version:

<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

Do you have any suggestion?

1

There are 1 best solutions below

0
On

Maybe you could remove the scrolling overflow when an item is dragged. Here I give the <div> the class name noscroll to let the overflow be hidden. When the drop happens the class name is removed again. The same could be done for the destination if necessary.

document.querySelector('ul.source').addEventListener('dragstart', e => {
  e.dataTransfer.setData('text/plain', e.target.dataset.id);
  e.target.closest('div').classList.add('noscroll');
});

document.querySelector('ul.destination').addEventListener('dragover', e => {
  e.preventDefault();
  //e.target.closest('div').classList.add('noscroll');
});

document.querySelector('ul.destination').addEventListener('drop', e => {
  e.preventDefault();
  let id = e.dataTransfer.getData('text/plain');
  let sourceElm = document.querySelector(`li[data-id="${id}"]`);
  e.target.closest('ul.destination').append(sourceElm);
  [...document.querySelectorAll('div.noscroll')]
    .forEach(div => div.classList.remove('noscroll'));
});
body {
  display: grid;
  grid-template-columns: 50vw 50vw;
}

div {
  border: solid thin black;
  overflow: scroll;
  height: 50vh;
}

div.noscroll {
  overflow: hidden;
}

div:nth-child(1){
  grid-column: 1;
  
}

div:nth-child(2){
  grid-column: 2;
}

ul {
  list-style: none;
  margin: 0;
  padding: .5em;
  height: 80vh;
  width: 70vw;
}

ul.destination:after {
  display: inline-block;
  content: "Drop here...";
  background-color: white;
  border: dotted black medium;
  width: 100%;
  padding: .5em;
  margin: .5em;
}

li {
  border: solid thin navy;
  padding: .5em;
  margin: .5em;
}
<div>
  <ul class="source">
    <li draggable="true" data-id="1">Item 1</li>
    <li draggable="true" data-id="2">Item 2</li>
  </ul>
</div>
<div>
  <ul class="destination"></ul>
</div>