I have two content type areas which contain unique filter options. These are:
type
tag
I'm trying to utilise isotope.js, to achieve a dual filtering layout, but it always gives the last clicked filter priority.
See use case here (reference below demo):
- If I click "Blog & News", I should see two posts (works)
- If I then also click "PDF", I should then see no posts (as no blog post that has pdf as a class exists). Instead, it shows me the case study post that has the pdf class.
- If I then also click "article", it should again show me no posts as no post exists that has the class
blog-and-news pdf article
. But instead shows me the case study post with it.
The filters in combination isn't working.
The documentation says the arrange()
method can handle multiple filter instances, but it isn't working in my use case.
I've also tried using the concatValues()
function to concatenate the values (as shown in many demos), but it still doesn't yield the correct results.
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);
});
});
});
.post {
padding: 100px;
}
.rSidebar__box {
margin-bottom: 30px;
}
.rSidebar__options {
padding-left: 0;
}
.rSidebar__options-li {
margin-bottom: 17px;
display: flex;
align-items: center;
cursor: pointer;
width: fit-content;
}
.rSidebar__options-li.selected .rSidebar__options-square {
background-color: #185A7D;
}
.rSidebar__options-square {
height: 20px;
width: 20px;
transition: all 0.5s ease;
border: 2px solid #000000;
}
.rSidebar__options-label {
margin-left: 10px;
}
.grid {
display: flex;
flex-wrap: wrap;
margin: -14px 0 0 -14px;
}
.grid-item {
box-sizing: border-box;
width: calc(33.33% - 14px);
margin: 14px 0 18px 14px;
}
<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 Studies</span>
</li>
</ul>
</div>
<!-- end -->
</div>
</div>
<!-- END -->
<!-- GRID -->
<div class="col-7">
<div class="grid">
<article class="resourceCard grid-item case-study pdf"><span class="resourceCard__body-title">Case study, PDF post</span></article>
<article class="resourceCard grid-item blogs-and-news"><span class="resourceCard__body-title">Blogs and news post</span></article>
<article class="resourceCard grid-item blogs-and-news article"><span class="resourceCard__body-title">Blogs and news, article post</span></article>
</div>
</div>
<!-- END -->
</div>
</div>
</div>
Latest attempt
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');
var allowMultiple = listItem.closest('.rSidebar__options').getAttribute('data-multiple') === 'true';
if (allowMultiple) {
// toggle the filter value
if (filters[filterGroup] && filters[filterGroup].includes(filterValue)) {
// remove the filter value if it already exists
filters[filterGroup] = filters[filterGroup].filter(value => value !== filterValue);
} else {
// add the filter value if it doesn't exist
if (!filters[filterGroup]) {
filters[filterGroup] = [];
}
filters[filterGroup].push(filterValue);
}
} else {
// replace the filter value
filters[filterGroup] = [filterValue];
}
var filterValues = concatValues( filters );
// 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);
});
});
});
from How do you combine multiple filters in isotope JS?
No comments:
Post a Comment