16
votes

I am using the jQuery UI Draggable/Sortable demo (http://jqueryui.com/demos/draggable/#sortable) for the basis of my project. I need to get a reference to the <li> that gets cloned into the sortable when the sortable receives it. I tried the sortable's receive event, but that only gives a reference to the original draggable <li>, and not its clone.

3
yes i'm using the clone helper...trying to get a reference to the newly cloned <li>Mark Richman
had this exact problemreabow

3 Answers

30
votes

In the demo you reference, there's actually a bug; after you drag an item down it inserts a cloned li with an id which is a duplicate of its brother's into the DOM, so beware (a bug was filed about this but there's no activity around it).

I did a few things to achieve this:

  1. To get around the limitation of the demo that I described above, instead apply a class to the draggable items that will be linked to the sortable:

    <ul>
        <li class="new-item ui-state-highlight">Drag me down</li>
    </ul>
    
  2. Make items with that class draggable, instead of selecting an element by id:

     $(".new-item").draggable({
         connectToSortable: "#sortable",
         helper: "clone",
         revert: "invalid"
     });
    
  3. Tap into the stop event of the sortable, and perform some simple logic about the item that was dropped, leveraging the fact that an item with the class new-item could only have been dropped (and isn't simply an existing item in the sortable):

    $("#sortable").sortable({
        revert: true,
        stop: function(event, ui) {
            if (ui.item.hasClass("new-item")) {
                // This is a new item
                ui.item.removeClass("new-item");
                ui.item.html("<b>HI</b>");
            }
        }
    });
    

Note that you could use the data-* attribute instead of adding a helper class.

Here's a working example: http://jsfiddle.net/andrewwhitaker/twFCu/

Hope that helps.

1
votes

And if you want another very rough-and-ready way to get that item just to remove it or something, just reference it in the drop as

var _clone = $(".ui-draggable-dragging");

Of course that class is removed just AFTER the drop, so that reference gets lost and you can't do anything that isn't immediate.

The answer above is more robust but if you're in a crazy rush...

1
votes

If you don't fear accessing the Sortable's internal state, you can do the following:

$('#sortable').sortable({
  receive: function() {
    // Sortable.currentItem refers to the item just added.
    // jQuery UI < 1.10 uses "sortable" as its data key,
    // jQuery UI >= 1.10 defines an "instance" method to get the current instance.
    var $item =
      (
        $('#sortable').data('sortable') || // jQuery UI < 1.10
        $('#sortable').sortable('instance') // jQuery UI >= 1.10
      ).currentItem;
  }
);

Fiddle: http://jsfiddle.net/t33bt/12/

Keep in mind though, that this might not work in a future jQuery UI version anymore because it doesn't use the official API. But nonetheless it works even in jQuery UI 1.11 (current version as of time of this writing).