Search code examples
javascriptjquery-uidraggablemasonrypackery

Programmatically reorder or move elements in Draggable + Packery (Masonry)


Here's a fiddle for this: http://jsfiddle.net/bortao/00uvL60c/1/

When i press "move left" / "move right" I want to send the block left/right. I do this by reinserting it on the dom structure with el.insertBefore(el.prev()) / el.insertAfter(el.next()) but this don't work since it keeps the left / top coordinates, and also don't touch the packery inner structure, if there's any.

If I drag the block it works. On bottom right i display the result of packery('getItemElements') but this is read only.

Is there a way to do this?


Solution

  • I worked a but with isotope (something similar).

    Now the direct answer http://jsfiddle.net/yry6kknh/:

    $(".item .left").on("click", function() {
      var el = $(this).closest(".item");
          if (el.prev()) {
            el.insertBefore(el.prev());
             $("#cont").packery('reloadItems');
             $("#cont").packery();
          }    
    });
    
    $(".item .right").on("click", function() {
      var el = $(this).closest(".item");
          if (el.next()) {
            el.insertAfter(el.next());
            $("#cont").packery('reloadItems');
            $("#cont").packery();
          }    
    });
    

    First fix: use $("#cont") instead of scope variable $container, to have all the time the last DOM elements (lazy loading or another DOM operations)

    Second I checked http://packery.metafizzy.co/js/packery-docs.min.js and found packery.prototype.reloadItems, when html is changed, packery needs to update his items, and $("#cont").packery(); to force re rendering.

    This is not the most correct method, but is working :)