【问题标题】:jQuery UI draggable prevent duplicatesjQuery UI 可拖动防止重复
【发布时间】:2018-02-16 09:29:24
【问题描述】:

我在左侧有一个项目列表,可以将其拖入右侧的任何框中。这些项目可以在多个盒子中,但每个盒子只能出现一次。我正在尝试获取可拖动项目的 ID,并将其与框中已存在的所有项目的 ID 进行比较,但似乎无法正确处理。我的代码如下:

$(".sortable").sortable({
    revert: true,
    connectWith: ".draggable"
});
$(".draggable").draggable({
    connectToSortable: ".sortable",
    helper: "clone",
    revert: "true",
    placeholder: ".droppable-placeholder",
    stop: function(event, ui) {
        //console.dir(ui.helper[0]);

        var listContainer = ui.helper[0].closest('ul');
        if (listContainer) {
        
          console.dir(listContainer);
          listContainer.find('li').each(function() { //This is not right
              var sortableItemId = $(this).attr("id");
              console.dir($(this));
              console.log("sortable item id " + sortableItemId);
          });
        }
    }
});


$("ul, li").disableSelection();
$(".draggable-column, .droppable-column").on("click", ".close-list-item", function(event) {

    event.preventDefault();
    $(this).closest('li').remove();
});
ul {
    list-style-type: none;
    margin: 0;
    padding: 0;
    margin-bottom: 0.7em;
    float: left;
}

li {
    margin: 0.5em;
    padding: 0.5em;
    width: 200px;
    border: 1px solid black;
}

.draggable-column {
    height: 100%;
}

.droppable-item {
    padding: 0.5em;
    float: left;
    align-content: space-between;
}

.droppable-item > h3 {
    text-align: center;
}

.sortable {
    width: 230px;
    height: 10em;
    overflow: auto;
    border: 1px solid black;
    background-color: lightgrey;
}

.droppable-placeholder {
    background-color: yellow;
}

.row {
    display: flex;
    /* equal height of the children*/
}

.col {
    flex: 1;
    /* additionally, equal width */
    padding: 1em;
    border: solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
<div class="row">
    <div class="col-xs-4 draggable-column">
        <ul class="" id="draggable-column-list">
            <li class="draggable " id="item1">1 Drag me onto item
                <a href="#" class="close-list-item">
                    <i class="fa fa-window-close"></i>
                </a>
            </li>
            <li class="draggable " id="item2">2 Drag me onto item
                <a href="#" class="close-list-item">
                    <i class="fa fa-window-close"></i>
                </a>
            </li>
            <li class="draggable " id="item3">3 Drag me onto item
                <a href="#" class="close-list-item">
                    <i class="fa fa-window-close"></i>
                </a>
            </li>
            <li class="draggable " id="item4">4 Drag me onto item
                <a href="#" class="close-list-item">
                    <i class="fa fa-window-close"></i>
                </a>
            </li>
            <li class="draggable " id="item5">5 Drag me onto item
                <a href="#" class="close-list-item">
                    <i class="fa fa-window-close"></i>
                </a>
            </li>
        </ul>
    </div>

    <div class="col-xs-8 droppable-column">

        <div class="droppable-item">
            <h3>
              Item 1
            </h3>
            <ul class="sortable" id="ul-item1">

            </ul>
        </div>
        <div class="droppable-item">
            <h3 class="">
              Item 2
            </h3>
            <ul class="sortable" id="ul-item2">

            </ul>
        </div>
        <div class="droppable-item">
            <h3>
              Item 3
            </h3>
            <ul class="sortable" id="ul-item3">

            </ul>
        </div>
        <div class="droppable-item">
            <h3>
              Item 4
            </h3>
            <ul class="sortable" id="ul-item4">

            </ul>
        </div>
        <div class="droppable-item">
            <h3>
              Item 5
            </h3>
            <ul class="sortable" id="ul-item5">

            </ul>
        </div>
        <div class="droppable-item">
            <h3>
              Item 6
            </h3>
            <ul class="sortable" id="ul-item6">

            </ul>
        </div>
    </div>

</div>

我基本上是想阻止在同一个盒子中出现重复。

【问题讨论】:

  • 那么您目前如何比较已删除的项目与列表中的项目?
  • @Twisty,对不起,我在 tiswas 并删除了很多不起作用的代码

标签: jquery-ui duplicates draggable


【解决方案1】:

所以我终于想出了一个可能的解决方案,虽然它不是特别干净:

$(".sortable").sortable({
    revert: true,
    connectWith: ".draggable"
   
});

$(".draggable").draggable({
    connectToSortable: ".sortable",
    helper: "clone",
    revert: "true",
    placeholder: ".droppable-placeholder",
    
    stop: function(event, ui) {
        console.log("--start of stop");
        var listContainer = $(ui.helper[0].parentElement);
        var newListId = listContainer.attr("id");
        var draggableId = $(this).attr("id");
        var cloneId = newListId + "-" + draggableId;
        console.log("new list id: " + newListId);
        console.log("draggableId: " + draggableId);
        console.log("cloneId: " + cloneId);
        var itemExists = false;
        $("#"+ newListId).find('li').each(function() {
            var sortableItemId = $(this).attr("id");
            console.log("sortable item id " + sortableItemId);
            if (sortableItemId != undefined && sortableItemId == cloneId) {
            	console.log("***  sortable item already exists");
            	itemExists = true;
            } 
        });
        if (itemExists) {
        	$("#" + cloneId).remove();
        }
        $(ui.helper[0]).attr("id", cloneId);
        
        console.log("--end of stop");

    },

});


$("ul, li").disableSelection();
$(".draggable-column, .droppable-column").on("click", ".close-list-item", function(event) {

    event.preventDefault();
    $(this).closest('li').remove();
});
ul {
    list-style-type: none;
    margin: 0;
    padding: 0;
    margin-bottom: 0.7em;
    float: left;
}

li {
    margin: 0.5em;
    padding: 0.5em;
    width: 200px;
    border: 1px solid black;
}

.draggable-column {
    height: 100%;
}

.droppable-item {
    padding: 0.5em;
    float: left;
    align-content: space-between;
}

.droppable-item > h3 {
    text-align: center;
}

.sortable {
    width: 230px;
    height: 10em;
    overflow: auto;
    border: 1px solid black;
    background-color: lightgrey;
}

.droppable-placeholder {
    background-color: yellow;
}

.row {
    display: flex;
    /* equal height of the children*/
}

.col {
    flex: 1;
    /* additionally, equal width */
    padding: 1em;
    border: solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
<div class="row">
    <div class="col-xs-4 draggable-column">
        <ul class="" id="draggable-column-list">
            <li class="draggable " id="item1">1 Drag me onto item
                <a href="#" class="close-list-item">
                    <i class="fa fa-window-close"></i>
                </a>
            </li>
            <li class="draggable " id="item2">2 Drag me onto item
                <a href="#" class="close-list-item">
                    <i class="fa fa-window-close"></i>
                </a>
            </li>
            <li class="draggable " id="item3">3 Drag me onto item
                <a href="#" class="close-list-item">
                    <i class="fa fa-window-close"></i>
                </a>
            </li>
            <li class="draggable " id="item4">4 Drag me onto item
                <a href="#" class="close-list-item">
                    <i class="fa fa-window-close"></i>
                </a>
            </li>
            <li class="draggable " id="item5">5 Drag me onto item
                <a href="#" class="close-list-item">
                    <i class="fa fa-window-close"></i>
                </a>
            </li>
        </ul>
    </div>

    <div class="col-xs-8 droppable-column">

        <div class="droppable-item">
            <h3>
              Item 1
            </h3>
            <ul class="sortable" id="ul-item1">

            </ul>
        </div>
        <div class="droppable-item">
            <h3 class="">
              Item 2
            </h3>
            <ul class="sortable" id="ul-item2">

            </ul>
        </div>
        <div class="droppable-item">
            <h3>
              Item 3
            </h3>
            <ul class="sortable" id="ul-item3">

            </ul>
        </div>
        <div class="droppable-item">
            <h3>
              Item 4
            </h3>
            <ul class="sortable" id="ul-item4">

            </ul>
        </div>
        <div class="droppable-item">
            <h3>
              Item 5
            </h3>
            <ul class="sortable" id="ul-item5">

            </ul>
        </div>
        <div class="droppable-item">
            <h3>
              Item 6
            </h3>
            <ul class="sortable" id="ul-item6">

            </ul>
        </div>
    </div>

</div>

【讨论】:

    【解决方案2】:

    我也为此苦苦挣扎,无法使其与控件的默认功能一起使用。我实现了一个类似于答案的解决方案,但在“接收”处理程序中。基本上在添加项目后,我会查找重复项,然后删除当前添加的重复项。这看起来也不是很干净,但很有效。我真的认为可排序控件应该具有此功能,如果有,则没有很好的文档记录。我想如果你真的想添加一个合适的解决方案,你需要编写一个挂钩到 mousedrop 事件的扩展,并尝试在接收处理程序触发之前阻止添加......

    注意:我使用可排序列表作为放置目标,使用可拖动项目的列表作为源。

    这是我的解决方案:

    $(".sortable").sortable({
    revert: "invalid",
    connectWith: ".draggable",
    placeholder: "ui-state-highlight",
    forcePlaceholderSize: true,
    receive: function (event, ui) {
        var addedItem = $($(this).data().uiSortable.currentItem);
        addedItem.prop("id", "dropped_" + $(ui.item[0]).prop("id"));
    
        // Elaborate way to check duplicates and remove them when added. Could not find a way to prevent the item from being dropped
        var childItems = $(this).children("li");
        var idCount = {};
    
        $.each(childItems, function (i, node) {
            var currentId = $(node).prop("id");
            if (idCount[currentId] != undefined) {
                if (addedItem.prop("id") === currentId) {
                    addedItem.remove();
                    return false;
                }
            } else {
                idCount[currentId] = true;
            }
        });
    }
    });
    

    可拖动对象如下:

     $(".draggable").draggable({
         connectToSortable: ".sortable-droptarget",
         helper: "clone",
         revert: "invalid"
     });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多