I am working on a catalog for a website that uses a grid to show different purchaseable items. Now I have a function that will hide certain items in the grid by clicking an image. But when clicked the items that are still visible stay in their original position in the grid. So if i have 6 items spread over 2 rows and 3 columns as such:
1 2 3
4 5 6
and then perform the function to lets say hide numbers dividable by 2 the grid looks like this
1 3
5
Is there a way to make the grid look like this instead?
1 3 5
I am using display = 'none' to hide the items.
Here is a simplified version of the code:
var ChangeLayout = function(rarity) {
var listItemContainers = document.getElementsByClassName("itemContainer");
var listItemContainersByRarity = document.getElementsByClassName(rarity);
var j;
var h;
if (rarity == 'all') {
for (j = 0; j < listItemContainers.length; j++) {
document.getElementsByClassName("itemContainer")[j].style.display = 'block';
}
} else {
for (j = 0; j < listItemContainers.length; j++) {
document.getElementsByClassName("itemContainer")[j].style.display = 'none';
}
for (h = 0; h < listItemContainersByRarity.length; h++) {
document.getElementsByClassName(rarity)[h].style.display = 'block';
}
}
}
#catalogGrid {
display: grid;
grid-auto-flow: row;
grid-template-columns: repeat(3, 1fr);
grid-column-gap: 5px;
grid-row-gap: 5px;
}
<img id="gemStoneAll" onclick="ChangeLayout('all')" />
<img id="gemStoneUncommon" onclick="ChangeLayout('uncommon')" />
<img id="gemStoneRare" onclick="ChangeLayout('rare')" />
<img id="gemStoneVeryRare" onclick="ChangeLayout('veryrare')" />
<ul id=catalogGrid>
<li>
<div class="itemContainer rare">
</div>
</li>
<li>
<div class="itemContainer veryrare">
</div>
</li>
<li>
<div class="itemContainer uncommon">
</div>
</li>
<li>
<div class="itemContainer uncommon">
</div>
</li>
<li>
<div class="itemContainer rare">
</div>
</li>
<li>
<div class="itemContainer rare">
</div>
</li>
</ul>
The <li>
elements are not shown/hidden because you're changing the styles of their child <div>
elements. One solution is to put the classes on the parent <li>
elements, instead.
In this case, I suggest using the display property list-item
rather than block
.
var ChangeLayout = function(rarity) {
var listItemContainers = document.getElementsByClassName("itemContainer");
var listItemContainersByRarity = document.getElementsByClassName(rarity);
if (rarity == 'all') {
for (var j = 0; j < listItemContainers.length; j++) {
listItemContainers[j].style.display = 'list-item';
}
} else {
for (var j = 0; j < listItemContainers.length; j++) {
listItemContainers[j].style.display = 'none';
}
for (var h = 0; h < listItemContainersByRarity.length; h++) {
listItemContainersByRarity[h].style.display = 'list-item';
}
}
}
#catalogGrid {
display: grid;
grid-auto-flow: row;
grid-template-columns: repeat(3, 1fr);
grid-column-gap: 5px;
grid-row-gap: 5px;
}
<img id="gemStoneAll" src="https://picsum.photos/id/10/50/50" onclick="ChangeLayout('all')" />
<img id="gemStoneUncommon" src="https://picsum.photos/id/30/50/50" onclick="ChangeLayout('uncommon')" />
<img id="gemStoneRare" src="https://picsum.photos/id/40/50/50" onclick="ChangeLayout('rare')" />
<img id="gemStoneVeryRare" src="https://picsum.photos/id/50/50/50" onclick="ChangeLayout('veryrare')" />
<ul id=catalogGrid>
<li class="itemContainer rare">
<div>Rare</div>
</li>
<li class="itemContainer veryrare">
<div>Very Rare</div>
</li>
<li class="itemContainer uncommon">
<div>Uncommon</div>
</li>
<li class="itemContainer uncommon">
<div>Uncommon</div>
</li>
<li class="itemContainer rare">
<div>Rare</div>
</li>
<li class="itemContainer rare">
<div>Rare</div>
</li>
</ul>
Here's a version with some minor optimzations:
var allItems = document.getElementsByClassName("item");
var btns = document.getElementsByClassName('btn');
function changeLayout(rarity) {
var selectedItems = document.getElementsByClassName(rarity);
// hide all
Array.from(allItems).forEach((el) => {
el.classList.add('hide');
});
// show selected
Array.from(selectedItems).forEach((el) => {
el.classList.remove('hide');
});
}
// bind click handlers
Array.from(btns).forEach((el) => {
el.addEventListener('click', function() {
changeLayout(el.dataset.filter);
});
});
#grid {
display: grid;
grid-auto-flow: row;
grid-template-columns: repeat(3, 1fr);
grid-column-gap: 5px;
grid-row-gap: 5px;
}
.hide {
display: none;
}
<img class="btn" data-filter="all" src="https://picsum.photos/id/10/50/50">
<img class="btn" data-filter="uncommon" src="https://picsum.photos/id/30/50/50">
<img class="btn" data-filter="rare" src="https://picsum.photos/id/40/50/50">
<img class="btn" data-filter="veryrare" src="https://picsum.photos/id/50/50/50">
<ul id=grid>
<li class="item all rare">Rare</li>
<li class="item all veryrare">Very Rare</li>
<li class="item all uncommon">Uncommon</li>
<li class="item all uncommon">Uncommon</li>
<li class="item all rare">Rare</li>
<li class="item all rare">Rare</li>
</ul>