Tom Hartwell
Tom Hartwell

Reputation: 668

JQuery UI Sortable - Add Placeholders to Lists to Simulate empty spaces

JQuery UI Sortable works great for lists with no gaps, but say I want to render a list of items with gaps, e.g.

1, 2, empty, 4, 5, 6, empty, 8

where the number represents the slot number. The behavior expected then would be if the user drags an element over the 2 slot, the 2 value gets pushed to the empty slot 3, and the user could drop the new element in the 2 slot, whereas if they drag a new element over the empty 3 slot, the list items would not push down, and the user could just drop the new item into the empty 3 slot. Hopefully this makes sense.

I've been looking at the JQuery UI Sortable code, and it seems that I need to utilize the change and receive callbacks in order to achieve this, but, being new to JQuery/JS in general, it's not clear to me what to use to add these empty slot placeholders and manage the selection list so that I don't break the sorting functionality with custom code.

Any pointers, examples, etc. would be much appreciated.

After banging my head on this for a while, I created a jsFiddle: http://jsfiddle.net/pdHnX/

To help explain the problem. I believe everything I'm trying to accomplish can happen in an overridden _rearrange method. The fiddle code handles the case where an item is replacing a filler item, but there is an odd issue, where if you drag an item from the item list to the filler list, drop the item, then drag the same item within the filler list, the filler list is shrunk by 1, which is a problem.

There are more issues once you start dragging more items into the filler list, but this is where I'm at with the problem at the moment.

Upvotes: 6

Views: 7503

Answers (3)

Tom Hartwell
Tom Hartwell

Reputation: 668

Sorry, this was a really difficult question to detail out. The requirements were really specific and hard to describe.

Here is the solution I was looking for.

The others answers here, while they may have been solutions to the poorly described problem, were not what I was looking for.

http://jsfiddle.net/vfezJ/

Unfortunately, the sortable.js code is very hairy so the code linked there is also very hairy. The solution I've posted also makes some assumptions on CSS classes and DOM ids to get the job done.

Upvotes: 1

Wray Bowling
Wray Bowling

Reputation: 2506

http://jsbin.com/igozat/2

Here's something I whipped up. It's not perfect or deserving of much credit because sortable() can't be interruped mid-drag. If that was possible, then a drop action could take over completely. Also, my attempt to re-sort was buggy. I know that this methods works with just regular jQuery, but it didn't work with jQuery UI mucking me up.

At risk of sounding like a jerk, if it were me, I'd write the functionality with just jQuery. jQuery UI isn't all its cracked up to be. :P

Upvotes: 0

Dziad Borowy
Dziad Borowy

Reputation: 12579

I'm not sure if I understood you correctly, but here's what I came up with:

http://jsfiddle.net/py3DE/

$(".source .item").draggable({ revert: "invalid", appendTo: 'body', helper: 'clone',
    start: function(ev, ui){ ui.helper.width($(this).width()); }                    // ensure helper width
});

$(".target .empty").droppable({ tolerance: 'pointer', hoverClass: 'highlight',
    drop: function(ev, ui){
        var item = ui.draggable;
        if (!ui.draggable.closest('.empty').length) item = item.clone().draggable();// if item was dragged from the source list - clone it
        this.innerHTML = '';                                                        // clean the placeholder
        item.css({ top: 0, left: 0 }).appendTo(this);                                // append item to placeholder
    }
});

Assumptions:

  • If you drag item from the top list - it will be "cloned" (original will remain in the list)
  • If you drag item from the bottom list - it will move (leaving empty placeholder)
  • If you drop any item on a bottom list's placeholder - it will replace the placeholder
  • If you drop any item on bottom list's non-empty placeholder/item - it will replace it
  • sizes of both lists always stay the same

Let me know if this helps or are you looking for something else. Also explaining the whole task (what's the purpose of this dragging) might help :-)

Upvotes: 10

Related Questions