JSFiddle - React, Tailwind, and code Playground
HTML
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<script src="https://unpkg.com/isotope-layout@3/dist/isotope.pkgd.min.js"></script>
<div class="post">
<div class="container">
<div class="row justify-content-between">
<!-- SIDEBAR -->
<div class="col-3">
<div class="rSidebar">
<!-- tags -->
<div class="rSidebar__box">
<span class="rSidebar__label d-block fw-bold">Filter by tag</span>
<ul class="rSidebar__options button-group" data-filter-group="type">
<li class="rSidebar__options-li" data-filter=".pdf">
<span class="rSidebar__options-square"></span>
<span class="rSidebar__options-label d-block buttonTemp" data-filter=".pdf">PDF</span>
</li>
<li class="rSidebar__options-li" data-filter=".article">
<span class="rSidebar__options-square"></span>
<span class="rSidebar__options-label d-block buttonTemp" data-filter=".article">Article</span>
</li>
</ul>
</div>
<!-- type -->
<div class="rSidebar__box">
<span class="rSidebar__label d-block fw-bold">Filter by type</span>
<ul class="rSidebar__options button-group" data-filter-group="type">
<li class="rSidebar__options-li" data-filter=".blogs-and-news">
<span class="rSidebar__options-square"></span>
<span class="rSidebar__options-label d-block buttonTemp" data-filter=".blogs-and-news">Blog & News</span>
</li>
<li class="rSidebar__options-li" data-filter=".case-study">
<span class="rSidebar__options-square"></span>
<span class="rSidebar__options-label d-block buttonTemp" data-filter=".case-study">Case...
SCSS
.post{
padding: 100px;
}
.rSidebar{
&__box{
margin-bottom: 30px;
}
&__options{
padding-left: 0;
&-li{
margin-bottom: 17px;
display: flex;
align-items: center;
cursor: pointer;
width: fit-content;
&.selected{
.rSidebar__options-square{
background-color: #185A7D;
}
}
}
&-square{
height: 20px;
width: 20px;
transition: all .5s ease;
border: 2px solid #000000;
}
&-label{
margin-left: 10px;
}
}
}
.grid{
display: flex;
flex-wrap: wrap;
margin: -14px 0 0 -14px;
&-item{
box-sizing: border-box;
width: calc(33.33% - 14px);
margin: 14px 0 18px 14px;
}
}
JavaScript
document.addEventListener('DOMContentLoaded', function() {
var container = document.querySelector('.grid');
var gridItems = container.querySelectorAll('.grid-item');
const optionLinks = document.querySelectorAll('.rSidebar__options-li');
var iso = new Isotope(container, {
itemSelector: '.resourceCard',
layoutMode: 'fitRows',
transitionDuration: '0.5s',
});
var filters = {};
function concatValues( obj ) {
var value = '';
for ( var prop in obj ) {
value += obj[ prop ];
}
return value;
}
function handleFilterClick(event, filters, iso) {
var listItem = event.target;
var filterGroup = listItem.closest('.rSidebar__options').getAttribute('data-filter-group');
var filterValue = listItem.getAttribute('data-filter');
if (filters[filterGroup] === filterValue) {
delete filters[filterGroup];
} else {
filters[filterGroup] = filterValue;
}
// Combine filters
var filterValues = Object.values(filters).join(', ');
// var filterValues = concatValues( filters );
// debugging
/* console.log('List Item:', listItem);
console.log('Filter Group:', filterGroup);
console.log('Filter Value:', filterValue);
console.log('Filters Object:', filters); */
console.log('Filter Values:', filterValues);
iso.arrange({ filter: filterValues });
}
optionLinks.forEach(function(optionLink) {
optionLink.addEventListener('click', function(event) {
event.preventDefault();
this.classList.toggle('selected');
handleFilterClick(event, filters, iso);
});
});
});