Search code examples
javascriptjqueryhtmlnested-sortable

jQuery sortable onDrop event freezes the page


I'm using jQuery Sortable library to create rearrangeable nested <ol> elements (do not confuse with jQuery UI sortable), when i try to execute code (console.log) in the onDrop event, the page freezes, and the dragged <li> element become transparent and floats on the page over the others elements (similar to position: absolute and opacity: 0.5)

Working example: https://johnny.github.io/jquery-sortable/#features

My code: http://jsfiddle.net/xdjn2wqp/2/


Solution

  • I wasn't getting a page freeze when testing your code, but the element that was dragged never got the .dragged class removed from it after dropping. Maybe you meant it appeared to freeze.

    Either way when executing your code you get an error on the console

    Uncaught TypeError: Cannot read property 'group' of undefined

    And looking at the code, the _super method is defined to have up to 4 arguments, but looks like it requires just 2

    http://johnny.github.io/jquery-sortable/js/jquery-sortable-min.js

    onDrop: function(a, b, c, e) {
      a.removeClass(b.group.options.draggedClass).removeAttr("style");
      d("body").removeClass(b.group.options.bodyClass)
    },
    

    Non-minified version

    http://johnny.github.io/jquery-sortable/js/jquery-sortable.js

    onDrop: function ($item, container, _super, event) {
       $item.removeClass(container.group.options.draggedClass).removeAttr("style")
       $("body").removeClass(container.group.options.bodyClass)
    },
    

    You however only pass 1, item. And from the documentation page all the examples that use _super() use two arguments, the item and then the container

    _super(item,container)
    

    So once you pass in container as well, the problem not longer exists

    $(".placeholder-children").droppable({
      drop: function(event, ui) {
        alert('dropped');
      }
    });
    $(function() {
    
      $("ol.tree").sortable({
        group: 'serialization',
        onDrop: function(item, container, _super) {
          alert("a");
          container.el.removeClass("active")
          _super(item, container)
        }
      });
    })
    body.dragging,
    body.dragging * {
      cursor: move !important;
    }
    
    .dragged {
      position: absolute;
      opacity: 0.5;
      z-index: 2000;
    }
    
    ol.tree {
      background-color: #FFF;
      margin: 10px;
      padding: 10px;
    }
    
    ol {
      list-style-type: none;
      list-style: none;
    }
    
    ol li {
      background: none repeat scroll 0 0 #eeeeee;
      border: 1px solid #cccccc;
      color: #0088cc;
      display: block;
      margin: 5px;
      padding: 5px;
      line-height: 18px;
    }
    <script type="text/javascript" src="//code.jquery.com/jquery-1.9.1.js"></script>
    <script type="text/javascript" src="//code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
    <link rel="stylesheet" type="text/css" href="//code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css">
    <script src="https://johnny.github.io/jquery-sortable/js/jquery-sortable-min.js"></script>
    <ol class="tree serialization">
      <li class="placeholder-children">First
        <ol></ol>
      </li>
      <li class="placeholder-children">Second
        <ol></ol>
      </li>
      <li class="placeholder-children">Third
        <ol>
          <li class="placeholder-children">First</li>
          <li class="placeholder-children">Second</li>
          <li class="placeholder-children">Third
            <ol>
              <li class="placeholder-children">First</li>
              <li class="placeholder-children">Second</li>
            </ol>
            <ol>
              <li class="placeholder-children">First</li>
              <li class="placeholder-children">Second</li>
            </ol>
          </li>
        </ol>
      </li>
      <li class="placeholder-children">Fourth</li>
      <li class="placeholder-children">Fifth</li>
      <li class="placeholder-children">Sixth</li>
    </ol>