Problem drag and drop replacing button

Hi need help please, I want the user can change the button that he drops to the slots, by dropping another button and the previous button will go back where it sits before. or I can drag it back where it sits.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- CSS only -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
    <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
    <style type="text/css">

        .btn-success:hover {
            background-color: #28a745 !important;
            border-color: #28a745 !important;
        }

        div.ui-droppable-disabled.divslot {
            background-color: #28a745;
        }

        div.divslot {
            border: 1px solid #3c8dbc;
        }
        .content {
            margin-top: 50px;
        }
        /* .......... */
        .ml-1 .btn {
            display: block;
        }
        .mr-1,
        .ml-1 {
            margin: 1rem 0;
            white-space: nowrap;
            display: flex;
            min-height: 29px;
        }
        .mr-1.divslot {
            flex: 1 0 0%;
            border: 1px dashed #666;
        }
        .mr-1.divslot.isDropped {
            max-width: min-content;
        }
        .ui-draggable-disabled {
            outline: 1px dotted #666;
            outline-offset: -2px;
        }
        .ml-1 .btn:active {
            background: transparent !important;
            border: 1px dashed #666;
            transition: background 3s ease;
        }

    </style>
</head>
<body>



<div class="content">
    <div class="container-fluid">

        <div class="row">
            <div class="col-lg-12">
                <div class="card card-primary card-outline">
                    <div class="card-body">
                        <div id="quest">

                        </div>
                    </div>
                </div>
            </div>


        </div>

    </div>
</div>

</body>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>

<script src="https://code.jquery.com/jquery-1.12.4.js"></script>

<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<!-- JavaScript Bundle with Popper -->

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script>

<script type="text/javascript">
    $(function () {
        var correctCards = 0;

        var stringtext = [
            [
                "Is",
                "there",
                "any",
                "chance",
                "you'd",
                "be",
                "interested in a",
                "movie",
                "tonight",
                "?"
            ]
        ];
        var label = [
            [
                "Is",
                "tonight",
                "there",
                "interested in a",
                "be",
                "you'd",
                "movie",
                "chance",
                "any",
                "?"
            ]
        ];

        $(init());

        function init() {
            correctCards = 0;
            $("#cardPile").html("");
            $("#cardSlots").html("");

            for (var x = 0; x < stringtext.length; x++) {
                var numdiv = x;
                var divs = "#cardPile_" + numdiv + " div";

                $("#quest").prepend(
                    $('<div class="row mb-auto pb-1" id="row_' + numdiv + '"></div>')
                );

                $("#row_" + numdiv).prepend(
                    $(
                        '<div class="col-lg-6 d-flex flex-row" id="cardSlots_' +
                        numdiv +
                        '"></div>'
                    )
                );
                for (var i = 0; i < 10; i++) {
                    $('<div class="ml-1 mr-1 divslot"></div>')
                        .data("number", stringtext[x][i])
                        .appendTo("#cardSlots_" + numdiv)
                        .droppable({
                            accept: divs,
                            hoverClass: "hovered",
                            drop: handleCardDrop
                        });
                }

                $("#row_" + numdiv).prepend(
                    $(
                        '<div class="col-lg-6 d-flex flex-row" id="cardPile_' +
                        numdiv +
                        '"></div>'
                    )
                );
                for (var i = 0; i < 10; i++) {
                    $(
                        '<div class="ml-1"><button type="button" class="btn  btn-primary btn-sm">' +
                        label[x][i] +
                        "</button></div>"
                    )
                        .data("number", label[x][i])
                        .attr("id", "card " + label[x][i])
                        .appendTo("#cardPile_" + numdiv)
                        .draggable({
                            stack: divs,
                            cursor: "move",
                            revert: false,
                            cancel: false,
                            opacity: 0.9,
                            helper: "clone"
                        });
                }
            }
        }

        function handleCardDrop(event, ui) {
            var slotNumber = $(this).data("number");
            var cardNumber = ui.draggable.data("number");

            ui.draggable.find("button").addClass("btn-success");

            ui.draggable.find("button").attr("title", cardNumber);
            $(this).addClass("isDropped");
            ui.draggable.draggable("disable");
            $(this).droppable("disable");
            ui.draggable.css("width", `${ui.draggable.find("button").css("width")}`);
            ui.draggable.find("button").appendTo($(this));
        }
    });


</script>


</html>

Thank you in advance.

Your droppable element has a ā€œDropā€ event that you use to detect when a draggable is dropped onto it. With this event you can detect when a button is dropped on it, if there is currently an element already attached to the droppable (using the find()) and then detach and move that previous button back to wherever you like (append back onto previous parent container). The newly dropped item can then be attached to the droppable as a child.

So it is just a matter of using the event to read the droppableā€™s children, detach and move the previous child and append the newly dropped button.

It is just a matter of working through the steps. But start with the Drop element of the droppable.

Thanks, I hope I can make it :face_with_head_bandage:

I think I got it now, just need to adjust my code because Iā€™m using ID with space

@Martyr2 How can I make the button draggable after being dropped and move back it to where it sits before ?

Thank you in advance.

Hi @PaulOB ,

I was able to drag the button after being dropped by using this

ui.draggable.find("button").draggable({cancel:false});

my problem is that when I release the button it will not move back where it sits before. (left side)

Thank you in advance.

Iā€™m guessing that youā€™d need to set up a new draggable event on the dropped item and set the original space to be the droppable target. Iā€™m not sure my JS skills are up to that but Iā€™ll try and have a look later this afternoon.

Hi,

It might be better to start from a working example and then re-engineer backwards.

I found a similar script on ā€˜tinternetā€™ that is simpler than yours and adapted it to what you were asking for.

Of course you will need to re-engineer it to construct the data and ids in the JS but you will be starting from a position where you have a working example already.

The styling can of course also be changed to match what you want.

1 Like

Thank you so much Paul, this is it , I will try this :slight_smile:

No worries hope its useful :slight_smile:

I forked the codepen to match your original colours a bit better.

1 Like

Wow thank you so much PaulOB , I like this update because it has transition , dotted lines and button color million thanks :slight_smile: . I will update my previous to this :slight_smile:

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.