JSFiddle - React, Tailwind, and code Playground
by johnnytrinh
HTML
<script src="//isotope.metafizzy.co/beta/isotope.pkgd.js"></script>
<body>
<h1>Isotope combination filters with checkboxes</h1>
<div id="options">
<div class="option-set" data-group="brand">
<input type="checkbox" value="" id="brand-all" class="all" checked />
<label for="brand-all">All</label>
<input type="checkbox" value=".brand1" id="brand1" />
<label for="brand1">brand1</label>
<input type="checkbox" value=".brand2" id="brand2" />
<label for="brand2">brand2</label>
<input type="checkbox" value=".brand3" id="brand3" />
<label for="brand3">brand3</label>
<input type="checkbox" value=".brand4" id="brand4" />
<label for="brand4">brand4</label>
</div>
<div class="option-set" data-group="type">
<input type="checkbox" value="" id="type-all" class="all" checked />
<label for="type-all">All</label>
<input type="checkbox" value=".type1" id="type1" />
<label for="type1">type1</label>
<input type="checkbox" value=".type2" id="type2" />
<label for="type2">type2</label>
<input type="checkbox" value=".type3" id="type3" />
<label for="type3">type3</label>
<input type="checkbox" value=".type4" id="type4" />
<label for="type4">type4</label>
</div>
<div class="option-set" data-group="color">
<input type="checkbox" value="" id="color-all" class="all" checked />
<label for="color-all">All</label>
<input type="checkbox" value=".red" id="red" />
<label for="red">red</label>
<input type="checkbox" value=".blue" id="blue" />
<label for="blue">blue</label>
<input type="checkbox" value=".green" id="green" />
<label for="green">green</label>
<input type="checkbox" value=".yellow" id="yellow" />
...
CSS
body {
font-family: sans-serif;
}
.item {
width: 80px;
height: 80px;
color: white;
float: left;
}
p {
margin: 0;
}
#filter-display {
font-size: 18px;
padding: 0.5em;
border: 1px solid #CCC;
color: blue;
}
.red {
background: red;
}
.blue {
background: blue;
}
.green {
background: green;
}
.yellow {
background: yellow;
color: black;
}
/* Start: Recommended Isotope styles */
/**** Isotope Filtering ****/
.isotope-item {
z-index: 2;
}
.isotope-hidden.isotope-item {
pointer-events: none;
z-index: 1;
}
/**** Isotope CSS3 transitions ****/
.isotope, .isotope .isotope-item {
-webkit-transition-duration: 0.8s;
-moz-transition-duration: 0.8s;
-o-transition-duration: 0.8s;
transition-duration: 0.8s;
}
.isotope {
-webkit-transition-property: height, width;
-moz-transition-property: height, width;
-o-transition-property: height, width;
transition-property: height, width;
}
.isotope .isotope-item {
-webkit-transition-property: -webkit-transform, opacity;
-moz-transition-property: -moz-transform, opacity;
-o-transition-property: top, left, opacity;
transition-property: transform, opacity;
}
/**** disabling Isotope CSS3 transitions ****/
.isotope.no-transition, .isotope.no-transition .isotope-item, .isotope .isotope-item.no-transition {
-webkit-transition-duration: 0s;
-moz-transition-duration: 0s;
-o-transition-duration: 0s;
transition-duration: 0s;
}
/* End: Recommended Isotope styles */
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
body {
font-family: sans-serif;
}
/* ---- button ---- */
.button {
display: inline-block;
padding: 0.5em 1.0em;
margin-bottom: 10px;
background: #EEE;
border: none;
border-radius: 7px;
background-image: linear-gradient(to bottom, hsla(0, 0%, 0%, 0), hsla(0, 0%, 0%, 0.2));
color: #222;
font-family: sans-serif;
...
JavaScript
var $container;
var filters = {};
$(function() {
$container = $('#container');
createContent();
var $filterDisplay = $('#filter-display');
$container.isotope();
// do stuff when checkbox change
$('#options').on('change', function(jQEvent) {
var $checkbox = $(jQEvent.target);
manageCheckbox($checkbox);
var comboFilter = getComboFilter(filters);
$container.isotope({
filter: comboFilter
});
$filterDisplay.text(comboFilter);
});
});
function createContent() {
var items = '';
// dynamically create content
$container.append(items);
}
function getComboFilter(filters) {
var i = 0;
var comboFilters = [];
var message = [];
for (var prop in filters) {
message.push(filters[prop].join(' '));
var filterGroup = filters[prop];
// skip to next filter group if it doesn't have any values
if (!filterGroup.length) {
continue;
}
if (i === 0) {
// copy to new array
comboFilters = filterGroup.slice(0);
} else {
var filterSelectors = [];
// copy to fresh array
var groupCombo = comboFilters.slice(0); // [ A, B ]
// merge filter Groups
for (var k = 0, len3 = filterGroup.length; k < len3; k++) {
for (var j = 0, len2 = groupCombo.length; j < len2; j++) {
filterSelectors.push(groupCombo[j] + filterGroup[k]); // [ 1, 2 ]
}
}
// apply filter selectors to combo filters for next group
comboFilters = filterSelectors;
}
i++;
}
var comboFilter = comboFilters.join(', ');
return comboFilter;
}
function manageCheckbox($checkbox) {
var checkbox = $checkbox[0];
var group = $checkbox.parents('.option-set').attr('data-group');
// create array for filter group, if not there yet
var filterGroup = filters[group];
if (!filterGroup) {
filterGroup = filters[group] = [];
}
var isAll = $checkbox.hasClass('all');
// reset filter group if the all box was checked
if (isAll) {
delete filters[group];
if (!checkbox.checked) {
checkbox.checked = 'checked';
}
}
// index of
var index =...