Alexander Dixon
Alexander Dixon

Reputation: 874

How to dynamically exclude sortable item while dragging?

I have two lists:

<ul class='list_one'>
<li>drag me</li>
<li>drag me</li>
</ul>

<ul class='list_two'>
<li class='first'>top most</li>
<li class='middle'>here i am</li>
<li class='middle'>here i am</li>
<li class='last'>least most</li>
</ul>

I want to prevent the first and last items in the second list from being sorted or shifted at all. They are to remain in those positions permanently.

The issue is that when a placeholder shadow is cast, the last item gets pushed down, out of the fixed spot.

jQuery('ul.sq-ranksort-buckets').sortable({
  connectsWith: 'ul.sq-ranksort-cards',
  items: "li:not(.last_dropped, .suppress_move)",
  cancel: ".ui-sortable-disabled, .suppress_move, .do_not_drop, ul.do_not_drop",
  over: function( event, ui ) {
    if(jQuery('.suppress_move.last:visible').length === 0) {
        jQuery(this).addClass('do_not_drop');
        jQuery(ui.item).addClass('last_dropped');
        console.log('should cancel happen: ' + jQuery('.do_not_drop').length);
    } else {
        jQuery(this).removeClass('do_not_drop');
        jQuery(ui.item).removeClass('last_dropped');
        console.log('should cancel happen: ' + jQuery('.do_not_drop').length);
    }
  }
});

Fiddle

I was wondering if there is way to dynamically recast what is typically canceled mid sort, specified by a class and then, have an event trigger as though you had dropped the sort in an un-sortable area?

This is the approach I have to take because I do not have control over the original sortable invocation and options, nor can I simply re-cast it with limited functionality.

Upvotes: 1

Views: 980

Answers (1)

MattOpen
MattOpen

Reputation: 824

There was a typo in your code. I have made a new fiddle based on yours. There is an issue in the newest jQuery UI version and ".sortable('instance')", so I choose the version 1.11.4.

The "over" option gives you the scrolling ability for both list and the "stop" option function re-order the second list. This was necessary when removing all items from list_two (exept the first and last item). Hope this is what you are searching for.

here is the new code:

$(function() {
    $( ".connectedSortable" ).sortable({
        connectWith: '.connectedSortable',
        items: "li:not(.first, .last)",
        placeholder: "ui-state-highlight",
        over: function(e, ui){
            $(ui.sender).sortable('instance').scrollParent = $(e.target)
        },
        stop: function (e, ui) {
            if ( $('.list_two li').length < 4 ) {
                $('.list_two li:eq(2):not(.first, .last)').after($('.list_two li:eq(1)'));
            }
        }
    }).disableSelection();
});

see fiddle: https://jsfiddle.net/9tLzwpra/7/

Upvotes: 2

Related Questions