2

I'm trying to make sortable blocks with various heights using JQuery .sortable().

But if you try to move the big block to the right then one of small boxes moves to bottom and leaves blank place.

And when I set float: right to parent div instead of float: left I can't drag the big block to the left correctly.

I understand why it happens and how the float works but I can't find a workaround.

jsFiddle sample

UPDATE: Here is complete picture of what I'm trying to do. All I want is to be able to create this structure from blank page using only 6 sizes of width, resizable height and sortable items.

ink
  • 649
  • 1
  • 9
  • 22
  • It's hard to avoid the current behavior, since moving the big block to the right causing float left on the two small ones to works just like it should :) You'll have to turn off float, depending on current sort order... – MartinHN Dec 06 '11 at 11:31
  • turn off float for which element? :) I see two ways: 1. depends of mouse x pos during dragging change float:left to float:right (when dragging to right side of parent div) 2. place small div's to one parent container to make one 'group'. but I hoped there is simplier solution :) – ink Dec 06 '11 at 11:49
  • http://jsfiddle.net/tnLcg/5/ this is example for solution #1 I posted above. This may work for 2-columns example but with 4 columns and more different blocks this is madness :( – ink Dec 06 '11 at 13:00
  • I'm not sure how you think sortable is going to help you solve this. That image is really confusing as to which column each block should end up belonging in. I think sortable was *mostly* designed for identically sized objects, and that's why you're having problems bending it to this application. – Merlyn Morgan-Graham Dec 16 '11 at 09:48

4 Answers4

1

Now works I originally had an almost working model using a second wrapping div around the short items. The bug is in my FF Win 7 (seemed okay in IE9) which sees a slight height difference between the large block and the group of blocks, so a lower float "hits" one to the upper left (if it is a large block) and does not go left. When I look in Firebug, FF is showing the computed border to be not 1px, but 0.916667px, so I don't know if that is the problem (fixed now below).

See http://jsfiddle.net/tnLcg/47/. I had originally enabled the ability to sort between short holders, but I think the correct functionality would be to make such a move a swap. Perhaps http://www.eslinstructor.net/demo/swappable/swappable_home.html might be implemented to work between the short holder stacks.

EDIT--Firefox fixed: I kept the short holder border but set it to transparent (so it calculates the same as the double height box) then used relative positioning of the elements inside to adjust for that and it works in FF now for me: EDIT: Improved version (4 column) http://jsfiddle.net/tnLcg/99/.

ScottS
  • 71,703
  • 13
  • 126
  • 146
  • Thanks for answer but it still not works. If I try to move small boxes they collapse with big ones. And most important - I've very simplified my example at jsFiddle that why there are only two columns. So if you try to use 4 columns probably block's behavior will totally incorrect. – ink Dec 09 '11 at 19:52
  • 1
    @ink--4 columns worked fine. I did notice some oddities with the placeholder, so I have modified the code (both javascript and css) to accommodate that ( http://jsfiddle.net/tnLcg/99/ ). I'm not sure what you mean by"If I try to move small boxes they collapse with big ones." I've modified the code so you can move the "block" of two together if you click between them. What behavior do you expect if a small box is attempted to be moved to a big box area? Also, do you intend to be able to move the small box positions with other small box positions? – ScottS Dec 09 '11 at 21:50
  • About 'collapsing': [screenshot](http://i.imgur.com/6Xe46.png) for [prev jsFiddle](http://jsfiddle.net/tnLcg/63/). Looks like 4 columns works good, but in your code small blocks already grouped manually (**.short_holder**). I don't know what user'll create, what width and height he'll set for new block. How can I manage this groups in case of dynamically blocks add? – ink Dec 09 '11 at 23:18
  • Well, if the user can create any size then I'm not sure you can manage it. If you set limits (largest block, half blocks, quarter blocks, etc.) then you might be able to get it to work. I am also still unclear how you want small blocks to interact with big blocks. – ScottS Dec 10 '11 at 00:06
  • I wanted to limit blocks width (6 sizes from largest to quater) and unlimited height (**.resizable()** only y axis). Big blocks have no difference with small ones. I wrote about them only because of bug (in previous post). Can you give me a clue how can I manage dynamically created blocks? – ink Dec 10 '11 at 00:11
  • 1
    Okay, based off another comment, I take it the 6 sizes are widths set to 1 (i.e. full), 3/4, 2/3, 1/2, 1/3, 1/4, correct? Height of any can be any size. But when are blocks supposed to "stack" on top of each other? How does one know if two 1/2 width blocks are to sit side by side or stack above each other? And are you expecting two 1/2 width blocks sitting side by side to stack on top of a 1/4 block sitting next to a 2/3 block both of which are stacked on top of a 3/4 block (I hope not)? That's what I mean by not understanding fully the interaction between block sizes that you are expecting. – ScottS Dec 10 '11 at 01:06
  • Yes, you're correct about sizes. If I understood you right, you asking am I want to make somethink like [this](http://i.imgur.com/cKsdA.png)? No, I want blocks to always fill row to full size, like [that](http://i.imgur.com/97bZy.png) – ink Dec 10 '11 at 07:41
  • Okay, your original question was how to make various `height` blocks interact when moved. The images you showed all show various `width` blocks of the same height. So I am still not understanding the working of the final product of various width/height blocks, but I suspect that it is too complicated for you to get a complete answer here on "how to do it". – ScottS Dec 10 '11 at 15:31
  • Sorry. You asked about widths and I forgot about others. [Here](http://i.imgur.com/r1UBc.png) is complete picture of what I'm trying to do. All I want is to be able to create this structure from blank page using only 6 sizes of width, resizable height and sortable items. – ink Dec 11 '11 at 17:07
0

You could try jQuery Masonry for that sort of layout (if I understood your question right).

AKX
  • 152,115
  • 15
  • 115
  • 172
  • Yes, you understood right, except your example doesn't support drag-in-drop (or I missed something?). I tried to add **.sortable()** to **#container** in [this demo](http://masonry.desandro.com/demos/basic-multi-column.html) but this not worked. It's exactly what I wanted excepting drag-n-drop, but without DnD it useless for me :( – ink Dec 09 '11 at 12:47
  • I think I found example of sortable and resizable masonry [here](http://tyler-designs.com/masonry-ui/) in similar [question](http://stackoverflow.com/questions/5141082/jquery-masonry-conflict-with-jquery-ui-sortable) - sometimes it works bad but it works! Maybe later somebody post somethink better than it so I'll wait to accept your answer. Thanks for your link! – ink Dec 09 '11 at 13:06
  • 2
    Masonry will not work. See [The mythical drag n’ drop multi-column grid plugin](http://metafizzy.co/blog/mythical-drag-drop-multi-column-grid-plugin/) – desandro Dec 09 '11 at 14:12
  • @desandro: Heh, alright. I'll take your word as the authority on the matter. :D – AKX Dec 11 '11 at 09:15
  • What about http://box2d-js.sourceforge.net/ ? At least, it would be fun (and maybe it will be helpful to organize your blocks tetris..). Anyways, *why* are you doing this thing? Maybe, if you describe your exact scenario, we could figure out an alternate way of doing that. (Personally, I don't like this kind of complex dragging, as many times it gets painful for the user figuring out how to move pieces to get the layout he wants..) – redShadow Dec 14 '11 at 23:40
0

If you want the two halves to be able to move independently, split them into 2 columns, then use the connectWith option to make them draggable between the two:

http://jsfiddle.net/ujahd/

If you want the two halves to stay grouped together, then group them into one div:

http://jsfiddle.net/W5VzD/1/

Will Stern
  • 17,181
  • 5
  • 36
  • 22
  • Can your example work with multiple columns (where block can have size 1/4, 1/3, 1/2 ... 3/4 of parent width and also various heights)? – ink Dec 09 '11 at 20:36
  • you could make it work like your mock by grouping 1/4 widths, etc, but once people start dragging things around it will become a mess. – Will Stern Dec 12 '11 at 18:54
0

There also this tutorial if you were interested in reading up on it. Hope you found your answer.

edit: it's not jquery though.

Nick Fury
  • 1,313
  • 3
  • 13
  • 23