7

This is my codepen: http://codepen.io/helloworld/pen/JoKmQr

Lets assume I get an array of data from the server. The data has a title and an order number.

I have 5 array items with orderNumber from 1 to 5.

Now I want to layout 5 divs where each div is positioned at a certain place in the packery layout system.

See this image:

enter image description here

The colors are NOT important. What is important is the order of the divs according to their order number.

The flow of the orderNumber goes from top to down and from left to right.

QUESTION:

How can I determine the order of the divs in the layout system? That they layout automatically to my wanted flow? Or hint about ordering manually would also be fine :-)

HTML

<h1>Packery demo - Draggabilly</h1>
<div class="packery js-packery" data-packery-options='{ "isHorizontal": true }'>
  <div class="item w1"></div>
  <div class="item h4"></div>
  <div class="item w2"></div>
  <div class="item w3"></div>
  <div class="item h2"></div>
</div>

CSS

* {
  -webkit-box-sizing: border-box;
     -moz-box-sizing: border-box;
          box-sizing: border-box;
}

body { font-family: sans-serif; }

.packery {
  background: #FDD;
  background: hsla(45, 100%, 40%, 0.2);
  counter-reset: item;
  height: 400px;
}

/* clearfix */
.packery:after {
  content: ' ';
  display: block;
  clear: both;
}

.item {
  width: 80px;
  height: 80px;
  float: left;
  border: 4px solid #333;
  border-color: hsla(0, 0%, 0%, 0.3);
}

.item:hover {
  border-color: white;
  cursor: move;
}

.item.w1 { width:   80px; background:green; }
.item.w2 { width:   80px; background:blue; }
.item.w3 { width:   80px; background:yellow; }
.item.h2 { height:  80px; background:red; }
.item.h4 { height: 160px; width:80px; background:orange;}

.item:before {
  counter-increment: item;
  content: counter(item);
  display: block;
  color: white;
  padding-top: 0.2em;
  text-align: center;
  font-size: 18px;
}

.item.is-dragging,
.item.is-positioning-post-drag {
  border-color: white;
  background: #09F;
  z-index: 2;
}

JS

// external js
// http://packery.metafizzy.co/packery.pkgd.js
// http://draggabilly.desandro.com/draggabilly.pkgd.js

$( function() {

  var $container = $('.packery').packery({
    columnWidth: 80,
    rowHeight: 80
  });

  $container.find('.item').each( function( i, itemElem ) {
    // make element draggable with Draggabilly
    var draggie = new Draggabilly( itemElem );
    // bind Draggabilly events to Packery
    $container.packery( 'bindDraggabillyEvents', draggie );
  });

});
HelloWorld
  • 4,100
  • 11
  • 38
  • 64
  • 1
    I'd like to ask for clarification: Are you attempting to determine the order of the array? If, say, the array is rearranged, are you attempting to determine the new order? – razorsyntax Dec 23 '14 at 20:48
  • @razorsyntax The array coming from the server has either a property orderIndex/Number or the ordering of the array is simply controlled by the index of each array element. Does that help? – HelloWorld Dec 23 '14 at 21:07
  • @razorsyntax At first the 5 elements are just displayed in the correct order/place. Then the user can drag/drop the elements around. The final state of the elements does not need to be persisted to the server/database. – HelloWorld Dec 24 '14 at 10:43
  • @HelloWorld, so you want to determine the order of elements after the users moves them around? – JSuar Dec 24 '14 at 14:08
  • @JSuar NO and Yes ;-) At first I want to display the elements in the correct order when the view is rendered. Drag/Drop is another new question. – HelloWorld Dec 25 '14 at 20:43
  • You are using `item h4` for the second item (which has the doubled height) and `item h2` for item 5 (normal height). How do you expect to get the results in the picture above, when the second Item is larger than the others and doesn't fit below item 1? Actually the second item loads fine, after the first item. But when the program sees a space below item 1 it goes there. Can you please clarify the question? Here's maybe what you expect to see: http://codepen.io/anon/pen/yyaQqV – Raein Hashemi Dec 29 '14 at 06:57
  • @RaeenHashemi You changed the static html. But my data is coming from the server... thats dynamically. One thing I forgot is that packery must behave responsive/fluid like it claims... but when I resize the window then all the items rearrange in a random order... I need the items to be sticked to their places! Does only masonry have this fluid mode? => http://desandro.github.io/masonry/demos/fluid.html – HelloWorld Dec 29 '14 at 16:04

1 Answers1

7

In order to get the index that packery gives elements one must call 'getItemElements' to get an accurate index of each element. The reason being is that packery doesn't actually reorder the items on the DOM it keeps its own index's.

Here's a way I solved this issue:

var $itemElems = $($container.packery('getItemElements'));

orderItems = function() {
var itemElems = $($container.packery('getItemElements'));
$(itemElems).each(function(i, itemElem) {
$(itemElem).attr('data-module-index', i); 
// adds a data attribute called data-module-index to the element and makes the value its actual index.
                });
            };
orderItems();

So when you relayout the items be sure to save/use the same index order for elements that packery gave you with the above function

Cpu Nerd
  • 276
  • 2
  • 9
  • When do you call the orderItems()? and why do you add the index as value for the data-module-index => I know the technical reason... I want to know what is the later usage for? – HelloWorld Dec 30 '14 at 11:18
  • You call orderItems whenever you want to update the data-module-index on all of the elements and yes I use the data attribute so I can use the indexes for different things at any time but you dont need that. you can do whatever you want inside of the .each function. Please +1 the answer if it helped ;-) – Cpu Nerd Dec 30 '14 at 15:08
  • Giving you a new years +51 is no problem :-) I realized that the isHorizontal = true together with the sorted order from the server is enough that it looks like in my sample screenshot. That the layout elements does not swap when I resize the windows I have to do this fluid layout with % column width: http://packery.metafizzy.co/options.html#columnwidth :-) – HelloWorld Dec 31 '14 at 09:20