Reputation: 3176
I have a custom-built select dropdown. I have a list of items with associated data values. The entire list displays by default. When an option from the dropdown is selected, on those listed items should remain.
i.e.; Select News and Media and only the items with the class news should display.
//dropdown
for (const dropdown of document.querySelectorAll(".custom__select-wrapper")) {
dropdown.addEventListener("click", function () {
this.querySelector(".custom__select").classList.toggle("open");
});
}
for (const option of document.querySelectorAll(".custom__option")) {
option.addEventListener("click", function () {
if (!this.classList.contains("selected")) {
this.parentNode
.querySelector(".custom__option.selected")
.classList.remove("selected");
this.classList.add("selected");
this.closest(".custom__select").querySelector(
".custom__select-trigger span"
).textContent = this.textContent;
}
});
}
window.addEventListener("click", function (e) {
for (const select of document.querySelectorAll(".custom__select")) {
if (!select.contains(e.target)) {
select.classList.remove("open");
}
}
});
//filter
document.addEventListener("DOMContentLoaded", function (event) {
const filter = document.querySelector("#filter");
const articles = document.querySelectorAll(".article");
filter.addEventListener("change", (event) => {
if (event.target.value != "") {
for (let i = 0; i < articles.length; i++) {
if (articles[i].dataset.itemName == event.target.value) {
articles[i].classList.remove("hidden-item");
} else {
articles[i].classList.add("hidden-item");
}
}
} else {
for (let i = 0; i < articles.length; i++) {
articles[i].classList.remove("hidden-item");
}
}
});
});
.hidden-item {
display: none;
}
.custom__select {
position: relative;
display: flex;
flex-direction: column;
}
.custom__select-wrapper {
position: relative;
user-select: none;
width: 100%;
}
.custom__select-trigger {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 22px;
font-size: 20px;
font-weight: 300;
color: #3b3b3b;
height: 60px;
line-height: 60px;
background: #ffffff;
cursor: pointer;
}
.custom__options {
position: absolute;
display: block;
background-color: #005fec;
top: 100%;
left: 0;
right: 0;
border-top: 0;
transition: all 0.5s;
opacity: 0;
visibility: hidden;
pointer-events: none;
z-index: 2;
}
.custom__select.open .custom__options {
opacity: 1;
visibility: visible;
pointer-events: all;
color: #fff;
}
.custom__option {
position: relative;
display: block;
padding: 0 22px 0 28px;
font-size: 22px;
font-weight: 300;
color: #fff;
line-height: 60px;
cursor: pointer;
transition: all 0.5s;
}
.custom__option:hover {
cursor: pointer;
background-color: #b2b2b2;
}
.custom__option.selected {
color: #ffffff;
}
.custom__option.selected::before {
content: "•";
margin-left: -12px;
padding-right: 8px;
}
/* arrow */
.arrow {
position: relative;
height: 15px;
width: 15px;
}
.arrow::before, .arrow::after {
content: "";
position: absolute;
bottom: 0px;
width: 0.15rem;
height: 100%;
transition: all 0.5s;
}
.arrow::before {
left: -5px;
transform: rotate(45deg);
background-color: #394a6d;
}
.arrow::after {
left: 5px;
transform: rotate(-45deg);
background-color: #394a6d;
}
.open .arrow::before {
left: -5px;
transform: rotate(-45deg);
}
.open .arrow::after {
left: 5px;
transform: rotate(45deg);
}
.arrow::after {
left: 5px;
transform: rotate(-45deg);
background-color: #394a6d;
}
.open .arrow::before {
left: -5px;
transform: rotate(-45deg);
}
.open .arrow::after {
left: 5px;
transform: rotate(45deg);
}
<div class="wrapper">
<div class="custom__select-wrapper">
<div class="custom__select">
<div class="custom__select-trigger"><span>Story Type</span>
<div class="arrow"></div>
</div>
<div class="custom__options" id="filter">
<span class="custom__option selected" selected="">All</span>
<span class="custom__option" value="news">News and Media</span>
<span class="custom__option" value="analysis">Analysis</span>
<span class="custom__option" value="press">Press Releases</span>
</div>
</div>
</div>
</div>
<div class="list article news 2020" data-item-name="news">
<ul>
<li><strong>Company:</strong> Company 1</li>
<li><strong>Start Date:</strong> March 26, 2020</li>
<li><strong>Title:</strong> <a href="#" target="_blank">Article Title</a></li>
<li><strong>Type:</strong> news</li>
</ul>
</div>
<div class="list article news 2019" data-item-name="news">
<ul>
<li><strong>Company:</strong> Company 2</li>
<li><strong>Start Date:</strong> November 17, 2019</li>
<li><strong>Title:</strong> <a href="#" target="_blank">Article Title</a></li>
<li><strong>Type:</strong> news</li>
</ul>
</div>
<div class="list article analysis 2017" data-item-name="analysis">
<ul>
<li><strong>Company:</strong> Company 3</li>
<li><strong>Start Date:</strong> March 15, 2017</li>
<li><strong>Title:</strong> <a href="#" target="_blank">Article Title</a></li>
<li><strong>Type:</strong> analysis</li>
</ul>
</div>
<div class="list article analysis 2016" data-item-name="analysis">
<ul>
<li><strong>Company:</strong> Company 4</li>
<li><strong>Start Date:</strong> January 3, 2016</li>
<li><strong>Title:</strong> <a href="#" target="_blank">Article Title</a></li>
<li><strong>Type:</strong> analysis</li>
</ul>
</div>
<div class="list article press 2014" data-item-name="press">
<ul>
<li><strong>Company:</strong> Company 5</li>
<li><strong>Start Date:</strong> March 13, 2014</li>
<li><strong>Title:</strong> <a href="#" target="_blank">Aritcle Title</a></li>
<li><strong>Type:</strong> press</li>
</ul>
</div>
<div class="list article press 2013" data-item-name="press">
<ul>
<li><strong>Company:</strong> Company 6</li>
<li><strong>Start Date:</strong> March 6, 2013</li>
<li><strong>Title:</strong> <a href="#" target="_blank">Article Title</a></li>
<li><strong>Type:</strong> press</li>
</ul>
</div>
Upvotes: 1
Views: 776
Reputation: 161
This is just the way I'd go about things but I would make a filter function that runs each time an option is selected.
I also wouldn't use the value tag on spans, that's what data attributes are for.
//dropdown
for (const dropdown of document.querySelectorAll(".custom__select-wrapper")) {
dropdown.addEventListener("click", function() {
this.querySelector(".custom__select").classList.toggle("open");
});
}
for (const option of document.querySelectorAll(".custom__option")) {
option.addEventListener("click", function() {
if (!this.classList.contains("selected")) {
this.parentNode.querySelector(".custom__option.selected").classList.remove("selected");
this.classList.add("selected");
this.closest(".custom__select").querySelector(".custom__select-trigger span").textContent = this.textContent;
filter(this.dataset['value']);
}
});
}
window.addEventListener("click", function(e) {
for (const select of document.querySelectorAll(".custom__select")) {
if (!select.contains(e.target)) {
select.classList.remove("open");
}
}
});
// filter
function filter(className) {
const list = document.querySelectorAll('.list.article');
for (const article of list) {
article.classList.add('hidden-item');
if (article.getAttribute('data-item-name') === className) {
article.classList.remove('hidden-item');
}
}
}
.hidden-item {
display: none;
}
.custom__select {
position: relative;
display: flex;
flex-direction: column;
}
.custom__select-wrapper {
position: relative;
user-select: none;
width: 100%;
}
.custom__select-trigger {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 22px;
font-size: 20px;
font-weight: 300;
color: #3b3b3b;
height: 60px;
line-height: 60px;
background: #ffffff;
cursor: pointer;
}
.custom__options {
position: absolute;
display: block;
background-color: #005fec;
top: 100%;
left: 0;
right: 0;
border-top: 0;
transition: all 0.5s;
opacity: 0;
visibility: hidden;
pointer-events: none;
z-index: 2;
}
.custom__select.open .custom__options {
opacity: 1;
visibility: visible;
pointer-events: all;
color: #fff;
}
.custom__option {
position: relative;
display: block;
padding: 0 22px 0 28px;
font-size: 22px;
font-weight: 300;
color: #fff;
line-height: 60px;
cursor: pointer;
transition: all 0.5s;
}
.custom__option:hover {
cursor: pointer;
background-color: #b2b2b2;
}
.custom__option.selected {
color: #ffffff;
}
.custom__option.selected::before {
content: "•";
margin-left: -12px;
padding-right: 8px;
}
/* arrow */
.arrow {
position: relative;
height: 15px;
width: 15px;
}
.arrow::before,
.arrow::after {
content: "";
position: absolute;
bottom: 0px;
width: 0.15rem;
height: 100%;
transition: all 0.5s;
}
.arrow::before {
left: -5px;
transform: rotate(45deg);
background-color: #394a6d;
}
.arrow::after {
left: 5px;
transform: rotate(-45deg);
background-color: #394a6d;
}
.open .arrow::before {
left: -5px;
transform: rotate(-45deg);
}
.open .arrow::after {
left: 5px;
transform: rotate(45deg);
}
.arrow::after {
left: 5px;
transform: rotate(-45deg);
background-color: #394a6d;
}
.open .arrow::before {
left: -5px;
transform: rotate(-45deg);
}
.open .arrow::after {
left: 5px;
transform: rotate(45deg);
}
<div class="wrapper">
<div class="custom__select-wrapper">
<div class="custom__select">
<div class="custom__select-trigger">
<span>Story Type</span>
<div class="arrow"></div>
</div>
<div class="custom__options" id="filter">
<span class="custom__option selected">All</span>
<span class="custom__option" data-value="news">News and Media</span>
<span class="custom__option" data-value="analysis">Analysis</span>
<span class="custom__option" data-value="press">Press Releases</span>
</div>
</div>
</div>
</div>
<div class="list article news 2020" data-item-name="news">
<ul>
<li><strong>Company:</strong> Company 1</li>
<li><strong>Start Date:</strong> March 26, 2020</li>
<li>
<strong>Title:</strong> <a href="#" target="_blank">Article Title</a>
</li>
<li><strong>Type:</strong> news</li>
</ul>
</div>
<div class="list article news 2019" data-item-name="news">
<ul>
<li><strong>Company:</strong> Company 2</li>
<li><strong>Start Date:</strong> November 17, 2019</li>
<li>
<strong>Title:</strong> <a href="#" target="_blank">Article Title</a>
</li>
<li><strong>Type:</strong> news</li>
</ul>
</div>
<div class="list article analysis 2017" data-item-name="analysis">
<ul>
<li><strong>Company:</strong> Company 3</li>
<li><strong>Start Date:</strong> March 15, 2017</li>
<li>
<strong>Title:</strong> <a href="#" target="_blank">Article Title</a>
</li>
<li><strong>Type:</strong> analysis</li>
</ul>
</div>
<div class="list article analysis 2016" data-item-name="analysis">
<ul>
<li><strong>Company:</strong> Company 4</li>
<li><strong>Start Date:</strong> January 3, 2016</li>
<li>
<strong>Title:</strong> <a href="#" target="_blank">Article Title</a>
</li>
<li><strong>Type:</strong> analysis</li>
</ul>
</div>
<div class="list article press 2014" data-item-name="press">
<ul>
<li><strong>Company:</strong> Company 5</li>
<li><strong>Start Date:</strong> March 13, 2014</li>
<li>
<strong>Title:</strong> <a href="#" target="_blank">Aritcle Title</a>
</li>
<li><strong>Type:</strong> press</li>
</ul>
</div>
Upvotes: 2