Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JQuery nested sortable chrome issues

I've been developing a file-tree like widget using Johnny's extended jquery sortable, which handles nested sortables better than standard JQuery.

I have an issue with reinitializing the tree with new data. There is no problem in firefox, but chrome acts up. A minimal example can be seen here (or on jsfiddle here)

In the onDrop callback, the tree is re-initialized. For brevity, all that happens is a console.log, but in my actual example, data is being POSTed to the server via ajax, and the response has new data to update the tree with.

So, Firefox is happy with this solution, but in chrome, once I drag-and-drop once, and the tree is re-initialized, the next drag will fail with Uncaught TypeError: Cannot read property 'group' of undefined

  • ✓ Firefox
  • ✓ Internet explorer
  • ✕ Chrome
like image 347
Eldamir Avatar asked Jul 28 '16 04:07

Eldamir


1 Answers

If you will destroy the sortable every time before you init that element it will work:

function init(e) {
    // First of all - we destroy the sortable
    $('ul').sortable('destroy');

    var root = $('<ul></ul>')
    createNodes(root)
    e.html(root)
    root.sortable({
        group: 'foo',
        onDrop: function ($item, container, _super, event) {
            // These two lines are default behaviour of the plugin
            $item.removeClass(container.group.options.draggedClass).removeAttr("style");
            $("body").removeClass(container.group.options.bodyClass);

            console.log('Updating')
            init(e)
        }
    })
}

Working snippet:

function createNodes(e) {
  var foo = $('<li>Foo<ul></ul></li>');
  var bar = $('<li>Bar<ul></ul></li>');
  var baz = $('<li>Baz<ul></ul></li>');
  bar.find('ul').append(baz);
  e.append(foo, bar);
}

function init(e) {
  // First of all - we destroy the sortable
  $('ul').sortable('destroy');
  
  var root = $('<ul></ul>')
  createNodes(root)
  e.html(root)
  root.sortable({
    group: 'foo',
    onDrop: function ($item, container, _super, event) {
        // These two lines are default behaviour of the plugin
        $item.removeClass(container.group.options.draggedClass).removeAttr("style");
        $("body").removeClass(container.group.options.bodyClass);

        console.log('Updating')
        init(e)
    }
  })
}

$(document).ready(function(){
  init($('#myroot'))
})
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//johnny.github.io/jquery-sortable/js/jquery-sortable.js"></script>
<div id="myroot">
</div>
like image 163
Dekel Avatar answered Sep 20 '22 20:09

Dekel