Mark Richman
Mark Richman

Reputation: 29710

jQuery UI Draggable/Sortable - Get reference to new item

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.

Upvotes: 16

Views: 15980

Answers (3)

flu
flu

Reputation: 14683

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).

Upvotes: 1

Dan
Dan

Reputation: 6504

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...

Upvotes: 1

Andrew Whitaker
Andrew Whitaker

Reputation: 126052

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.

Upvotes: 30

Related Questions