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 =...