简体   繁体   中英

jQueryUI Sortable Refresh Fail

I wanted to write jQuery/JavaScript code for two sortable lists with the following restrictions:

  • List1 will only accept from List2, and vice versa.
  • Items can only be dragged from the top.
  • Items can only be added to the top.

    I tried with several different versions of jQuery and jQueryUI, and I cannot seem to achieve this. This is what I have so far:

HTML:

<ul class='sortList' id="list1">
    <li class="ui-state-default">abc1</li>
    <li class="ui-state-default">def1</li>
    <li class="ui-state-default">ghi1</li>
    <li class="ui-state-default">jkl1</li>
    <li class="ui-state-default">mno1</li>
</ul>

<ul class='sortList' id="list2">
    <li class="ui-state-default">abc2</li>
    <li class="ui-state-default">def2</li>
    <li class="ui-state-default">ghi2</li>
    <li class="ui-state-default">jkl2</li>
    <li class="ui-state-default">mno2</li>
</ul>

JavaScript:

$(function() {

    var blockSort = true;

    $("#list1").sortable({
        connectWith: "#list2",
        items: "> li:first",
        start: function(event, ui) {
            ui.placeholder.height(ui.item.height());
        },
        receive: function(event, ui) {
            blockSort = false;
            $('#list1').find('li:eq(0)').before(ui.item);
        },
        stop: function(event, ui) {
            if (blockSort) {
                event.preventDefault();
            }
            blockSort = true;
        }
    }).disableSelection();

    $("#list2").sortable({
        connectWith: "#list1",
        items: "> li:first",
        start: function(event, ui) {
            ui.placeholder.height(ui.item.height());
        },
        receive: function(event, ui) {
            blockSort = false;
            $('#list2').find('li:eq(0)').before(ui.item);
        },
        stop: function(event, ui) {
            if (blockSort) {
                event.preventDefault();
            }
            blockSort = true;
        }
    }).disableSelection();

});

CSS:

.sortList { list-style-type: none; margin: 0; padding: 0; float: left; margin-right: 10px; background: #eee; padding: 5px; width: 150px;
}

.sortList li { display: inline-block; margin: 5px; padding: 5px; font-size: 1.2em; width: 120px;
}

.ui-sortable-placeholder {
    border: 1px dotted black;
    background: rgba(99,99,99,0.05);
    visibility: visible !important;
}

.ui-sortable-placeholder * {
    visibility: hidden;
}

JSFiddle Example

The problem is, once a list item becomes active as sortable, it does not get disabled when more items are added on top. I thought that would happen on its own, and there is no longer an explicit refresh necessary. But I also tried using refresh, which also did not work.

How should this be properly implemented?

This might be a bug .

But as a workaround, you can destroy the sortable and re-initialize it with cached options in the receive event as follows:

receive: function(event, ui) {
        blockSort = false;
        $('#list1').find('li:eq(0)').before(ui.item);
        var options = $("#list1").sortable('option')
        $("#list1").sortable('destroy').sortable(options);
    },

JSfiddle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM