4

I am using ajax to refresh a div containing images. I use masonry to add layout initially.

Then the ajax call returns a js that refreshes the div using the html() method. Now after it completes I am calling masonry('reloadItems'). But masonry loads all images onto one another. After a page resize it works. I tried manually triggering the page resize but it doesnt make masonry make the adjustments.

JS:

$('#timerange-select, #category_select').bind('change', function() {
    form=$('#images-filter-form');
    $.get(form.action, form.serialize(),function(){
      var $container = $('#images_container');
      $container.imagesLoaded(function(){$container.masonry('reloadItems');});
      $(window).trigger('resize');
    }, 'script');
 });

OKay the response of this ajax request is:

$('#images_container').html('<%= escape_javascript(render("shared/random_issues")) %>');

So I am not appending the images. I am replacing the container to be precise. enter image description here

This is actually 10 images loaded on each other.

EDIT: See http://stackoverflow.com/questions/17697223/masonry-images-overlapping-above-each-other/17697495?noredirect=1#17697495 for css and html.

Steve Robinson
  • 3,759
  • 3
  • 36
  • 57
  • the fist load of the items is made by an ajax call? See: http://masonry.desandro.com/methods.html#appended – grigno Jul 18 '13 at 07:28
  • Im not appending. I am just replacing the div with the response. Check edits made now. And initial load isnt ajax. – Steve Robinson Jul 18 '13 at 08:12
  • @SteveRobinson I have the same problem if you know how can i fixed it can you help me ? Please click my question [HERE](http://stackoverflow.com/questions/28874932/masonry-items-not-reloaded-when-cliking-ajax-load-more-button) –  Mar 05 '15 at 11:15

2 Answers2

7

Okay I seemed to have solved the problem.

I obtained the masonry object by using:

var masonry = $('#issue_container').data('masonry');

Now using this method I called reloadItems() and then layout(). After first method call every item overlaps onto each other in one tile and then after calling layout() a nice masonry layout is formed. The animation of moving from top-left corner into a nice layout also seems nice :D.

Steve Robinson
  • 3,759
  • 3
  • 36
  • 57
  • Thanks! I was getting insane with that issue! – Akatosh Nov 06 '13 at 20:12
  • Youre welcome! It drove me crazy too. Was a big stumbling block to Ajaxifying an important page. – Steve Robinson Nov 07 '13 at 05:46
  • I was struggling with this for a long time as well. Thanks! One observation that made me struggle with it a little more. Make sure you append items to your container and only then you fetch the `$('#issue_container').data('masonry');`. If you get the masonry instance before appending the elements it won't work. – Lucas Garcia Feb 27 '15 at 03:09
1

I resolved a similar issue just now. I had an outer div (enclosing the masonry container) that was set to {display: none} in CSS, and then made visible later on using $('#...').show(); I had the same issue. When the div + container is first made visible all the elements overlap. Then when the window is re-sized it's redrawn properly.

The issue seemed to be that when the elements are first created, the size of the div is zero (cause of the display:none setting), and when the Div is displayed (.show();) the elements are already rendered for a zero height container. Hence the overlap.

I fixed this by preventing the layout from being initialized till it's made visible

$myContainer = $('#myTiles');
$myContainer.masonry({
    itemSelector: '.myTile',
    isInitLayout: false
});

and then calling layout later on (in my case on a button click) using

$myContainer.masonry();

I checked your code, and couldn't replicate the issue on my side using your css / script settings... but thought I'd share my solution in case it helps.

perNalin
  • 161
  • 9
  • Thank you so much. I am going to bed right now. Ill try this tomorrow and let you know. Thank you so much again! – Steve Robinson Jul 30 '13 at 17:13
  • I cant seem to replicate the original problem too! I cant even seem to get masonry working after the ajax call! :( – Steve Robinson Jul 31 '13 at 12:43
  • Btw - did you put in the code above? If so the isInitLayout stops masonry from working till you actually invoke it using masonry(). There's a non-jquery version of this as well. – perNalin Aug 01 '13 at 02:41
  • No. I had removed Ajax from my search page. I tried re implementing it with masonry but masonry did not work after Ajax request. Then I added an extra container outside the original container and called masonry on this after ajax success and the first time it worked.. but in subsequent ajax calls, the masonry doesnt seem to be firing. – Steve Robinson Aug 01 '13 at 06:34
  • Ok this this what I want: I have divs showing images in a container and I have a select box to select some filters. When a person changes the value of the select box an ajax call is made and the response is a js script that will replace the HTML of the container with new set of images. I want these images to be aligned by masonry. But this isnt happening. How do I achieve this? – Steve Robinson Aug 01 '13 at 06:35
  • Without seeing the code I'm not sure I can help you with that, why not open another thread and post your code? – perNalin Aug 01 '13 at 22:48
  • Please check this: http://stackoverflow.com/questions/18015932/fire-jquery-masonry-after-refreshing-div-with-ajax-getscript-call – Steve Robinson Aug 02 '13 at 11:36
  • Nice! Glad you got it sorted out – perNalin Aug 02 '13 at 13:10