roflwaffle
roflwaffle

Reputation: 30656

Working with jQuery UI Draggable, Droppable and Sortable

I have an ul of draggable items (#doc-editor-options ul li), an area for dropping those items (#doc-editor-content) and an ul within that area for holding those items (#items-holder), which is sortable. This dragging and dropping is only one-way, only items from the list can be dragged and dropped into the holder.

$("#doc-editor-options ul li").draggable({
    helper: 'clone',
    connectToSortable: '#item-holder',
    containment: $(".doc-editor")
});
$("#doc-editor-content").droppable({
    drop: function(e, ui){
        console.log('dropped');
    }
});
$("#item-holder").sortable({
    placeholder: 'placeholder-highlight',
    cursor: 'pointer',
});

Two questions that I have:

  1. Right now when I drag an item from the list and drop it into the other list, the drop callback for .droppable() is called twice. I think this has something to do with the #item-holder being sortable. I want it to only be fired when I drop an item into the list and only know about that item's event and ui in the callback.
  2. I also need the functionality where by default, the items-holder is not sortable. The only time it becomes sortable is when you are dragging and hovering an item over it. So I can't sort the list by default, but if I drag an item over to it, I can choose where to place that item in the list (i.e. the list is now sortable) and once I drop it, the list becomes unsortable again.

EDIT: I figured out #2, I needed to bind mousedown to the draggable items which enables sorting then disables it on mouseup. Still having problems with #1, it seems like some of the sortable events are firing the drop callback when I drop an item in or I hover out of the item holder.

Upvotes: 1

Views: 6380

Answers (1)

Elliot Nelson
Elliot Nelson

Reputation: 11557

1:

Your drop() gets called twice because connectToSortable is also triggering a drop().

My suggestion would be to delete $("#doc-editor-content").droppable() altogether, and instead add the receive(e, ui) handler to your sortable.

2:

Your fix works. However I would suggest a much easier alternative: leave the sortable always enabled and add the option "handle: h2". (Pick any tag that will not exist within your LIs.) This will let you drop into the list, but disable user sorting in-place.

Example:

$('#item-holder').sortable({
  placeholder: 'placeholder-highlight',
  cursor: 'pointer',
  handle: 'h2',
  receive: function(e, ui) {
    console.log('dropped');
  }
});

Upvotes: 8

Related Questions