Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery draggable items lose their draggability after being swapped (with jsfiddle example)

I have two li elements which are jQuery draggable. When I drag and drop box 'one' over box 'two', they get swapped. So far so good. (The delay fixes another problem described here.) However the elements now are not draggable anymore, even after resetting their draggable option.

Any ideas how to fix this? full working jsfiddle here

<html>
<head>

    <script type="text/javascript" src="includes/jquery-1.4.2.min.js"></script>

    <script type="text/javascript" src="includes/jquery-ui-1.8.2.custom.min.js"></script>

    <script type="text/javascript">

        jQuery.fn.swapWith = function(to) {
            return this.each(function() {
                var copy_to = $(to).clone(true);
                var copy_from = $(this).clone(true);
                $(to).replaceWith(copy_from);
                $(this).replaceWith(copy_to);
            });
        };



        $(document).ready(function() {

            options = { revert: true};

            $("li").draggable(options);

            $('#wrapper').droppable({
                drop: function(event, ui) {
                window.setTimeout("Swap()", 600);
                }
            });
        });

        function Swap() {
            $('#one').swapWith($('#two'));

            //trying to fix problem where elements can't be dragged anymore
            $("li").draggable("destroy"); 
            $("li").draggable(options);
        }
    </script>

</head>
<body>
    <form>
    <ul id="wrapper">
        <li id='one'>
            <div style="width: 100px; height: 100px; border: 1px solid green">
                one<br /></div>
        </li>
        <li id='two'>
            <div style="width: 110px; height: 110px; border: 1px solid red">
                two<br /></div>
        </li>
    </ul>
    <br />
    </form>
</body>
</html>
like image 302
Tony_Henrich Avatar asked Jan 04 '11 00:01

Tony_Henrich


People also ask

Why is draggable not working?

You have one of these problems: Your jQuery or jQuery UI Javascript path files are wrong. Your jQuery UI does not include draggable. Your jQuery or jQuery UI Javascript files are corrupted.

What is the syntax of the draggable function?

The draggable (option) method specifies that an HTML element can be moved in the HTML page. Here, the option parameter specifies the behavior of the elements involved. Syntax: $(selector, context).

How do you drag and drop in jQuery?

Using jQuery UI, we can make the DOM(Document Object Model) elements to drag anywhere within the view port. This can be done by clicking on the draggable object by mouse and dragging it anywhere within the view port. If the value of this option is set to false, it will prevent the DOM elements to be dragged .

How do I disable draggable?

We can disable drag and drop on HTML elements by setting the draggable attribute to false . We set draggable to false so we can't drag it. We add event listeners for the dragstart and drop events with addEventListener .


1 Answers

So after playing with your code, here's the conclusion I've come to.

It looks like the draggable jqueryui method is tracking its objects seperately. When you clone, that tracking isn't cloned. I modified your code as follows:

jQuery.fn.swapWith = function(to) {
        return this.each(function() {
            var copy_to = $(to).clone(true).appendTo($("#wrapper"));
            var copy_from = $(this).clone(true).appendTo($("#wrapper"));
    //$(to).replaceWith(copy_from);
    //$(this).replaceWith(copy_to);
        });
    };

You can see the fascinating results http://jsfiddle.net/XkUDv/16/

As you can see, if you drag the new cloned objects, it moves the original, not the cloned one.

It's not an answer, but I hope it helps.

UPDATE:

after taking a closer look at clone I changed the javascript to:

<script type="text/javascript">

    jQuery.fn.swapWith = function(to) {
        return this.each(function() {
            var copy_to = $(to).clone();
            var copy_from = $(this).clone();
            $(to).replaceWith(copy_from);
            $(this).replaceWith(copy_to);
        });
    };



    $(document).ready(function() {

        options = { revert: true };

        $("li").draggable(options);
        $('#wrapper').droppable({
            drop: function(event, ui) {
            window.setTimeout(function(){
                $('#one').swapWith($('#two'));
                $("li").draggable(options);
            }, 600);
            }
        });
    });
</script>

Now it works the way you wanted :)

I'm guessing the issue is that since clone(true) copies the event handlers, when you try to reattach the draggable to the new clones it sees the old event handlers and ignores the elements. So instead of clone(true), I changed it to clone();

hope that helps!

Working version: http://jsfiddle.net/XkUDv/21/

like image 52
ehudokai Avatar answered Sep 30 '22 03:09

ehudokai