OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

How to change drag and drop from vertically to horizontally in JavaScript?

  • Thread starter Thread starter Program
  • Start date Start date
P

Program

Guest
I am working on a sortable list, I am very new to javascript, I am able to vertically drag and drop. but i am not able do the same for horizontally. I saw a tutorial completed this.

For horizontal do i need to use X axis? If somebody can help me out with this code.

From what I can tell, the drop, along with the dragstart and dragend events, only are aware of the element they are going into. They can't tell if the mouse is on the top half of the dropzone, or the bottom half. How to basically create dropzone and switch element in case of horizontal

I want to create something like this

enter image description here

I don't want to do swapping between the words.


Code:
const list = document.querySelector('.list')
const listItems = document.querySelectorAll('.list-item')

// let dragIndex, dragSource

const getMouseOffset = (evt) => {
  const targetRect = evt.target.getBoundingClientRect()
  const offset = {
    x: evt.pageX - targetRect.left,
    y: evt.pageY - targetRect.top
  }
  return offset
}

const getElementVerticalCenter = (el) => {
  const rect = el.getBoundingClientRect()
  return (rect.bottom - rect.top) / 2
}

const appendPlaceholder = (evt, idx) => {
  evt.preventDefault()
  if (idx === dragIndex) {
    return
  }
  
  const offset = getMouseOffset(evt)
  const middleY = getElementVerticalCenter(evt.target)
  const placeholder = list.children[dragIndex]
  
  // console.log(`hover on ${idx} ${offset.y > middleY ? 'bottom half' : 'top half'}`)
  if (offset.y > middleY) {
    list.insertBefore(evt.target, placeholder)
  } else if (list.children[idx + 1]) {
    list.insertBefore(evt.target.nextSibling || evt.target, placeholder)
  }
  return
}

function sortable(rootEl, onUpdate) {
   var dragEl;
   
   // Making all siblings movable
   [].slice.call(rootEl.children).forEach(function (itemEl) {
       itemEl.draggable = true;
   });
   
   // Function responsible for sorting
   function _onDragOver(evt) {
       evt.preventDefault();
       evt.dataTransfer.dropEffect = 'move';
      
       var target = evt.target;
       if (target && target !== dragEl && target.nodeName == 'DIV') {
           // Sorting
       const offset = getMouseOffset(evt)
       const middleY = getElementVerticalCenter(evt.target)

      if (offset.y > middleY) {
        rootEl.insertBefore(dragEl, target.nextSibling)
      } else {
        rootEl.insertBefore(dragEl, target)
      }
     }
   }
   
   // End of sorting
   function _onDragEnd(evt){
       evt.preventDefault();
      
       dragEl.classList.remove('ghost');
       rootEl.removeEventListener('dragover', _onDragOver, false);
       rootEl.removeEventListener('dragend', _onDragEnd, false);


       // Notification about the end of sorting
       onUpdate(dragEl);
   }
   
   // Sorting starts
   rootEl.addEventListener('dragstart', function (evt){
       dragEl = evt.target; // Remembering an element that will be moved
       
       // Limiting the movement type
       evt.dataTransfer.effectAllowed = 'move';
       evt.dataTransfer.setData('Text', dragEl.textContent);


       // Subscribing to the events at dnd
       rootEl.addEventListener('dragover', _onDragOver, false);
       rootEl.addEventListener('dragend', _onDragEnd, false);


       setTimeout(function () {
           // If this action is performed without setTimeout, then
           // the moved object will be of this class.
           dragEl.classList.add('ghost');
       }, 0)
   }, false);
}
                       
// Using                    
sortable(list, function (item) {
   console.log(item);
});

Code:
.list {
  padding: 1rem;
}

.ghost {
    opacity: 1;
}

.list-item {
  background: #8bb3f4;
  padding: 0.5rem;
  border: 1px solid white;
  margin: 1px 0;
}

.placeholder {
  display: none;
  background: #303742;
  pointer-events: none;
}

Code:
<div class="list">
  <div class="list-item" draggable=true>
    Item 1
  </div>
  <div class="list-item" draggable=true>
    Item 2
  </div>
  <div class="list-item" draggable=true>
    Item 3
  </div>
  <div class="list-item" draggable=true>
    Item 4
  </div>
</div>
<p>I am working on a sortable list, I am very new to javascript, I am able to vertically drag and drop. but i am not able do the same for horizontally. I saw a tutorial completed this.</p>
<p>For horizontal do i need to use X axis? If somebody can help me out with this code.</p>
<p>From what I can tell, the drop, along with the dragstart and dragend events, only are aware of the element they are going into. They can't tell if the mouse is on the top half of the dropzone, or the bottom half. How to basically create dropzone and switch element in case of horizontal</p>
<p>I want to create something like this</p>
<p><a href="https://i.sstatic.net/YwFMs.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/YwFMs.png" alt="enter image description here" /></a></p>
<p>I don't want to do swapping between the words.</p>
<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>const list = document.querySelector('.list')
const listItems = document.querySelectorAll('.list-item')

// let dragIndex, dragSource

const getMouseOffset = (evt) => {
const targetRect = evt.target.getBoundingClientRect()
const offset = {
x: evt.pageX - targetRect.left,
y: evt.pageY - targetRect.top
}
return offset
}

const getElementVerticalCenter = (el) => {
const rect = el.getBoundingClientRect()
return (rect.bottom - rect.top) / 2
}

const appendPlaceholder = (evt, idx) => {
evt.preventDefault()
if (idx === dragIndex) {
return
}

const offset = getMouseOffset(evt)
const middleY = getElementVerticalCenter(evt.target)
const placeholder = list.children[dragIndex]

// console.log(`hover on ${idx} ${offset.y > middleY ? 'bottom half' : 'top half'}`)
if (offset.y > middleY) {
list.insertBefore(evt.target, placeholder)
} else if (list.children[idx + 1]) {
list.insertBefore(evt.target.nextSibling || evt.target, placeholder)
}
return
}

function sortable(rootEl, onUpdate) {
var dragEl;

// Making all siblings movable
[].slice.call(rootEl.children).forEach(function (itemEl) {
itemEl.draggable = true;
});

// Function responsible for sorting
function _onDragOver(evt) {
evt.preventDefault();
evt.dataTransfer.dropEffect = 'move';

var target = evt.target;
if (target && target !== dragEl && target.nodeName == 'DIV') {
// Sorting
const offset = getMouseOffset(evt)
const middleY = getElementVerticalCenter(evt.target)

if (offset.y > middleY) {
rootEl.insertBefore(dragEl, target.nextSibling)
} else {
rootEl.insertBefore(dragEl, target)
}
}
}

// End of sorting
function _onDragEnd(evt){
evt.preventDefault();

dragEl.classList.remove('ghost');
rootEl.removeEventListener('dragover', _onDragOver, false);
rootEl.removeEventListener('dragend', _onDragEnd, false);


// Notification about the end of sorting
onUpdate(dragEl);
}

// Sorting starts
rootEl.addEventListener('dragstart', function (evt){
dragEl = evt.target; // Remembering an element that will be moved

// Limiting the movement type
evt.dataTransfer.effectAllowed = 'move';
evt.dataTransfer.setData('Text', dragEl.textContent);


// Subscribing to the events at dnd
rootEl.addEventListener('dragover', _onDragOver, false);
rootEl.addEventListener('dragend', _onDragEnd, false);


setTimeout(function () {
// If this action is performed without setTimeout, then
// the moved object will be of this class.
dragEl.classList.add('ghost');
}, 0)
}, false);
}

// Using
sortable(list, function (item) {
console.log(item);
});</code></pre>
<pre class="snippet-code-css lang-css prettyprint-override"><code>.list {
padding: 1rem;
}

.ghost {
opacity: 1;
}

.list-item {
background: #8bb3f4;
padding: 0.5rem;
border: 1px solid white;
margin: 1px 0;
}

.placeholder {
display: none;
background: #303742;
pointer-events: none;
}</code></pre>
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="list">
<div class="list-item" draggable=true>
Item 1
</div>
<div class="list-item" draggable=true>
Item 2
</div>
<div class="list-item" draggable=true>
Item 3
</div>
<div class="list-item" draggable=true>
Item 4
</div>
</div></code></pre>
</div>
</div>
</p>
Continue reading...
 

Latest posts

Top