Filtering
Isotope can hide and show item elements with the filter
option. Items that match that filter will be shown. Items that do not match will be hidden.
Selectors
The simplest way to filter items is with selectors, like classes. For example, each item element can have several identifying classes: transition
, metal
, lanthanoid
, alkali
, etc.
<div class="grid">
<div class="element-item transition metal">...</div>
<div class="element-item post-transition metal">...</div>
<div class="element-item alkali metal">...</div>
<div class="element-item transition metal">...</div>
<div class="element-item lanthanoid metal inner-transition">...</div>
<div class="element-item halogen nonmetal">...</div>
<div class="element-item alkaline-earth metal">...</div>
...
</div>
Set a selector with the filter
option. Items that match the selector will be shown. Items that do not match will be hidden.
// filter .metal items
$grid.isotope({ filter: '.metal' });
// filter .alkali OR .alkaline-earth items
$grid.isotope({ filter: '.alkali, .alkaline-earth' });
// filter .metal AND .transition items
$grid.isotope({ filter: '.metal.transition' });
// show all items
$grid.isotope({ filter: '*' });
jQuery selectors
Isotope uses jQuery to filter items (if jQuery is present). You can filter items with jQuery selectors.
// filter .metal items that are NOT .transition
$grid.isotope({ filter: '.metal:not(.transition)' });
Functions
You can filter with functions. The example at the top of this page uses a function to filter items when the item’s number is greater than 50.
<div class="grid">
<div class="element-item ..."><p class="number">80</p></div>
<div class="element-item ..."><p class="number">42</p></div>
<div class="element-item ..."><p class="number">20</p></div>
<div class="element-item ..."><p class="number">75</p></div>
...
</div>
If you use jQuery, you can filter with functions in jQuery.
$grid.isotope({
// filter element with numbers greater than 50
filter: function() {
// _this_ is the item element. Get text of element's .number
var number = $(this).find('.number').text();
// return true to show, false to hide
return parseInt( number, 10 ) > 50;
}
})
You can still filter with functions if you don’t use jQuery.
iso.arrange({
// item element provided as argument
filter: function( itemElem ) {
var number = itemElem.querySelector('.number').innerText;
return parseInt( number, 10 ) > 50;
}
});
UI
The example at the top uses buttons for UI. Each button has its filter set in the data-filter
attribute.
<div class="button-group filter-button-group">
<button data-filter="*">show all</button>
<button data-filter=".metal">metal</button>
<button data-filter=".transition">transition</button>
<button data-filter=".alkali, .alkaline-earth">alkali & alkaline-earth</button>
<button data-filter=":not(.transition)">not transition</button>
<button data-filter=".metal:not(.transition)">metal but not transition</button>
</div>
In the JS, we can use that filter when a button is clicked.
// init Isotope
var $grid = $('.grid').isotope({
// options
});
// filter items on button click
$('.filter-button-group').on( 'click', 'button', function() {
var filterValue = $(this).attr('data-filter');
$grid.isotope({ filter: filterValue });
});
Filter functions
To filter with a function, use a keyword and map it to an object.
<button data-filter="numberGreaterThan50">number > 50</button>
<button data-filter="ium">name ends with -ium</button>
// jQuery
// hash of functions that match data-filter values
var filterFns = {
// show if number is greater than 50
numberGreaterThan50: function() {
// use $(this) to get item element
var number = $(this).find('.number').text();
return parseInt( number, 10 ) > 50;
},
// show if name ends with -ium
ium: function() {
var name = $(this).find('.name').text();
return name.match( /ium$/ );
}
};
// filter items on button click
$('.filter-button-group').on( 'click', 'button', function() {
var filterValue = $(this).attr('data-filter');
// use filter function if value matches
filterValue = filterFns[ filterValue ] || filterValue;
$grid.isotope({ filter: filterValue });
});
// vanilla JS
// hash of functions that match data-filter values
var filterFns = {
// show if number is greater than 50
numberGreaterThan50: function( itemElem ) {
// use itemElem argument for item element
var number = itemElem.querySelector('.number').textContent;
return parseInt( number, 10 ) > 50;
},
// show if name ends with -ium
ium: function( itemElem ) {
var number = itemElem.querySelector('.name').textContent;
return name.match( /ium$/ );
}
};
Other UI
Your UI does not have to be buttons. You can use <select>
s, radio inputs, and other options.
- Select example
- Radio input example
- Filtering with a quick-search
- Inclusive combination filters with checkboxes
- Inclusive combination filters with toggle buttons
Combination filters
Filters can be combined. In addition to filtering for just .red
or .tall
, you can pass in a filter selector of both: .red.tall
.
Combination filters UI
In this example, buttons are collected in a button-group
. Each button-group
has a data-filter-group
.
<div class="button-group" data-filter-group="color">
<button data-filter="">any</button>
<button data-filter=".red">red</button>
<button data-filter=".blue">blue</button>
<button data-filter=".yellow">yellow</button>
</div>
<div class="button-group" data-filter-group="size">
<button data-filter="">any</button>
<button data-filter=".small">small</button>
<button data-filter=".wide">wide</button>
...
</div>
In the JavaScript, these filters are stored in an object, filters
. When a button is clicked, it changes the filter for that group. The object’s values are then combined into one filter '.red.small'
.
// store filter for each group
var filters = {};
$demo.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 );
$grid.isotope({ filter: filterValue });
});
// flatten object by concatting values
function concatValues( obj ) {
var value = '';
for ( var prop in obj ) {
value += obj[ prop ];
}
return value;
}
URL hash
You can hook filtering into the hashchange
event so that Isotope filters can be applied as links. See filtering with URL hash example on CodePen, view code on CodePen.
function getHashFilter() {
var hash = location.hash;
// get filter=filterName
var matches = location.hash.match( /filter=([^&]+)/i );
var hashFilter = matches && matches[1];
return hashFilter && decodeURIComponent( hashFilter );
}
$( function() {
var $grid = $('.isotope');
// bind filter button click
var $filters = $('#filters').on( 'click', 'button', function() {
var filterAttr = $( this ).attr('data-filter');
// set filter in hash
location.hash = 'filter=' + encodeURIComponent( filterAttr );
});
var isIsotopeInit = false;
function onHashchange() {
var hashFilter = getHashFilter();
if ( !hashFilter && isIsotopeInit ) {
return;
}
isIsotopeInit = true;
// filter isotope
$grid.isotope({
itemSelector: '.element-item',
filter: hashFilter
});
// set selected class on button
if ( hashFilter ) {
$filters.find('.is-checked').removeClass('is-checked');
$filters.find('[data-filter="' + hashFilter + '"]').addClass('is-checked');
}
}
$(window).on( 'hashchange', onHashchange );
// trigger event handler to init Isotope
onHashchange();
});