JS Drag and Drop that also changes object properties

Issue

Im building an EXPRESS app in which I have entries that have the status propery. This status propery determines if the object display appears in one of three columns (ex: if the entry has status of 1, it’ll appear in the first column; if it has a status of 2 it’ll appear in the second column; and so on…). I wanted to add some drag and drop functionality, which actually work. I can now drag an entry from the first column to the second one and this will remain there. However, since there is no status update, once the page is refreshed the entry will go back to its original column. I have to find a way to change the status of each entry once the dragend event has occured, however, I can’t find a solution to update my mongoDB database from the browser side javascript file that I use for the drag and drop functionality. Here is the code:

Drag and Drop JS:

const draggables = document.querySelectorAll(".draggable");
const containers = document.querySelectorAll(".container__entries");

function getDrapAfterElement(container, y) {
    const draggableElements = [...container.querySelectorAll(".draggable:not(.dragging)")];
    return draggableElements.reduce((closest, child) => {
        const box = child.getBoundingClientRect();
        const offset = y - box.top - box.height / 2;
        if(offset < 0 && offset > closest.offset) {
            return { offset: offset, element: child };
        } else {
            return closest;
        };
    }, { offset: Number.NEGATIVE_INFINITY }).element;
};

draggables.forEach(draggable => {
    draggable.addEventListener("dragstart", () => {
        draggable.classList.add("dragging");
    });

    draggable.addEventListener("dragend", () => {
        draggable.classList.remove("dragging");
    });
});

containers.forEach(container => {
    container.addEventListener("dragover", e => {
        e.preventDefault();
        const afterElement = getDrapAfterElement(container, e.clientY);
        const draggable = document.querySelector(".dragging");
        if (afterElement == null) {
            container.appendChild(draggable);
        } else {
            container.insertBefore(draggable, afterElement);
        };
    });
});

Here is the HTML, which is the same for all the columns:

<div class="container__entries">
   <% for(let entry of entries) { %> 
      <%- partial('partials/edit', { entry }) %>
      <% if(entry.status == 1) { %>
         <div class="draggable" draggable="true">
            <!-- Entry Small -->
            <%- partial('partials/entrySmall', { entry }) %>
            <!-- Entry Big -->
            <%- partial('partials/entryBig', { entry }) %>
         </div>
      <% } %>
   <% } %>
</div>

Thank you.

Solution

Use fetch with method POST to send data containing information about status to your express server. Like this.

var formData = new FormData();
formData.append('data', data);

fetch("your_url", { method: 'POST', body: formData }).then((res) => res.text().then(res2 => {
   // response
}))
.catch(error => console.log(error)

Answered By – Lukas

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published