metafizzy / infinite-scroll

📜 Automatically add next page
https://infinite-scroll.com
7.41k stars 1.74k forks source link

Isotope and the filters/sort #674

Open psntr opened 7 years ago

psntr commented 7 years ago

Thank you I was really excited when I heard there was an update available for infinite scroll. I was still wondering if there is way to 'cleanly' use the Isotope default Sorting/Filtering options with Infinite Scroll.

I'm asking that because, from the older post (back in 2013), it wasn't recommended to use Isotope filter with Infinite Scroll. So I used Ajax to filter my posts.

But since there is an update versions of Infinite Scroll, I was wondering if we could use both flawlessly.

Thank you again!

desandro commented 7 years ago

Thanks for this question. Whew, it's a big one.

Can you use Infinite Scroll with Isotope's filtering and sorting? Yes. The code would look something like:

// init Isotope
var $grid = $('.grid').isotope({
  // Isotope options
});

// init Infinite Scroll
$grid.infiniteScroll({
  // Infinite Scroll options
  // do not set append
  // do not set outlayer
});

// append items on load
$grid.on( 'load.infiniteScroll', function( event, response, path ) {
  var $items = $( response ).find('.grid-item');
  // append items after images loaded
  $items.imagesLoaded( function() {
    $grid.append( $items );
    $grid.isotope( 'insert', $items );
  });
});

Add a 👍 reaction to this issue if you would like to see this feature added to the docs with demos. Do not add +1 comments — They will be deleted.


But I still feel the same: Infinite Scroll with Isotope's filtering and sorting is not a good user experience. I've discussed this elsewhere in metafizzy/isotope#724.

Infinite Scroll and filtering/sorting have conflicting behaviors. Infinite Scroll adds more items in sequential order. Filtering removes items. Sorting re-arranges the order of item. This leads to several odd behaviors:

I could go on. My point is that just because even though you can use these features together, maybe you should not. Then again, metafizzy/isotope#724 has gotten a lot of 👍 so maybe I should sit back and just let this ride.

psntr commented 7 years ago

Thank you very much for the very detailed answer, to be honest I didn't ask myself those questions because I wasn't aware of some behaviours of Infinite Scroll.

I think there is a compromise between infinite scrolling and sorting/filtering posts, it would be the Ajax call to loads post according to the user chosen taxonomy. Something like you can see here: http://ma-ad.ch/ (Filter is located on the nav-bar).

Again thanks for the prompt reply and your amazing work.

radmedov commented 7 years ago

Hi, @desandro and everything! I'm using in my project Isotope Filtering and Infinite Scroll together. Please don't ask me why and tell it bad UX etc. :) My only issue is: When I apply the filter then scroll down, infinite scroll adds items, however, the filtering is not applying to these items. Please give me advice how to force the filtering to the new items? Here is my code:

Isotope.Item.prototype._create = function() {
    // assign id, used for original-order sorting
    this.id = this.layout.itemGUID++;
    // transition objects
    this._transn = {
        ingProperties: {},
        clean: {},
        onEnd: {}
    };
    this.sortData = {};
};

Isotope.Item.prototype.layoutPosition = function() {
    this.emitEvent( 'layout', [ this ] );
};

Isotope.prototype.arrange = function( opts ) {
    // set any options pass
    this.option( opts );
    this._getIsInstant();
    // just filter
    this.filteredItems = this._filter( this.items );
    // flag for initalized
    this._isLayoutInited = true;
};

// layout mode that does not position items
Isotope.LayoutMode.create('none');

// init Isotope
var $grid = $('.grid-1').isotope({
    itemSelector: '.color-shape',
    layoutMode: 'none'
});

// store filter for each group
var filters = {};

$('.filters').on( 'click', '.button', function() {
    var $this = $(this);
    // get group key
    var $buttonGroup = $this.parents('.button-group');
    var filterGroup = $buttonGroup.attr('data-filter-group');
    // set filter for group
    filters[ filterGroup ] = $this.attr('data-filter');
    // combine filters
    var filterValue = concatValues( filters );
    // set filter for Isotope
    $grid.isotope({ filter: filterValue });
});

// change is-checked class on buttons
$('.button-group').each( function( i, buttonGroup ) {
    var $buttonGroup = $( buttonGroup );
    $buttonGroup.on( 'click', 'button', function() {
        $buttonGroup.find('.is-checked').removeClass('is-checked');
        $( this ).addClass('is-checked');
    });
});

// flatten object by concatting values
function concatValues( obj ) {
    var value = '';
    for ( var prop in obj ) {
        value += obj[ prop ];
    }
    return value;
}

// init Infinite Scroll
$grid.infiniteScroll({
    // Infinite Scroll options
    path: '.pagination__next',
    button: '.view-more-button',
    status: '.page-load-status',
    // do not set append
    // do not set outlayer
});

// append items on load
$grid.on( 'load.infiniteScroll', function( event, response, path ) {
    var $items = $( response ).find('.color-shape');
    // append items after images loaded
    $items.imagesLoaded( function() {
        $grid.append( $items );
        $grid.isotope( 'insert', $items );
    });
});

var $viewMoreButton = $('.view-more-button');

// get Infinite Scroll instance
var infScroll = $grid.data('infiniteScroll');

$grid.on( 'load.infiniteScroll', onPageLoad );

function onPageLoad() {
    if ( infScroll.loadCount == 1 ) {
        // after 2nd page loaded
        // disable loading on scroll
        $grid.infiniteScroll( 'option', {
            loadOnScroll: false,
        });
        // show button
        $viewMoreButton.show();
        // remove event listener
        $grid.off( 'load.infiniteScroll', onPageLoad );
    }
}

Thank you

desandro commented 7 years ago

@radmedov Thank you for reporting this issue. I'm sorry to see you're having trouble with Infinite Scroll. Could you provide a live URL, or even better a reduced test case? See Submitting Issues in the contributing guidelines.

Danovich commented 7 years ago

@desandro Having some trouble using it with isotope, I tried your code but it will load all the images not infinite scroll.

// init Isotope
var $grid = $('.grid').isotope({
  // Isotope options
});
// init Infinite Scroll
$grid.infiniteScroll({
  // Infinite Scroll options
  // do not set append
  // do not set outlayer
});
// append items on load
$grid.on( 'load.infiniteScroll', function( event, response, path ) {
  var $items = $( response ).find('.element-item');
  // append items after images loaded
  $items.imagesLoaded( function() {
    $grid.append( $items );
    $grid.isotope( 'insert', $items );
  });
});