How to make a sort behave like a droppable when other sortable items are moved to it

I have a grid containing both icons and groups (folders). I want icons and groups to be sortable, but with the limitation that the groups don't go out of the way, but stay in place and basically turn into fixed targets for icon targets. Moving a group in a larger sort should be possible, this time other groups should act as sorts and get out of the way.

[Group 1] [Group 2] [Icon  1] [Icon  2]
[Group 3] [Icon  3] [Icon  4]

      

I partially achieved the desired result by making all groups part of one sortable, and all icons part of another, containing them both inside one parent container, and connecting the groups being sorted with sortable icons, but not vice versa around.

This allows me to keep static group icons when dragging the icon, while the icons are still sorted. So far so good, but I can't seem to find a way to turn the groups into falling targets for the icons. When dragging the icon over the group, I want to display the hover class and grab the group the icon was ended in if it was removed. I tried to make the groups unavailable but doesn't respond to sorts, and if I try to make the icons drag and drop they override all sortable behavior.

Another problem with my code is that groups can move icons around, but not groups. I want groups that remain stationary when the icon is moved, but move in the sortable if another group is dragged.

Note that I really don't need nested sorting because all I want is to remove the icons above the group, they don't need to be added there.

<div class='container'>
    <div class='groups'>
        <div class='item group'>Group 1</div>
        <div class='item group'>Group 2</div>
        <div class='item icon'>Icon 1</div>
        <div class='item icon'>Icon 2</div>
        <div class='item group'>Group 3</div>
        <div class='item icon'>Icon 3</div>
        <div class='item icon'>Icon 4</div>
    </div>
</div>


$('.icons').sortable({
    items: '.icon',
    containment: '.container'  
}).disableSelection();
$('.groups').sortable({
    items: '.group',
    connectWith: '.container',
    containment: '.container'
}).disableSelection();

      

jsfiddle: http://jsfiddle.net/illuminaut/vtxfsgv2/

Update: I was able to reproduce the modifiable behavior by looking document.elementFromPoint(e.clientX, e.clientY)

inside the sort event handler of the sort containing the icons. I set pointer-events: none

to .ui-sortable-helper

to peek under the currently dragged element, and if the dom element is a group, I act on it.

Here's the updated fiddle: http://jsfiddle.net/illuminaut/vtxfsgv2/4/

However, I'm not sure how reliable this method is, and I don't think it even works with touch. I would probably be better off using an actual droppable, so I leave this question open. Also, sorting for groups is still not sorted when another group is moved.

+3


source to share


1 answer


The combination of sortable and droppable did work in the end, but keeping the group items in place after dragging the icon is tricky. I ended up updating the sorting items property on the fly during the sort event, but the result is a bit quirky: it works most of the time, but is a little unpredictable.

$('.container').sortable({
    items: '.item',
    containment: '.container',
    cursor: 'move',
    placeholder: 'placeholder',
    start: function(e,ui) {
        $('.group').each(function(i) {
            var index = $(this).index('.item');
            $(this).data('pos',index);
        })
    },
    sort: function(e,ui) {
        var $sortable = $(this);
        var index = ui.placeholder.index();
        $('.group').each(function(i,el) {
            if ($(el).data('pos') == index) {
                $sortable.sortable('option','items','.icon');
                $sortable.sortable('refresh');
            }
        });
    },
    stop: function(e,ui) {
        $(this).sortable("option","items",".item");
    }
}).disableSelection();
$('.group').droppable({
    accept: '.placeholder,.icon',
    hoverClass: 'hover-target',
    drop: function(e,ui) {
        $(this).append('<p>'+ui.draggable.text()+'</p>');
        ui.draggable.remove();
    }
}).disableSelection();

      



script: http://jsfiddle.net/illuminaut/govfr3xc/

+1


source







All Articles