I am trying to build a very simple drag and drop website. The user can drag a preset ‘section’ from a sidebar which contains different numbers of columns, referred to as ‘cells’. The user drags it onto a canvas and can rearrange the cells and sections. Sections are in rows, and are the parent of these cells.
The issue is that the user is not able to move a cell from one section to another section if they try to drop it in front of the first cell of that section or after the last cell of that section. Anything in between is working.
Code snippet:
if (userOption.classList.contains('gen-section')) { // Different actions depending on class of element
let dropPosition = ev.clientY;
let elements = document.querySelectorAll('.gen-section');
let closestElement = null;
elements.forEach((element) => {
if (!closestElement || Math.abs(dropPosition - element.getBoundingClientRect().top) < Math.abs(dropPosition - closestElement.getBoundingClientRect().top)) {
closestElement = element;
}
});
if (dropPosition < closestElement.getBoundingClientRect().top + closestElement.offsetHeight / 2) {
// Insert before the closest element if the drop position is above its midpoint
closestElement.parentNode.insertBefore(userOption, closestElement);
} else {
// Insert after the closest element if the drop position is below its midpoint
closestElement.parentNode.insertBefore(userOption, closestElement.nextSibling);
}
} else if (userOption.classList.contains('gen-cell')) {
let dropPositionX = ev.clientX;
let elements = document.querySelectorAll('.gen-cell');
let closestElement = null;
elements.forEach((element) => {
if (!closestElement || Math.abs(dropPositionX - element.getBoundingClientRect().left) < Math.abs(dropPositionX - closestElement.getBoundingClientRect().left)) {
closestElement = element;
}
});
let hoveredElement = ev.target;
let closestCell = hoveredElement.closest(".gen-cell");
let closestSection = hoveredElement.closest(".gen-section");
if (closestSection.hasChildNodes()) {
if (Math.abs(dropPositionX - closestElement.getBoundingClientRect().left) < Math.abs(dropPositionX - closestElement.getBoundingClientRect().right)) {
// Insert before the closest element if the drop position is left of its midpoint
closestElement.parentNode.insertBefore(userOption, closestElement);
} else {
closestElement.parentNode.insertBefore(userOption, closestElement.nextSibling);
}
} else {
// Insert into an empty section
hoveredElement.appendChild(userOption);
}
}
Also, when I drag and drop a cell inside of a section that only contains itself, it drops itself into another section below when it should stay where it is. I am not sure where I have gone wrong in my logic, or if I am missing a piece of code which I have completely overlooked.