3
votes

I am using a jQuery UI draggable list connected to a sortable list, which mostly works well except that when an item is dropped onto the sortable list it does not seem to correctly clone the original element id, or any associated jquery data().

Weirdly these things ARE available from inside the receiver function, but it doesn't seem to actually save them to the elements so things like the sortable list's update function never see the new dropped element correctly as the new li element doesn't really have an id.

What am I doing wrong?!

Javascript:

$(document).ready(function () {
    $("#dest").sortable( {
      update : function () { 
          onUpdate();
        },
      receive: function(event, ui) {
          alert("dropped item ID: "+ui.item.attr('id'));
        }
    });

    jQuery('#src > li').draggable({helper:'clone',connectToSortable:'#dest'});
});

function onUpdate() {
    var order = $('#dest').sortable('toArray');
    var txt = "Order: "+order;

    $("#info").text(txt);


}

HTML:

Source List (dragable):
<div>
    <ul id="src">
        <li id="src_0">src 0</li>
        <li id="src_1">src 1</li>
        <li id="src_2">src 2</li>
    </ul>
</div>

Target List (sortable):  
<div>
    <ul id="dest">
        <li id="dest_0">dest 0</li>
        <li id="dest_1">dest 1</li>
        <li id="dest_2">dest 2</li>
    </ul>
</div>

<span id="info">
    Waiting update...
</span>

Demo at http://jsfiddle.net/h3WJH/1/

2

2 Answers

4
votes

I believe jQuery does this on purpose because an ID is meant to identify a single element on a page. Try using $.data() to store information.

Check this out: http://jsfiddle.net/wngchng87/h3WJH/11/

1
votes

I had the same problem and didn't find a nice way to do that, but got a workaround.

The original element can be acessed on "receive" event, but not on update. I did the following:

    var droppedId;
    myList.sortable({ 
        receive: function(e, ui) {
            droppedId = ui.item.data('id');

        },
        update: function(e, ui) {
            ui.item.data('id', droppedId);
        },
    })

The item id cannot be accessed through ui.item, but it's available at ui.sender.attr('id'), so if you use element's id instead of data you could do:

    var droppedId;
    myList.sortable({ 
        receive: function(e, ui) {
            droppedId = ui.sender.attr('id');

        },
        update: function(e, ui) {
            ui.item.attr('id', droppedId);
        },
    })

Although it doesn't seem a good idea to have repeated IDs.