JQuery可排序嵌套的可排序div

时间:2016-02-05 19:08:13

标签: javascript jquery jquery-ui nested jquery-ui-sortable

这个问题与这个Nest jQuery UI sortables有关,但我无法解决我的问题。

问题在于:我有一个包含项目的主容器,这些项目是可以是未分组项目或组的div,其中包含其他项目。我可以通过拖动.multiply-group div来定义新组,然后我可以立即拖动所有组。这是代码:

    <body>
    <div class="multiply-container">
        <div class="row multiply">Item 1</div>
        <div class="row multiply">Item 2</div>
        <div class="row multiply">Item 3</div>
        <div class="row multiply-group"> Group 1</div>
        <div class="row multiply">Item 4</div>
        <div class="row multiply-group"> Group 2 </div>
        <div class="row multiply">Item 5</div>
    </div>

    <script>

        var groupWrap = function(){

            $('.multiply-container').children().each(function(index, item){
                if($(item).hasClass('multiply-group')){
                    $(item).nextUntil('.multiply-group').addBack().wrapAll('<div class="locked"></div>');
                }
            });

        };

        var updateMultiply = function(){

            var $container = $('.multiply-container');

            $container.children().each(function(index, item){
                if($(item).hasClass('locked')){
                    $(item).children().each(function(i, elem){

                        $container.append($(elem));

                    });
                    $(item).remove();
                }


            });

            groupWrap();

            $('.multiply-container').sortable({
                connectWith: '.locked',
                helper: 'clone',
                placeholder: '.multiply-placeholder',
                axis: 'y',
                update: function(){
                    updateMultiply();
                }
            });

            $('.locked').sortable({
                connectWith: '.multiply-container, .locked',
                helper: 'clone',
                axis: 'y',
                update: function(){
                    updateMultiply();
                },
                receive: function(event, ui){

                    if($(ui.item).hasClass('locked')){
                        $(ui.sender).sortable('cancel');

                        return false;
                    }

                }
            });

        };




        updateMultiply();

    </script>

</body>

这是一个小提琴:https://jsfiddle.net/antoq/n1w6e6ar/2/

问题是我得到的是当我将 last 组容器拖出主容器的底部时,它停在那里而不是回到主容器,我得到以下错误:

  

Uncaught HierarchyRequestError:无法执行'insertBefore'   'Node':新的子元素包含父元素。

有人可以帮助我了解正在发生的事情以及如何解决这个问题吗?

1 个答案:

答案 0 :(得分:4)

当你编码时,你可能会过度思考它:两个可排序的,不必要的事件取消,连接已经连接的列表等等。

最后一组陷入困境或消失的问题似乎是在每次更新列表时重新附加.sortable()的问题,这是导致意外行为的重现。但是简单地删除那个重复使得你的列表不像你看起来那样表现,所以需要一些额外的重构:

1)只使用一次.sortable()次调用,然后定义哪些项目可以排序(分别为.row.locked进行个别和分组排序。这已经足够你想要的了。这里唯一的问题是将一个组拖到另一个组的中间会增加另一个嵌套级别;

2)为防止出现其他嵌套级别,请在再次换行之前打开.locked组。

var groupWrap = function() {
  $('.locked').children().unwrap();
  $('.multiply-container')
    .children().each(function(index, item) {
      if ($(item).hasClass('multiply-group')) {
        $(item).nextUntil('.multiply-group').addBack().wrapAll('<div class="locked"></div>');
      }
    });
};

var updateMultiply = function() {

  var $container = $('.multiply-container');

  $container.children().each(function(index, item) {
    if ($(item).hasClass('locked')) {
      $(item).children().each(function(i, elem) {

        $container.append($(elem));

      });
      $(item).remove();
    }
  });
};

$('.multiply-container').sortable({
  items: '.row, .locked',
  helper: 'clone',
  axis: 'y',
  update: function() {
    update();
  }
});

var update = function() {
  updateMultiply();
  groupWrap();
};

update();
body {
   background-color: #eee;
   padding: 50px;
 }
 .multiply {
   height: 45px;
   width: 100%;
   background-color: violet;
   border: 1px solid purple;
   margin: 0 auto;
   text-align: center;
 }
 .multiply-group {
   height: 25px;
   width: 100%;
   background-color: teal;
   border: 2px solid orange;
   margin: 0 auto;
   text-align: center;
 }
 .multiply-container {
   background-color: lime;
   padding: 20px;
 }
 .multiply-placeholder {
   height: 65px;
   width: 100%;
 }
 .locked {
   padding: 20px;
   background-color: cyan;
   border: 1px solid blue;
 }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<body>
  <div class="multiply-container">
    <div class="row multiply">Item 1</div>
    <div class="row multiply">Item 2</div>
    <div class="row multiply">Item 3</div>
    <div class="row multiply-group">Group 1</div>
    <div class="row multiply">Item 4</div>
    <div class="row multiply-group">Group 2</div>
    <div class="row multiply">Item 5</div>
  </div>
</body>