germanysbestkeptsecret / Wookmark-jQuery

A jQuery plugin to create a dynamic, multi-column layout.
MIT License
2.64k stars 759 forks source link

Refresh Filter when new images are added via AJAX #217

Closed ZainSohail closed 8 years ago

ZainSohail commented 8 years ago

Hi guys, let me start by appreciating the plugin, its really good and helped me alot ..

Okay, so I am using WookMark Filtering and Endless scroll together. I load posts via AJAX rather than cloning the first ten. Everything is working fine, but the filter doesn't seem to register the new images fetched via AJAX. I probably missed something. Guide me please ..

MY JS:

jQuery(document).ready(function($) {

    function getWindowWidth() {
      return Math.max(document.documentElement.clientWidth, window.innerWidth || 0)
    }

     // Init lightbox
    $('#container').magnificPopup({
      delegate: 'li:not(.inactive) a',
      type: 'image',
      gallery: {
        enabled: true
      }
    });

    // Instantiate wookmark after all images have been loaded
    var wookmark,
        container = '#container',
        $container = $(container),
        $window = $(window),
        $document = $(document);

    imagesLoaded('#container', function() {
      wookmark = new Wookmark('#container', {
        itemWidth: 300, // Optional min width of a grid item
        outerOffset: 0, // Optional the distance from grid to parent
        flexibleWidth: function () {
          // Return a maximum width depending on the viewport
          return getWindowWidth() < 1024 ? '100%' : '50%';
        }
      });
    });

    $('#main').append( '<span class="load-more"></span>' );
    var button = $('#main .load-more');
    var page = 2;
    var loading = false;
    var scrollHandling = {
        allow: true,
        reallow: function() {
            scrollHandling.allow = true;
        },
        delay: 400 //(milliseconds) adjust to the highest acceptable value
    };

    $(window).scroll(function(){
      if( ! loading && scrollHandling.allow ) {

        scrollHandling.allow = false;
        setTimeout(scrollHandling.reallow, scrollHandling.delay);
        var offset = $(button).offset().top - $(window).scrollTop();

        if( 2000 > offset ) {
          console.log('Added more items');
          // Get Next Page Posts AJAX
          loading = true;
          var data = {
            // Function which grabs next 10 posts available
            action: 'be_ajax_load_more',
            nonce: beloadmore.nonce,
            page: page,
            query: beloadmore.query,
          };
          $.post(beloadmore.url, data, function(res) {
            if( res.success) {
              // Get the first then items from the grid, clone them, and add them to the bottom of the grid
              var $items = $(res.data, $container);
              $container.append($items);

              wookmark.initItems();
              wookmark.layout(true, function () {
                // Fade in items after layout
                setTimeout(function() {
                  $items.css('opacity', 1);
                }, 300);
              });

              $('#main').append( button );
              page = page + 1;
              loading = false;
            } else {
              // console.log(res);
            }
          }).fail(function(xhr, textStatus, e) {
            // console.log(xhr.responseText);
          });
        }
      }
    });

    // Setup filter buttons when jQuery is available
    var $filters = $('#filters li');

    /**
     * When a filter is clicked, toggle it's active state and refresh.
     */
    var onClickFilter = function(event) {
      var $item = $(event.currentTarget),
          itemActive = $item.hasClass('active');

      if (!itemActive) {
        $filters.removeClass('active');
        itemActive = true;
      } else {
        itemActive = false;
      }
      $item.toggleClass('active');

      // Filter by the currently selected filter
      $('#container').trigger('refreshWookmark');
      wookmark.filter(itemActive ? [$item.data('filter')] : []);
    }

    // Capture filter click events.
    $('#filters').on('click.wookmrk-filter', 'li', onClickFilter);

});

Thanks in advance ..

ZainSohail commented 8 years ago

Okay, I tracked the solution on Wookmark documentation ..

I have to update the filter classes when I load new items via ajax. So I simply added wookmark.updateFilterClasses(); on my ajax success. Below is the working code if anyone needs it.

jQuery(document).ready(function($) {

    function getWindowWidth() {
      return Math.max(document.documentElement.clientWidth, window.innerWidth || 0)
    }

     // Init lightbox
    $('#container').magnificPopup({
      delegate: 'li:not(.inactive) a',
      type: 'image',
      gallery: {
        enabled: true
      }
    });

    // Instantiate wookmark after all images have been loaded
    var wookmark,
        container = '#container',
        $container = $(container),
        $window = $(window),
        $document = $(document);

    imagesLoaded('#container', function() {
      wookmark = new Wookmark('#container', {
        itemWidth: 300, // Optional min width of a grid item
        outerOffset: 0, // Optional the distance from grid to parent
        flexibleWidth: function () {
          // Return a maximum width depending on the viewport
          return getWindowWidth() < 1024 ? '100%' : '50%';
        }
      });
    });

    $('#main').append( '<span class="load-more"></span>' );
    var button = $('#main .load-more');
    var page = 2;
    var loading = false;
    var scrollHandling = {
        allow: true,
        reallow: function() {
            scrollHandling.allow = true;
        },
        delay: 400 //(milliseconds) adjust to the highest acceptable value
    };

    $(window).scroll(function(){
      if( ! loading && scrollHandling.allow ) {

        scrollHandling.allow = false;
        setTimeout(scrollHandling.reallow, scrollHandling.delay);
        var offset = $(button).offset().top - $(window).scrollTop();

        if( 2000 > offset ) {
          console.log('Added more items');
          // Get Next Page Posts AJAX
          loading = true;
          var data = {
            // Function which grabs next 10 posts available
            action: 'be_ajax_load_more',
            nonce: beloadmore.nonce,
            page: page,
            query: beloadmore.query,
          };
          $.post(beloadmore.url, data, function(res) {
            if( res.success) {
              // Get the first then items from the grid, clone them, and add them to the bottom of the grid
              var $items = $(res.data, $container);
              $container.append($items);

              wookmark.initItems();
              wookmark.updateFilterClasses();
              wookmark.layout(true, function () {
                // Fade in items after layout
                setTimeout(function() {
                  $items.css('opacity', 1);
                }, 300);
              });

              $('#main').append( button );
              page = page + 1;
              loading = false;
            } else {
              // console.log(res);
            }
          }).fail(function(xhr, textStatus, e) {
            // console.log(xhr.responseText);
          });
        }
      }
    });

    // Setup filter buttons when jQuery is available
    var $filters = $('#filters li');

    /**
     * When a filter is clicked, toggle it's active state and refresh.
     */
    var onClickFilter = function(event) {
      var $item = $(event.currentTarget),
          itemActive = $item.hasClass('active');
      console.log(itemActive);

      if (!itemActive) {
        $filters.removeClass('active');
        itemActive = true;
      } else {
        itemActive = false;
      }
      $item.toggleClass('active');

      // Filter by the currently selected filter
      wookmark.filter(itemActive ? [$item.data('filter')] : []);
    }

    // Capture filter click events.
    $('#filters').on('click.wookmrk-filter', 'li', onClickFilter);

});