Drag words problem

Hi, can ask for some help, please my problem is that when I drag a long text it will overlap to other div, what I want is whatever the size of the button it will fit to the slot and also it will show the dashed line. just like this example, I want to achieve

and here is my overlap

Here is my code

<!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;
        }
    </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" style="width:10%;border:dashed 1px;"></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: true,
                        cancel:false
                    } );
                }



            }



        }

        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);
            ui.draggable.draggable( 'disable' );
            $(this).droppable( 'disable' );
            ui.draggable.position( { of: $(this), my: 'left top', at: 'left top' } );
            ui.draggable.draggable( 'option', 'revert', false );

        }


    });

</script>


</html>

Thank you in advance

Back of my head’s saying this is a CSS fix, not a Javascript one…
Is this code online somewhere we can play with?

EDIT: Back of my head’s probably wrong. Why are we assigning the position of the element, rather than just inserting the element into the DOM at the defined point, and letting the browser handle the rendering?

Effectively:
On Drop, figure out what outline element i’m hovering over. Remove that outline element, and append the dropped element in its place.

1 Like

can someone please move my post to CSS channel, thanks

Unfortunately CSS can’t help here as @m_hutley said above the element is dropped into a specific position and doesn’t take part in the flow of the document. The dropped element needs to replace the existing element and then css can size it to fit properly instead of the default 10% width placeholder.

Note that the method you are using is not viable anyway because if you resize the screen once an element has been dropped it just stays where it was and escapes out of its dotted box altogether.

Until the html is in the correct order then its still a js issue I’m afraid.

1 Like

Hi @PaulOB , should I moved this to javascript ?

Hi Paul, what should I change ? I have no idea how to solved the problem.

Thank you in advance

I’ve moved it back to the JS forum.

I think you need to use droppable but hopefully one of the JS Gurus can chip in and help. It’s a bit too much for me to attempt as my JS is basic and would take me all week :wink:

I Hope JS Gurus can help me, I’m pulling out my hair here. :pleading_face:

i’m… trying to squint at this and determine the values of the variables, but my instinct is to say:
(Stabbing in the dark)

            ui.draggable.draggable( 'disable' );
            $(this).droppable( 'disable' );
           /* ui.draggable.position( { of: $(this), my: 'left top', at: 'left top' } ); This line can be removed. */
           if($(this).next() !== undefined) {
             var marker = $(this).next();
             $(this).insertBefore(ui);
             ui.insertBefore(marker);
          } else { //The thing we're trying to replace is the last in the list. So we have to look at the parent and append to the end.
             var marker = $(this).parent();
             $(this).insertBefore(ui);
             ui.appendTo(marker);
         }

Thank you for the reply, I tried your solution but when I drop the word in the slot the dashed line did not remove and it stays where it was being dropped. the result the words are not aligned properly. also, how can I make a dashed line on the left side when I moved the word /button the dashed line remains, the same as the example I want to achieve above in my first post.

Thank you in advance

Bearing in mind I don’t understand what I’m doing does this help :slight_smile:

1 Like

Wow awesome @PaulOB, Thank you so much. I will try this now, I’ll be back if I get in to trouble.

1 Like

Thank you I tried your solution and it works.

Is it possible to have a dotted outline button when we drag or move the button to the right?

just like this?

Thank you in advance.

I believe that the ui.draggable has a clone option to preserve the space until its dropped. However I can’t see an easy way to always preserve the space once the button is dropped.

The best I could come up with is to leave a default 10% spacer once the button is dropped.

It probably needs some JS to make another clone of the button that is left in space but invisible apart from its border.

Hi, Paul thank you so much. I will still use your solution. hopefully one of the JS Gurus can help.

Thank you again Paul :slight_smile:

well i’d think you’re already there mostly Paul…
instead of removing the cloned element on drop, change its CSS properties to make the text and background transparent, and you should achieve the desired effect? (the text still being there will enforced the width, but transparent makes it ‘invisible’)

Thanks, i was expecting you to say it was all wrong :slight_smile:

I couldn’t quite work that out but I did manage to find the width of the button and then apply that to the parent instead.

This is a lot closer now.

Not sure what this bit is doing as it adds an invalid id to each div.

.attr("id", "card " + label[x][i])

e.g. that would result in id="card interested in a" which is invalid. I’m guessing it should be something else but seems to do no harm apart from being invalid.

Thanks Paul :slight_smile:

1 Like