skip to Main Content

I have a bunch of users that are represented by the gray boxes. I would like to move these users from one column to another (light blue). Each column represents a different status of the user.

enter image description here

The draggable (https://github.com/Shopify/draggable) function is already working, and I can get the source location and item id that was dragged.
But I can not figure out how to get the information of the destination column.

Here is my code so far:

var containers = document.querySelectorAll(".draggable-zone");

    if (containers.length === 0) {
        return false;
    }

    var swappable = new Sortable.default(containers, {
        draggable: ".draggable",
        handle: ".draggable .draggable-handle",
        mirror: {
            //appendTo: selector,
            constrainDimensions: true
        }
    });

    swappable.on('drag:start', (event) => {
        // works
    });

    swappable.on('drag:stop', (event) => {
        console.log(event);
        console.log(event.source.id); // return user id
        console.log(event.sourceContainer.id); // return source column id (status)
    });
<script src="https://cdn.jsdelivr.net/npm/@shopify/[email protected]/lib/draggable.bundle.js"></script>
<div class="content d-flex flex-column flex-column-fluid" id="">
    <div class="container-fluid" id="">
        <div class="col-xs-12 no-padding s-row" style="display: flex;overflow-x: auto;">
            <div id="col_1" class="draggable-zone col-xs-12 col-md-3 p-2 m-2" style="background-color: lightblue">
                <h3>Col 1</h3>
                <!-- start::draggable user item -->
                <div id="user_1" class="draggable text-white rounded p-3 m-1 mb-3 h-100px" style="background-color: lightslategray">
                    User 1
                    <div class="draggable-handle">X</div>
                </div>
                <!-- end::draggable user item -->
                <!-- start::draggable user item -->
                <div id="user_2" class="draggable text-white rounded p-3 m-1 mb-3 h-100px" style="background-color: lightslategray">
                    User 2
                    <div class="draggable-handle">X</div>
                </div>
                <!-- end::draggable user item -->
                <!-- start::draggable user item -->
                <div id="user_3" class="draggable text-white rounded p-3 m-1 mb-3 h-100px" style="background-color: lightslategray">
                    User 3
                    <div class="draggable-handle">X</div>
                </div>
                <!-- end::draggable user item -->
                <!-- start::draggable user item -->
                <div id="user_4" class="draggable text-white rounded p-3 m-1 mb-3 h-100px" style="background-color: lightslategray">
                    User 4
                    <div class="draggable-handle">X</div>
                </div>
                <!-- end::draggable user item -->
            </div>
            <!-- end::col -->
            <!-- start::col -->
            <div id="col_2" class="draggable-zone col-xs-12 col-md-3  p-2 m-2" style="background-color: lightblue">
                <h3>Col 2</h3>
                <!-- start::draggable user item -->
                <div id="user_5" class="draggable text-white rounded p-3 m-1 mb-3 h-100px" style="background-color: lightslategray">
                    User 5
                    <div class="draggable-handle">X</div>
                </div>
                <!-- end::draggable user item -->
                <!-- start::draggable user item -->
                <div id="user_6" class="draggable text-white rounded p-3 m-1 mb-3 h-100px" style="background-color: lightslategray">
                    User 6
                    <div class="draggable-handle">X</div>
                </div>
                <!-- end::draggable user item -->
                <!-- start::draggable user item -->
                <div id="user_7" class="draggable text-white rounded p-3 m-1 mb-3 h-100px" style="background-color: lightslategray">
                    User 7
                    <div class="draggable-handle">X</div>
                </div>
                <!-- end::draggable user item -->
            </div>
            <!-- end::col -->
            <!-- start::col -->
            <div id="col_3" class="draggable-zone col-xs-12 col-md-3  p-2 m-2" style="background-color: lightblue">
                <h3>Col 3</h3>
            </div>
            <!-- end::col -->
            <!-- start::col -->
            <div id="col_4" class="draggable-zone col-xs-12 col-md-3  p-2 m-2" style="background-color: lightblue">
                <h3>Col 4</h3>
            </div>
            <!-- end::col -->
            <!-- start::col -->
            <div id="col_5" class="draggable-zone col-xs-12 col-md-3  p-2 m-2" style="background-color: lightblue">
                <h3>Col 5</h3>
                <!-- start::draggable user item -->
                <div id="user_8" class="draggable text-white rounded p-3 mb-3 m-1 h-100px" style="background-color: lightslategray">
                    User 8
                    <div class="draggable-handle">X</div>
                </div>
                <!-- end::draggable user item -->
                <!-- start::draggable user item -->
                <div id="user_9" class="draggable text-white rounded p-3 mb-3 m-1 h-100px" style="background-color: lightslategray">
                    User 9
                    <div class="draggable-handle">X</div>
                </div>
                <!-- end::draggable user item -->
            </div>
            <!-- end::col -->
            <!-- start::col -->
            <div id="col_6" class="draggable-zone col-xs-12 col-md-3  p-2 m-2" style="background-color: lightblue">
                <h3>Col 6</h3>
            </div>
            <!-- end::col -->
        </div>
    </div>
</div>

In addition I would like also to save the order of the user in each column.

May be some can help me out.

Any help is appreciated.

Best regards

Tim

2

Answers


  1. Solution

    based on [email protected]

    Binding Javascript Data to DOM

    to bind internal data to a DOM element, use data attribute.

    // data-column exposes the bound data of given element
    <div class="column" data-column="1" />
    

    column data is accessible with this data attribute.

    Dynamically Save and Reconstruct Status

    Try build the DOM structure with a given data, not with static HTML code. So that the item state can be reconstructed later with modified data.

    <div id="root">
      <div class="col" data-column="0">col0</div>
      <div class="col" data-column="1">col1</div>
      <div class="col" data-column="2">col2</div>
    </div>
    
    // use data to dynamically reconstruct the items
    const items = [
      { column: 0, label: "aaa", index: "a" },
      { column: 1, label: "bbb", index: "b" },
      { column: 1, label: "ccc", index: "c" }
    ];
    
    function init() {
      const root = document.getElementById("root");
      const columns = document.querySelectorAll("#root .col");
      const divItems = items.map((item) => {
        const divItem = document.createElement("div");
        divItem.setAttribute("class", "draggable item");
        divItem.setAttribute("data-index", item.index);
        divItem.innerHTML = item.label;
    }
    init();
    

    Getting Column Data from Draggable.Sortable Event

    Draggable exposes all necessary DOM elements. Utilize the data attribute to get column data.

    const sortable = new Sortable(columns, { draggable: ".draggable" });
      sortable.on("sortable:stop", (ev) => {
        const newCol = ev.data.newContainer.getAttribute("data-column");
        const oldCol = ev.data.oldContainer.getAttribute("data-column");
        const index = ev.data.dragEvent.data.source.getAttribute("data-index");
        // mutate items data with data acquired from DOM attribute
        console.log({ index, newCol, oldCol });
        // i.g. var idx = items.findIndex(i => i.index === index); items[idx].column = newCol;
      });
    

    demo available at codepen. check browser console.

    Login or Signup to reply.
  2. swappable.on('drag:stop', (event) => {
          console.log(event);
          console.log(event.originalSource.parentNode.id); // return current col id
      });
    
    

    No code changes are required, the originalSource is returned with whatever information you want :D

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search