Sagar
Sagar

Reputation: 484

How to make dynamically added list elements draggable in jquery?

Here is my code from http://jsfiddle.net/XUFUQ/1/

$(document).ready(function()
    {
        addElements();
    }
);

function addElements()
{
    $("#list1").empty().append(
        "<li id='item1' class='list1Items'>Item 1</li>"+
        "<li id='item2' class='list1Items'>Item 2</li>"+
        "<li id='item3' class='list1Items'>Item 3</li>"
    );
}

$(function() {
    // there's the gallery and the trash
    var $gallery = $( "#list1" ),
    $trash = $( "#list2" );

    // let the gallery items be draggable
    $( "li", $gallery ).draggable({
        cancel: "button", // these elements won't initiate dragging
        revert: "invalid", // when not dropped, the item will revert back to its initial position
        containment: "document",
        helper: "clone",
        cursor: "move"
    });

    // let the trash be droppable, accepting the gallery items
    $trash.droppable({
        accept: "#list1 > li",
        drop: function( event, ui ) {
            $("#list2").append(ui.draggable);
            addElements();
    }
    });


});

On document ready method I am appending some elements to list1, and then I am initializing draggable on that list so for first time I am able to drag list1 elements. On dropping in list2 I am calling addElements() function to clear and add some elements to list1. But I am unable to drag these added elements.

How can I make these elements draggable?

Upvotes: 4

Views: 17016

Answers (5)

alien45
alien45

Reputation: 306

Here is a little trick I did for any future seeker :) This code needs to be run only once and it's pretty much self-explanatory.

//The "on" event is assigned to the "document" element which is always available within the context
//Capture all the "mouseenter" event to any child element of "document" with a specific class (you can you any valid jQuery selector you like)
//any live and dynamic element with the class will become draggable (haven't tested on touchscreen devices)
$(document).on("mouseenter", '.someClass', function(e){
 var item = $(this); 
 //check if the item is already draggable
 if (!item.is('.ui-draggable')) {
         //make the item draggable
         item.draggable({
            .............
         });
  }
});

Cheers!

Upvotes: 16

Dhaval Bharadva
Dhaval Bharadva

Reputation: 3083

Try this:

$(document).ready(function () {
    addElements();

    var $gallery = $("#list1"),
        $trash = $("#list2");

$("li", $gallery).draggable({
    cancel: "button", 
    revert: "invalid", 
    containment: "document",
    helper: "clone",
    cursor: "move"
});

$trash.droppable({
    accept: "#list1 > li",
    drop: function (event, ui) {
        $("#list2").append(ui.draggable);
        addElements();
    }
});
});

function addElements() {
$("#list1").empty().append(
    "<li id='item1' class='list1Items'>Item 1</li>" +
    "<li id='item2' class='list1Items'>Item 2</li>" +
    "<li id='item3' class='list1Items'>Item 3</li>");

$("#list1 > li").draggable({
    cancel: "button", // these elements won't initiate dragging
    revert: "invalid", // when not dropped, the item will revert back to its initial position
    containment: "document",
    helper: "clone",
    cursor: "move"
});

$("#list2").droppable({
    accept: "#list1 > li",
    drop: function (event, ui) {
        $("#list2").append(ui.draggable);
        addElements();
    }
});
}  

JSFIDDLE DEMO

Upvotes: 0

iCollect.it Ltd
iCollect.it Ltd

Reputation: 93611

Here is an ugly version of what you need to do based on the update http://jsfiddle.net/XUFUQ/6/. Best to factor out the resuable code:

// let the trash be droppable, accepting the gallery items
$trash.droppable({
    accept: "#list1 > li",
    drop: function( event, ui ) {
        $("#list2").append(ui.draggable);
        addElements();
        $( "li", $gallery ).draggable({
            cancel: "button", // these elements won't initiate dragging
            revert: "invalid", // when not dropped, the item will revert back to its initial position
            containment: "document",
            helper: "clone",
            cursor: "move"
           })
        }
});

Basically calling draggable only connects to the elements that exist at the time it is run. This adds the various mouse handling events to each element. If you add elements it knows nothing about them, so you need to call draggable again on those.

The other two answers both give examples of where you can add the draggable to ensure the elements are included, but that is a coding excercise.

Upvotes: 4

Mandeep Jain
Mandeep Jain

Reputation: 2674

make the newly addded elements draggable again.

function addElements()
{
    $("#list1").empty().append(
        "<li id='item1' class='list1Items'>Item 1</li>"+
        "<li id='item2' class='list1Items'>Item 2</li>"+
        "<li id='item3' class='list1Items'>Item 3</li>"
    );
    $("#list1 li").draggable({
        cancel: "button", // these elements won't initiate dragging
        revert: "invalid", // when not dropped, the item will revert back to its initial position
        containment: "document",
        helper: "clone",
        cursor: "move"
    });
}

here is the fiddle

Upvotes: 1

Okazari
Okazari

Reputation: 4597

    function addElements()
    {
        $("#list1").empty().append(
            "<li id='item1' class='list1Items'>Item 1</li>"+
            "<li id='item2' class='list1Items'>Item 2</li>"+
            "<li id='item3' class='list1Items'>Item 3</li>"
        );
        // there's the gallery and the trash
        var $gallery = $( "#list1" );


   $( "li", $gallery ).draggable({
            cancel: "button", // these elements won't initiate dragging
            revert: "invalid", // when not dropped, the item will revert back to its initial position
            containment: "document",
            helper: "clone",
            cursor: "move"
        });

}

You just had to push your ".draggable()" method in your "addElement()" one. Thx to that, you'll attach the draggrable function on each list you append in your gallery.

Check this fiddle for the correction. http://jsfiddle.net/XUFUQ/7/

Upvotes: 0

Related Questions