12 Dec.2014

Drupal: How to implement isotope and infinitescroll using Views only!

drupal + view + isotope + infinitescroll

I will begin my story with the fact that Drupal already has greatly finished contrib modules to implement this functionality.

It's just not full list:

What makes these modules? That's right, they check for libraries and their version, they change the HTML output, they allow flexibility to change some settings in the admin section.

However, for some reason, you do not want to use two or three additional modules.

The reasons may be different. For example:

  • You don't want to use a lot of additional modules and each time the test after the upgrade
  • You don't want to look for additional patches, every time when you meet the next bug
  • You are trying to save RAM of server
  • The server doesn't allow to install other modules, for example, "drupalgardens" hosting
  • You want to have full control over the source code and be independent of the modules

Now I'll quickly show you how to implement such functionality in your custom theme using View only. The module already in the code in Drupal v8, so we will use this module for Drupal v7 only.

The structure of files.
The structure of the files.

Let's prepare the necessary. We need few JavaScript libraries and own JS for the own Drupal theme:

In brackets, I showed the version I used, you can download the latest version, however, you may need to change a couple of lines in scripts.js. Do not worry, usually, those libraries are stable ;-)

We also need to create a view! Just standard drupal view: Unformatted list, Use pager: Mini, Use AJAX: No. It's enough!

The next step, open scripts.js in your favorite editor and add a few pieces of code.

File
YOUTHEME.info
scripts[] = js/imagesloaded.pkgd.min.js
scripts[] = js/isotope.pkgd.min.js
scripts[] = js/infinite-scroll/jquery.infinitescroll.min.js
scripts[] = js/infinite-scroll/behaviors/manual-trigger.js
scripts[] = js/scripts.js
File
scripts.js
/**
 * Apply imagesLoaded, isotope and infinitescroll for the view.
 * 
 * @type {{attach: Drupal.behaviors.isotopeAndInfiniteScroll.attach}}
 */
Drupal.behaviors.isotopeAndInfiniteScroll = {
  attach: function (context, settings) {
 
    var $YOUR_VIEW_Container = $('.YOUR-VIEW-CLASS .view-content', context),
      $pager = $('ul.pager', context);
 
    $YOUR_VIEW_Container.imagesLoaded(function () {
      $YOUR_VIEW_Container.isotope({
        itemSelector: '.views-row'
      });
    });
 
    $YOUR_VIEW_Container.infinitescroll({
      navSelector: 'ul.pager', // Selector for the paged navigation (it will be hidden)
      nextSelector: 'ul.pager .pager-next a', // Selector for the NEXT link (to page 2)
      itemSelector: '.views-row', // Selector for all items you'll retrieve
      loading: {
        finishedMsg: '<em>' + Drupal.t('We don\'t have such content anymore!') + '</em>',
        img: 'http://i.imgur.com/qkKy8.gif', // Preloader.
        msgText: '<em>' + Drupal.t('Loading!') + '</em>'
      },
      debug: false,
      state: {
        // The string is very important because drupal starts from page = 0, 
        // however "infinite scroll" except 1, so we override.
        currPage: 0
      },
      behavior: 'twitter',
      animate: true,
      errorCallback: function () {
      }
    }, function (arrayOfNewElements) {
      var $newElements = $(arrayOfNewElements).css({
        opacity: 0
      });
 
      $newElements.imagesLoaded(function () {
        $newElements.animate({
          opacity: 1
        });
        $YOUR_VIEW_Container.isotope('appended', $newElements);
      });
    });
 
 
    if ($YOUR_VIEW_Container.length > 0) {
      $pager.find('.pager-next a').text('load more');
      // How to Get "Twitter-style triggered infinite scroll"
      // https://github.com/paulirish/infinite-scroll/issues/520
      $('.view-content').infinitescroll('manual');
    }
 
  }
};
File
style.scss
// To make some CSS styling.
.view-id-ideas_marathon {
  .views-row {
    padding: 7px;
    vertical-align: middle;
    text-align: center;
    background-color: #FFF;
    width: 25%;
    &:before {
      content: '';
    }
  }
  // To hide the some links in the pager. We want to see "Next" link only.
  .pager-previous,
  .pager-current {
    display: none;
  }
}

Ruslan Piskarov

Ukraine
PHP/WEB Developer / Drupal Expert. More than 11 years of experience delivering Drupal based General Purpose solutions for different sectors such as Job Boards, Product Portfolios, Geo Coding, Real Estate solutions, E-Commerce, Classifieds, Corporate and online Magazines/Newspapers.