How to apply a default filter to the container after dynamic insertion of items using Jquery Isotope plugin?

15,326

Solution 1

If you have something simple like

<ul id="filters">
    <li><a href="#" data-filter=".home">Show all</a></li>
    <li><a href="#" data-filter=".what">What?</a></li>
    <li><a href="#" data-filter=".when">When?</a></li>
    <li><a href="#" data-filter=".why">Why?</a></li>
    // and so forth...
</ul>

you could just run a function to preset filtering, once the DOM has been fully constructed

$(function() {
    // Isotope stuff...
    $container.isotope({filter: '.home'});
    // more Isotope stuff...
});

and Isotope has been initialised. See this modified DeSandro fiddle in which the initial view is filtered to show only the red elements.

UPDATE Loading the initial content into an empty #container (via Ajax?), you could use the insert method or just hide the #container until all elements have been loaded and sorted. Regarding Ajax and initialising Isotope on success, see also this SO answer here.

Solution 2

You can use isotope initial options.

Please check this codepen which is based on the official example of "Combination filters".

// init Isotope
var $grid = $('.grid').isotope({
  itemSelector: '.color-shape',
  filter: '.initial-filter-class' //use this class with the items you want to load initially.
});

For example:

  <div class="color-shape small round red initial-filter-class"></div>

Solution 3

I'm a little late to the party, but I had the same question when I was working with Isotope yesterday and ended up solving it a different way.

Let's say I have a group of filter buttons, much like what Systembolaget had:

<div id="filters">
  <button data-filter="*">Show all</button>
  <button data-filter=".hidden">Archived</button>
  <button data-filter="*:not(.hidden)">Current</button>
</div>

Perhaps I want to only show the "Current" filter when a user finishes loading the page. I set a variable to the CSS selector matching the filter I wanted. We'll use this variable later.

var $grid;
var filterValue = "*:not(.hidden)";

Next, I need to initialize my content. I already had my content ready to go so I skipped this step, but you could use a JavaScript Promise if you're planning on loading the content asynchronously.

This is an example I took from Google's Promise introduction article:

var promise = new Promise(function(resolve, reject) {
  var content = [];

  // do a thing, possibly async, then…

  if (content.length > 0) {
    resolve(content);
  }
  else {
    reject(Error("Nothing loaded"));
  }
});

Here's the function I used to set-up the isotope grid and event listener:

function init() {
  // Initialize isotope and the filter method we want to use
  $grid = $('.grid').isotope({
    itemSelector: '.grid-item',
    filter: function() {
      return filterValue ? $(this).is(filterValue) : true;
    }
  });

  // Event listener for the filter buttons
  $('#filters').on('click', 'button', function() {
    filterValue = $(this).attr('data-filter');

    $(this).addClass('active')
           .siblings().removeClass('active');

    // Refresh the isotope grid to display the filtered items
    $grid.isotope();
  });
} 

Once you've defined what the promise should do, you can initialize your isotope grid. You'll need to nest it within the then method so that it only runs once the promise has successfully resolved. This also allows you to set-up any fallbacks that should run in the case where your content-loading step fails.

promise.then(function(results) {

  // Function defined in the last code snippet
  return init();

}, function(err) {
  // Error: "Nothing loaded"
  console.log(err); 

  // If you have a banner hidden on the page, you can display it
  $('.message').show();
});

If you don't need to use a promise (like in my case), then all you need to do is this:

init();
Share:
15,326
vpx
Author by

vpx

Updated on June 09, 2022

Comments

  • vpx
    vpx almost 2 years

    I'm using the Isotope Plugin. I have an empty container to which I am adding items on $(document).ready(...

    All those items are added correctly and isotope's layout and filtering on links are working perfectly.

    However, I would like to be able to apply a filter on a certain item class directly after they are appended to the container, or even better, during the insertion.

    How to do that?

    To resume, I have a '.home' filter that I would like to be applied once all items are appended to the container in stead of needing to click a "home" filter.