'how to check X and Y on draggable element to find closest element

i have followed this video to make drag and drop elements. i already made them work in the X direction, but now i also need to check for the Y direction to find the closets element. so its posable to move the element in any row unlike now as it only checks for the first row.

<html>
    <head>
        <title>Testing</title>
        <link rel="stylesheet" href="{{ asset('css/app.css') }}">
    </head>
    <body>

        <div class="h-64 grid grid-cols-3 gap-4 bg-gray-400 draggable-container">
            <div class="bg-red-500 w-full h-32 draggable" draggable="true">1</div>
            <div class="bg-red-500 w-full h-32 draggable" draggable="true">2</div>
            <div class="bg-red-500 w-full h-32 draggable" draggable="true">3</div>
            <div class="bg-red-500 w-full h-32 draggable" draggable="true">4</div>
            <div class="bg-red-500 w-full h-32 draggable" draggable="true">5</div>
        </div>

        <script src="{{ asset('js/products.js') }}"></script>
    </body>
</html>
const _doc = document;

const draggables = _doc.querySelectorAll('.draggable'),
    constainers = _doc.querySelectorAll('.draggable-container');

draggables.forEach(draggable => {
    draggable.addEventListener('dragstart', () => {
        draggable.classList.add('dragging');
        draggable.style.opacity = 0.5;
    });

    draggable.addEventListener('dragend', () => {
        draggable.classList.remove('dragging');
        draggable.style.opacity = 1;
    })
})

constainers.forEach(container => {
    container.addEventListener('dragover', (event) => {
        event.preventDefault()

        const draggable = _doc.querySelector('.dragging');
        const afterElement = getDragAfterElement(container, event.clientX, event.clientY);
        if (afterElement == null) {
            container.appendChild(draggable);
        } else {
            container.insertBefore(draggable, afterElement);
        }
    })
})


function getDragAfterElement(container, x, y) {
    const draggableElements = [...container.querySelectorAll('.draggable:not(.dragging)')]

    return draggableElements.reduce((closest, child) => {
      const box = child.getBoundingClientRect();
      const offsetX = x - box.left - box.width / 2,
            offsetY = y - box.top - box.height / 2;
      if (offsetX < 0 && offsetX > closest.offsetX) {
          return { offset: offsetX, element: child};
      } else {
          return closest;
      }

    }, { offsetX: Number.NEGATIVE_INFINITY }).element;
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source