Home>

How to position new cards in the Masonry grid after an AJAX request. There are cards in the container. After clicking the Load More button, new cards are not positioned. Tried two methods:

  1. uncommented

  2. commented out

    import Masonry from "masonry-layout"; import imagesLoaded from "imagesloaded";

    export default ()= > { const msnry= new Masonry ('. news-inner.grid', { itemSelector: '.news-inner .grid-item', columnWidth: '.news-inner .grid-sizer', gutter: '.news-inner .gutter-sizer', percentPosition: true, });

    const grid= document.querySelector ('. news-inner.grid');

    imagesLoaded (grid, function () { msnry.options.itemSelector= '.news-inner .grid-item';

    const items= grid.querySelectorAll ('. news-inner .grid-item');
     msnry.reloadItems (items); //This reload the masonry layout after the first call
     msnry.layout (); //This restrain the overlapping on the first call
    

    });

    //function masonryUpdate () { //setTimeout (function () { ////masonryInstance.masonry (); //msnry.reloadItems (); //}, 500); //}

    //document.documentElement.addEventListener ('click', masonryUpdate); };

  • Answer # 1

    Fixed by re-initializing Masonry in server response after AJAX request. It turned out that in one component I did the initial initialization of Masonry. And in another, where a request is made, I re-initialize Masonry in the response and use imagesLoaded.

    Used with Masonry:

    Axios

    imagesLoaded

    Code:

    import axios from 'axios';
    import Masonry from 'masonry-layout';
    import imagesLoaded from 'imagesloaded';
    export default ()= >
     {
      const posts_container= document.querySelector ('. post-inner');
      const loadMoreBtn= document.querySelector ('# ajax_load_posts');
      loadMoreBtn.style.display= 'none';
      //console.log ('posts_container:', posts_container);
      let data= new FormData ();
      data.append ('action', 'loadmore');
      data.append ('query', true_posts);
      data.append ('page', current_page);
      data.append ('post_type', post_type);
      //console.log ('data:', data);
      axios ({
        method: 'post',
        url: ajaxurl,
        data: data,
        contentType: false,
        cache: false,
        processData: false,
        dataType: 'json',
      }). then ((response)= >
     {
        if (response.data) {
          //posts_container.append (data.data); //insert new posts
          posts_container.insertAdjacentHTML ('beforeend', response.data);
          current_page ++;
          initMasonryGrid ();
          function initMasonryGrid () {
            const grid= document.querySelector ('. masonry-grid');
            const msnry= new Masonry (grid, {
              itemSelector: '.masonry-grid .grid-item',
              columnWidth: '.masonry-grid .grid-sizer',
              gutter: '.masonry-grid .gutter-sizer',
              percentPosition: true,
            });
            imagesLoaded (grid, ()= >
     {
              msnry.options.itemSelector= '.news-inner .grid-item';
              const items= grid.querySelectorAll ('. news-inner .grid-item');
              msnry.reloadItems (items); //This reload the masonry layout after the first call
              msnry.layout (); //This restrain the overlapping on the first call
            });
          }
          if (current_page!= max_pages) {
            loadMoreBtn.style.display= 'flex';
          }
          return data;
        } else {
          loadMoreBtn.remove (); //if no data, remove the button as well
        }
        //preloader.style.display= 'none';
      });
    }; 
  • Answer # 2

    Fixed by re-initializing Masonry in server response after AJAX request. It turned out that in one component I did the initial initialization of Masonry. And in another, where a request is made, I re-initialize Masonry in the response and use imagesLoaded.

    Used with Masonry:

    Axios

    imagesLoaded

    Code:

    import axios from 'axios';
    import Masonry from 'masonry-layout';
    import imagesLoaded from 'imagesloaded';
    export default ()= >
     {
      const posts_container= document.querySelector ('. post-inner');
      const loadMoreBtn= document.querySelector ('# ajax_load_posts');
      loadMoreBtn.style.display= 'none';
      //console.log ('posts_container:', posts_container);
      let data= new FormData ();
      data.append ('action', 'loadmore');
      data.append ('query', true_posts);
      data.append ('page', current_page);
      data.append ('post_type', post_type);
      //console.log ('data:', data);
      axios ({
        method: 'post',
        url: ajaxurl,
        data: data,
        contentType: false,
        cache: false,
        processData: false,
        dataType: 'json',
      }). then ((response)= >
     {
        if (response.data) {
          //posts_container.append (data.data); //insert new posts
          posts_container.insertAdjacentHTML ('beforeend', response.data);
          current_page ++;
          initMasonryGrid ();
          function initMasonryGrid () {
            const grid= document.querySelector ('. masonry-grid');
            const msnry= new Masonry (grid, {
              itemSelector: '.masonry-grid .grid-item',
              columnWidth: '.masonry-grid .grid-sizer',
              gutter: '.masonry-grid .gutter-sizer',
              percentPosition: true,
            });
            imagesLoaded (grid, ()= >
     {
              msnry.options.itemSelector= '.news-inner .grid-item';
              const items= grid.querySelectorAll ('. news-inner .grid-item');
              msnry.reloadItems (items); //This reload the masonry layout after the first call
              msnry.layout (); //This restrain the overlapping on the first call
            });
          }
          if (current_page!= max_pages) {
            loadMoreBtn.style.display= 'flex';
          }
          return data;
        } else {
          loadMoreBtn.remove (); //if no data, remove the button as well
        }
        //preloader.style.display= 'none';
      });
    };