Draggable / Sortable Elements

Just waking this one up again… are we any closer :hugs:

If I say pretty please does it help.

8 Likes

Still hoping…

1 Like

73 votes and 2 years since requested. Still hoping…

6 Likes

Until this is implemented, this seems quite easy to use https://github.com/bevacqua/dragula

1 Like

Not that easy to integrate with Wappler. Would be far better if it was added! The demand for dynamic-tables and draggable interface elements is growing so lets hope the Wappler team are still listening :neutral_face:

4 Likes

See:

The last part

1 Like

One more bump!

I do not understand why this topic is still active. The feature has been part of Wappler for over a year.

4 Likes

Thanks Ben… That is great… thanks for you video tutorial… this will do… i guess i was looking for a “build in solution within wappler” but your tutorial is awesome thanks for doing it…

1 Like

Has anyone built a kanban style board using Wappler sortable elements?
Each column list contains group by (e.g. Stage) and then dragged into the next column to update the stage.

e.g. https://codepen.io/ettrics/pen/QbPEeg/

2 Likes

As someone else has asked, is it possible to do something like Kanban or Trello by doing it the way you show?

I want to be able to have 2+ lists and be able to sort between them.

3 Likes

Any notice??

I agree - the guys are hard at work improving all server related stuff but nothing seems to be moving on the front end on bells and whistles that most of the non-tech users actually need. The sortable/drag and drop / kanban featuer would be a massive hit, not sure why they don’t get onto these sort of features.

1 Like

Hello, i was reviewing some threads about Kanban boards. I landed on this topic, so I jotted down my drafts. I don’t know if this is exactly the way, but it’s an outline. To update the MySQL database after reordering a card within a Kanban board and passing the ID back to the database, follow few steps:
In the Kanban board, each card must have a unique id related to the corresponding record in the MySQL database.
When reordering the card on the Kanban board, capture the ID of the moved card. On the server side, use PHP, Node.js, to receive the reordered card ID and implement the logic that updates the record in the database based on the received ID. Then use a MySQL database connection on the server side to run an update SQL query on the corresponding table, passing the reordered card ID. This query should reflect the changes needed to be made to the database record. For example, if a customer purchased an item, you could update the corresponding field in the table to reflect that information.
Finally run the update SQL query against the database using the established connection. If everything goes well and the thinking logic is correct, after reordering the card on the Kanban board, the corresponding ID is forwarded to the server and used to update the record in the MySQL database with the updated information.
I haven’t put it into practice yet, but I intend to test it.

Taking this a step further, Wappler already has an sorting system included in FormRepeat. All that is required is to include the group option (@patrick) and we are set to go.

1 Like

As an example in principle - visually, this will work:

  1. Create the databse, table and contents:
  2. Create the read API:
  3. Add Server Connect and 3 Data Views:
  4. Copy and paste the following code into a static page:
<!doctype html>
<html lang="en">

<head>
    <base href="/">
    <meta charset="UTF-8">
    <title>Kanban Board</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="Kanban Board">

    <link rel="stylesheet" href="/bootstrap/5/css/bootstrap.min.css" />
    <link rel="stylesheet" href="/css/style.css" />

    <script src="/dmxAppConnect/dmxAppConnect.js"></script>
    <script src="/dmxAppConnect/dmxRouting/dmxRouting.js" defer></script>
    <script src="/dmxAppConnect/dmxFormRepeat/dmxFormRepeat.js" defer></script>
    <script src="https://cdn.jsdelivr.net/npm/sortablejs@1/Sortable.min.js"></script>
    <script src="/dmxAppConnect/dmxDataTraversal/dmxDataTraversal.js" defer></script>
</head>

<body is="dmx-app" id="mykanban">
    <dmx-serverconnect id="scKanban" url="/api/kanban/read"></dmx-serverconnect>
    <dmx-data-view id="dvToDo" dmx-bind:data="scKanban.data.query" filter="(group == 'todo')"></dmx-data-view>
    <dmx-data-view id="dvInProgress" dmx-bind:data="scKanban.data.query" filter="(group == 'inprogress')"></dmx-data-view>
    <dmx-data-view id="dvDone" dmx-bind:data="scKanban.data.query" filter="(group == 'done')"></dmx-data-view>
    <meta name="ac:route" content="/kanban">
    <div class="container">
        <div class="row">
            <div class="col">
                <h1 class="text-center"><span class="badge bg-primary rounded-pill">Kanban Board</span></h1>
            </div>
        </div>
        <div class="row">
            <div class="col">
                <form id="frmToDo" method="post" is="dmx-serverconnect-form" action="/api/kanban/update_todo" dmx-on:success="scKanban.load({})">
                    <input id="todo_group" name="group" type="hidden" value="todo">
                    <div class="card h-100 bg-secondary text-light">
                        <div class="card-header">To Do</div>
                        <div id="ToDo" class="card-body" is="dmx-form-repeat" dmx-bind:items="dvToDo.data" sortable="true" handle=".handle" animation="500">
                            <div class="list-group-item handle p-0">
                                <input id="todo_task" name="task" type="text" class="form-control" dmx-bind:value="task">
                                <input id="todo_rank" name="rank" type="hidden" class="form-control" dmx-bind:value="$index">
                            </div>
                        </div>
                    </div>
                </form>
            </div>
            <div class="col">
                <form id="frmInProgress" is="dmx-serverconnect-form" method="post" action="/api/kanban/update_inprogress" dmx-on:success="scKanban.load({})">
                    <input id="inprogress_group" name="group" type="hidden" value="inprogress">
                    <div class="card h-100 bg-warning">
                        <div class="card-header">In Progress</div>
                        <div id="InProgress" class="card-body" is="dmx-form-repeat" dmx-bind:items="dvInProgress.data" sortable="true" handle=".handle" animation="500">
                            <div class="list-group-item handle p-0">
                                <input id="inprogress_task" name="task" type="text" class="form-control" dmx-bind:value="task">
                                <input id="inprogress_rank" name="rank" type="hidden" class="form-control" dmx-bind:value="$index">
                            </div>
                        </div>
                    </div>
                </form>
            </div>
            <div class="col">
                <form id="frmDone" is="dmx-serverconnect-form" method="post" action="/api/kanban/update_done" dmx-on:success="scKanban.load({})">
                    <input id="done_group" name="group" type="hidden" value="done">
                    <div class="card h-100 bg-success text-light">
                        <div class="card-header">Done</div>
                        <div id="Done" class="card-body" is="dmx-form-repeat" dmx-bind:items="dvDone.data" sortable="true" handle=".handle" animation="500">
                            <div class="list-group-item handle p-0">
                                <input id="done_task" name="task" type="text" class="form-control" dmx-bind:value="task">
                                <input id="done_rank" name="rank" type="hidden" class="form-control" dmx-bind:value="$index">
                            </div>
                        </div>
                    </div>
                </form>
            </div>
        </div>
        <div class="row mt-3">
            <div class="col">
                <button id="btnSave" class="btn btn-primary" dmx-on:click="frmToDo.submit();frmInProgress.submit();form1.submit()">Save</button>
            </div>
        </div>
    </div>
    <script>
        new Sortable(ToDo, {
            group: 'shared' // set lists to same group
        });
        new Sortable(InProgress, {
            group: 'shared'
        });
        new Sortable(Done, {
            group: 'shared'
        });
    </script>
</body>

</html>

The problem is that the index does not get changed as it would if I removed the script at the bottom of the page. This makes the example, as is, unsuitable for backend processing (@patrick) .

2 Likes

See it working:
https://app.screencast.com/PmtXGjdkcWg37?conversation=kKVoF835ZfCHZSTbZJN7Fr

1 Like

Nice :ok_hand:

1 Like

There’s a lot more involved than just moving the elements from one shared list to another on the page.
On drag end you need the initial list new items ids/indexes and the destination list new items ids/indexes, so you can then send them to an update record server action and update the items with their new positions and the list they are in.

1 Like

As I said

2 Likes