Olen Olen - 3 months ago 20
Javascript Question

Initiate Masonry - After infinite scroll and parametric search

Having a problem with AJAX and Masonry grid. Masonry grid is simple not being initiated at the right moments.

Before scrolling or using the parametric search to go to a specific category, it works very well.

Sample site can be found here.




Masonry



Masonry is a JavaScript grid layout library. Used normally with Bootstrap or another grid system that does not align the items correctly. Example:

Only bootstrap:



With only Bootstrap

Bootstrap and Masonry:



With Bootstrap and Masonry




When scrolling



The next columns are being added above the older ones. Giving almost the same output as unloaded images which makes images overlapping. This is normally solved by using
imagesLoaded
which I have already included in the provided code.

After scroll

When using parametric search



The Masonry is not being fired after the AJAX. Meaning it does not work at all. So the columns are being loaded without Masonry.

Please see sample site.

When using parametric search




Both scrolling and parametric search is delivered by Toolset. They have a good system with making it very easy to load JS at specific times:


  • After the AJAX Pagination with Toolset has been completed.

  • When parametric search has been triggered.

  • When the parametric search data has been collected.

  • When the parametric search form has been updated.

  • When the parametric search results have been updated.



So both after pagination and before/during/after Parametric search. Since the problem is after scrolling, and after the results for Parametric search has been updated, I would like to initiate the Masonry grid at this very moment.

The easiest example is when the scrolling is done, or pagination as it's also called.

What I have tried



I used
reloadItems
as I guessed would be correct. Please correct me if I am wrong. Resource.

jQuery( document ).on( 'js_event_wpv_pagination_completed', function( event, data ) {
$container.masonry('reloadItems')
});


In my theory it would reload all the items when scrolling, so they would be arranged properly. But it changes nothing.

I have also tried the following:

jQuery( document ).on( 'js_event_wpv_pagination_completed', function( event, data ) {
var $container = $('.masonry-container');
$container.imagesLoaded(function() {
$container.masonry('reload');
$container.masonry({
isInitLayout : true,
itemSelector: '.col-md-3'
});
});
//and on ajax call append or prepend
$container.prepend($data).imagesLoaded(function(){
$container.masonry( 'prepended', $data, true );
});
});


I also tried to reload the items when the parametric search results has been updated.

jQuery( document ).on( 'js_event_wpv_parametric_search_results_updated', function( event, data ) {
$container.masonry('reloadItems')
});


But this did not work either.

The Masonry is also added in the footer by using one of the methodes.

(function( $ ) {
"use strict";
var $container = $('.masonry-container');
$container.imagesLoaded( function () {
$container.masonry({
columnWidth: '.col-md-3',
percentPosition: true,
itemSelector: '.col-md-3'
});
});
})(jQuery);


Do you have any ideas? Where am I doing wrong?




Edit 1:



Console Error



When loading the page


Uncaught ReferenceError: data is not defined


When scrolling


Uncaught ReferenceError: $container is not defined


Changed the function to the following



(function( $ ) {
// Initiate Masonry
"use strict";
var $container = $('.masonry-container');
$container.imagesLoaded( function () {
$container.masonry({
columnWidth: '.item',
percentPosition: true,
itemSelector: '.item',
isAnimated: true // the animated makes the process smooth
});
});
$(window).resize(function() {
$('.masonry-container').masonry({
itemSelector: '.item',
isAnimated: true
}, 'reload');
});

})(jQuery);

//and on ajax call append or prepend more items
var $data = $(data).filter(".item");
$container.prepend($data).imagesLoaded(function(){
$container.masonry( 'prepended', $data, true );
});


Updated imagesloaded to newest version



I also updated imagesloaded to the newest version.

Script can be found here.

Added
.item



I added the class
.item
instead of using col-md-3, as I thought it would be a better solution.

Meaning the HTML is the following right now:

<div class="container">
<div class="masonry-container">
<div class="item">
<!-- Content comes here -->
</div>
<div class="item">
<!-- Content comes here -->
</div>
<div class="item">
<!-- Content comes here -->
</div>
<div class="item">
<!-- Content comes here -->
</div>
...
</div>
</div>


And so on.

Still console errors.

Any solutions?

Answer

The problem was solved by removing some of the duplication and so on.

Then using the following:

(function( $ ) {
    "use strict";
    var $container = $('.masonry-container');
    $container.imagesLoaded( function () {
        $container.masonry({
          columnWidth: '.item',
          percentPosition: true,
          itemSelector: '.item'
        });
    });

    $( document ).on( 'js_event_wpv_pagination_completed', function( event, data ) {
        $container.masonry('reloadItems').masonry();
    });

    $( document ).on( 'js_event_wpv_parametric_search_results_updated', function( event, data ) {
        $container.masonry('reloadItems').masonry();    
    });

    $( document ).on( 'js_event_wpv_pagination_completed', function( event, data ) {
        $container.masonry('reloadItems').masonry();
        $container.imagesLoaded( function() {
          $container.masonry();
        });
    });

    $( document ).on( 'js_event_wpv_parametric_search_results_updated', function( event, data ) {
        $container.masonry('reloadItems').masonry();
        $container.imagesLoaded( function() {
          $container.masonry();
        });
    });

})(jQuery);

This was added in the footer.php.

Comments