implement normalize() into search function in javascript - javascript

I'm trying to implement this normalize() function into my search function to make it accent insensitive, but I don't really understand how to do it. This is how I tried, but it messes up the whole search function. I would be really grateful if anyone could show me how to do this.
function myFunction() {
var input, filter, cards, cardContainer, title, i, filt, tit;
input = document.getElementById("myFilter");
filter = input.value.toUpperCase();
filt = filter.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
cardContainer = document.getElementById("myItems");
cards = cardContainer.getElementsByClassName("col-md-4");
for (i = 0; i < cards.length; i++) {
title = cards[i].querySelector(".card-body");
tit = title.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
if (tit.innerText.toUpperCase().indexOf(filt) > -1) {
cards[i].style.display = "";
} else {
cards[i].style.display = "none";
}
}
}
The working accent sensitive version:
function myFunction() {
var input, filter, cards, cardContainer, title, i;
input = document.getElementById("myFilter");
filter = input.value.toUpperCase();
cardContainer = document.getElementById("myItems");
cards = cardContainer.getElementsByClassName("col-md-4");
for (i = 0; i < cards.length; i++) {
title = cards[i].querySelector(".card-body");
if (title.innerText.toUpperCase().indexOf(filter) > -1) {
cards[i].style.display = "";
} else {
cards[i].style.display = "none";
}
}
}
and an example for the html I want to search in:
<div class="col-md-4">
<div class="card card-profile" style="min-height: 386px;" id="268">
<div class="card-avatar">
<a href="#">
<img class="img" src="assets/img/faces/avatar.png" />
</a>
</div>
<div class="card-body">
<div class="card-top">
<h4 class="card-category text-gray"><b>ááá</b><br>
<span style="color: black;">úú</span><br>
<span style="color: black;" ></span>
blabla</h4>
</div>
<hr>
<h5 class="card-description">
<i class="material-icons md-18">
mobile_friendly
</i>
<b>tel.:</b> 06301212121
</h5>
<div class="card-header" role="tab" id="heading268">
<h5 class="mb-0">
<div class="col text-center">
<a class="btn btn-dark" style="width: 100%;" data-toggle="collapse" data-parent="#accordion" href="#collapse268" aria-expanded="false" aria-controls="collapse268">Részletek<i class="material-icons">
keyboard_arrow_down
</i></a>
</div>
</h5>
</div>
<div id="collapse268" class="collapse" role="tabpanel" aria-labelledby="heading268">
<h5 class="card-description" style='display: none';>
<i class="material-icons">
mobile_friendly
</i>
<b>tel2.:</b>
</h5>
<h5 class="card-description">
<b> Leírás:</b>
leírás teszt </div>
</h5>
</div>
</div>
</div>
</div>

Here's the solution:
function myFunction() {
var input, filter, cards, cardContainer, title, i;
input = document.getElementById("myFilter");
filter = input.value.toUpperCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
cardContainer = document.getElementById("myItems");
cards = cardContainer.getElementsByClassName("col-md-4");
for (i = 0; i < cards.length; i++) {
title = cards[i].querySelector(".card-body");
if (title.innerText.toUpperCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").indexOf(filter) > -1) {
cards[i].style.display = "";
} else {
cards[i].style.display = "none";
}
}
}

Related

Count DIVs with a dynamic class inside of other DIVs with a dynamic class

I have this horrendous code, it works, but... I am sure you are all gagging at the site of it. What can be done to dynamically place the resortcode into those classes to clean this code up?
What I am trying to achieve is to add the result count in the resortheader for available rooms under each resort. This works, I just know there has to be a better way, but I am not sure how to achieve that.
The code in question is the second set.
Initial code that creates my room DIVs:
let searchresult = function(response) {
let resortCodes = new Set();
for (let j = 0; j < response.length; j++) {
resortCodes.add(response[j].resortcode); // add only happens if the resortcode isn't already in resortCodes
let divID = 'results-' + response[j].resortcode;
let container = document.getElementById(divID);
let price = response[j].points.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
if (response[j].available < 1) {
var available = 'soldoutresult';
var resultClass = response[j].resortcode + 'soldout';
var btn = '<button type="button" class="soldout">SOLD OUT</button>';
}
else {
var available = 'availableresult';
var resultClass = response[j].resortcode + 'roomavail';
var btn = '<button type="button" class="booknow">BOOK NOW</button>';
}
container.innerHTML += `
<div class="${available} roomresults ${resultClass}">
<div class="roomthumb" style="background-image:url(${response[j].roomimgthumb});">
<center><button class="myBtn roomdetailsbtn" data-target="#modal${response[j].roomcode}" data-toggle="modal">Room Details</button></center>
</div>
`
}
};
To Count My DIVs.
let countResults = function(response){
var countAKV = $('div.AKVroomavail').length;
var countAKV2 = $('div.AKV2roomavail').length;
var countAULV = $('div.AULVroomavail').length;
var countBLT = $('div.BLTroomavail').length;
if(countAKV == 0){
document.getElementById('count-akvjh').innerHTML='Sold Out';
}
else {
document.getElementById('count-akvjh').innerHTML = countAKV + " Results";
}
if(countAKV2 == 0){
document.getElementById('count-akvkv').innerHTML='Sold Out';
}
else {
document.getElementById('count-akvkv').innerHTML = countAKV2 + " Results";
}
if(countAULV == 0){
document.getElementById('count-aul').innerHTML='Sold Out';
}
else {
document.getElementById('count-aul').innerHTML = countAULV + " Results";
}
if(countBLT == 0){
document.getElementById('count-blt').innerHTML='Sold Out';
}
}
The HTML:
<div id="akvjhcontainer" class="resortcontainer">
<div id="akvjhheader" class="resortheader">
<div class="headertext"><p class="resortnametext">Animal Kingdom Villas - Jambo House</p><p class="locationtext">Walt Disney World - Orlando, Florida</p></div>
<div class="collapseBTN"><span id="count-akvjh"class="rescount"></span><button class="collstyle" data-toggle="collapse" data-target="#results-AKV"><i></i></button></div>
</div>
<div id="results-AKV" class="results-AKV collapse show"></div>
</div>
<div id="akvkvcontainer" class="resortcontainer">
<div id="akvkvheader" class="resortheader">
<div class="headertext"><p class="resortnametext">Animal Kingdom Villas - Kidani Village</p><p class="locationtext">Walt Disney World - Orlando, Florida</p></div>
<div class="collapseBTN"><span id="count-akvkv"class="rescount"></span><button class="collstyle" data-toggle="collapse" data-target="#results-AKV2"><i></i></button></div>
</div>
<div id="results-AKV2" class="results-AKV2 collapse show"></div>
</div>
<div id="aulcontainer" class="resortcontainer">
<div id="aulheader" class="resortheader">
<div class="headertext"><p class="resortnametext">Aulani</p><p class="locationtext">Kapolei, Hawaii</p></div>
<div class="collapseBTN"><span id="count-aul"class="rescount"></span><button class="collstyle" data-toggle="collapse" data-target="#results-AULV"><i></i></button></div>
</div>
<div id="results-AULV" class="results-AULV collapse show"></div>
</div>
<div id="bltcontainer" class="resortcontainer">
<div id="bltheader" class="resortheader">
<div class="headertext"><p class="resortnametext">Bay Lake Tower</p><p class="locationtext">Walt Disney World - Orlando, Florida</p></div>
<div class="collapseBTN"><span id="count-blt"class="rescount"></span><button class="collstyle" data-toggle="collapse" data-target="#results-BLT"><i></i></button></div>
</div>
<div id="results-BLT" class="results-BLT collapse show"></div>
</div>
Any help is appreciated.
I figured it out. I came across this fiddle: http://jsfiddle.net/dv5gtfcw/
That was submitted as the answer here: counting divs inside div
HTML"
<div id="akvjhcontainer" class="resortcontainer">
<div id="akvjhheader" class="resortheader">
<div class="headertext"><p class="resortnametext">Animal Kingdom Villas - Jambo House</p><p class="locationtext">Walt Disney World - Orlando, Florida</p></div>
<div class="collapseBTN"><span class="countDiv0"></span><button class="collstyle" data-toggle="collapse" data-target="#results-AKV"><i></i></button></div>
</div>
<div id="results-AKV" class="results-AKV collapse show resultcontainer"></div>
</div>
<div id="akvkvcontainer" class="resortcontainer">
<div id="akvkvheader" class="resortheader">
<div class="headertext"><p class="resortnametext">Animal Kingdom Villas - Kidani Village</p><p class="locationtext">Walt Disney World - Orlando, Florida</p></div>
<div class="collapseBTN"><span class="countDiv1"></span><button class="collstyle" data-toggle="collapse" data-target="#results-AKV2"><i></i></button></div>
</div>
<div id="results-AKV2" class="results-AKV2 collapse show resultcontainer"></div>
</div>
$('.resultcontainer').each(function(i) {
var n = $(this).children('.roomavailable').length;
$(".countDiv"+i).text(n + " Results");
console.log(n);
});
let searchresult = function(response) {
let resortCodes = new Set();
for (let j = 0; j < response.length; j++) {
resortCodes.add(response[j].resortcode); // add only happens if the resortcode isn't already in resortCodes
let divID = 'results-' + response[j].resortcode;
let container = document.getElementById(divID);
let price = response[j].points.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
if (response[j].available < 1) {
var available = 'soldoutresult';
var status = 'soldout';
var btn = '<button type="button" class="soldout">SOLD OUT</button>';
}
else {
var available = 'availableresult';
var status = 'available';
var btn = '<button type="button" class="booknow">BOOK NOW</button>';
}
container.innerHTML += `
<div class="${available} roomresults room${status}">

pure JS handling if content text length < 0 then hide

I tried to handling,
if content text length < 0
then set class match-name & divider style to display none.
it seem like not working with below code.
var newsMatchName = document.querySelectorAll(".match-name");
var newsMatchNameDivider = document.querySelectorAll(".divider");
for (var i = 0; i < newsMatchName.length; i++) {
if (newsMatchName[i].length < 0) {
console.log(newsMatchName[i].length)
for (var i = 0; i < elem.length; i++) {
newsMatchName[i].style.display = "none";
newsMatchNameDivider[i].style.display = "none"
}
}
}
<div class="news-content">
<div class="match-name"></div>
<div class="divider"></div>
<div class="title">Title Text</div>
<div class="footer">
<span class="author">Author</span>
<span class="spacer"></span>
<div class="timeline">
<span class="date">2021-04-01</span>
<span class="time">12:15</span>
</div>
</div>
</div>
I have corrected the code for you:
var newsMatchName = document.querySelectorAll(".match-name");
var newsMatchNameDivider = document.querySelectorAll(".divider");
for (var i = 0; i < newsMatchName.length; i++) {
if (newsMatchName[i].innerText.length <= 0) {
newsMatchName[i].style.display = "none";
newsMatchNameDivider[i].style.display = "none"
}
}
<div class="news-content">
<div class="match-name"></div>
<div class="divider"></div>
<div class="title">Title Text</div>
<div class="footer">
<span class="author">Author</span>
<span class="spacer"></span>
<div class="timeline">
<span class="date">2021-04-01</span>
<span class="time">12:15</span>
</div>
</div>
</div>
I test the length of the text in match-name
Length can be 0 or more, not <0, so use
newsMatchName[i].textContent.length === 0
but I suggest this:
var newsMatchName = document.querySelectorAll(".match-name");
var newsMatchNameDivider = document.querySelectorAll(".divider");
newsMatchName.forEach((name, i) => {
const textLen = name.textContent.trim().length;
name.classList.toggle("hide", textLen === 0);
newsMatchNameDivider[i].classList.toggle("hide", textLen === 0);
})
.hide {
display: none;
}
<div class="news-content">
<div class="match-name"></div>
<div class="divider">This will be hidden</div>
<div class="title">Title Text</div>
<div class="footer">
<span class="author">Author</span>
<span class="spacer"></span>
<div class="timeline">
<span class="date">2021-04-01</span>
<span class="time">12:15</span>
</div>
</div>
</div>

how to display "No records found" in search operation when no matching records are found

I have a search option where I can search for elements in page, search operation is working but I want to display "No records found" message when it doesn't match any element
And if any item get visible it should hide automatically
function filterFunction() {
var input, filter, ul, li, a, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
div = document.getElementById("myTableDropdown");
a = div.getElementsByTagName("a");
for (i = 0; i < a.length; i++) {
txtValue = a[i].textContent || a[i].innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
a[i].style.display = "";
} else {
a[i].style.display = "none";
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="dropdown"> <i class="fas fa-table btn dropdown-toggle p-0" onclick="lastSaved();" type="button" id="TabledropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></i>
<div id="myTableDropdown" class="dropdown-menu Organization_Desg_table_dropdown" aria-labelledby="TabledropdownMenuButton">
<form>
<label class="d-flex flex-row mb-0" style="padding: 4px 12px;">
<input type="text" placeholder="Search.." id="myInput" data-live-search="true" onkeyup="filterFunction()">
</label>
<hr class="m-0" /> <span id="errmsg"></span>
<a>
Designation Name,
</a>
<a >
Mail Alias,
</a>
<a >
Added By,
</a>
<a >
Added Time,
</a>
<a >
Modified By,
</a>
<a >
Modified Time,
</a>
<hr class="mt-1 mb-2" />
</form>
<div class="d-flex flex-row Organization_Desg_table_item">
<button>save</button>
</div>
</div>
</div>
In your function, you should determine if you have results or not, you could just use a boolean variable; if you have result you clear the text of your errmsg span, else you fill it:
function filterFunction() {
var input, filter, ul, li, a, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
div = document.getElementById("myTableDropdown");
a = div.getElementsByTagName("a");
let noResults = true;
for (i = 0; i < a.length; i++) {
txtValue = a[i].textContent || a[i].innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
noResults = false; // at least one record was found
a[i].style.display = "";
} else {
a[i].style.display = "none";
}
}
document.getElementById("errmsg").innerHTML = noResults ? 'No records found' : '';
}
.error {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="dropdown"> <i class="fas fa-table btn dropdown-toggle p-0" onclick="lastSaved();" type="button" id="TabledropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></i>
<div id="myTableDropdown" class="dropdown-menu Organization_Desg_table_dropdown" aria-labelledby="TabledropdownMenuButton">
<form>
<label class="d-flex flex-row mb-0" style="padding: 4px 12px;">
<input type="text" placeholder="Search.." id="myInput" data-live-search="true" onkeyup="filterFunction()">
</label>
<hr class="m-0" /> <span class="error" id="errmsg"></span>
<a>
Designation Name,
</a>
<a>
Mail Alias,
</a>
<a>
Added By,
</a>
<a>
Added Time,
</a>
<a>
Modified By,
</a>
<a>
Modified Time,
</a>
<hr class="mt-1 mb-2" />
</form>
<div class="d-flex flex-row Organization_Desg_table_item">
<button>save</button>
</div>
</div>
</div>
You can check if all of your anchor tags have style as display:none then you can add "No records found" like below :
function filterFunction() {
var input, filter, ul, li, a, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
div = document.getElementById("myTableDropdown");
a = div.getElementsByTagName("a");
for (i = 0; i < a.length; i++) {
txtValue = a[i].textContent || a[i].innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
a[i].style.display = "";
} else {
a[i].style.display = "none";
}
}
var isNoRecords = true;
for (i = 0; i < a.length; i++) {
if(a[i].style.display != "none") {
isNoRecords = false;
}
}
if (isNoRecords) {
document.getElementById("errmsg").innerHTML = 'No records found';
} else {
document.getElementById("errmsg").innerHTML = '';
}
}

how to prevent adding the same product 2 times in the shopping cart

Can you please tell me what i did wrong in js code ...I'm trying to prevent adding the the same product twice by clicking 'add to cart' button then alert him that this product was already added in the shopping cart
JS code:
function ready() {
//REMOVE THE SHOPPING ITEM FROM THE CART
var removeCartItemButtons = document.getElementsByClassName('btn-danger')
for (var i = 0; i < removeCartItemButtons.length; i++) {
var button = removeCartItemButtons[i]
button.addEventListener('click', removeCartItem)
}
var quantityInputs = document.getElementsByClassName('cart-quantity-input')
for (var i = 0; i < quantityInputs.length; i++) {
var input = quantityInputs[i]
input.addEventListener('change', quantityChanged)
}
var addToCartButtons = document.getElementsByClassName('add-to-cart')
for (var i = 0; i < addToCartButtons.length; i++) {
var button = addToCartButtons[i]
button.addEventListener('click', addToCartClicked)
}
}
function addToCartClicked(event) {
event.preventDefault()
var button = event.target
var shopItem = button.parentElement.parentElement.parentElement.parentElement
var title = shopItem.getElementsByClassName('shop-title')[0].innerText
var price = shopItem.getElementsByClassName('new-price')[0].innerText
var image = shopItem.getElementsByClassName('img')[0].src
addItemToCart(title, price, image)
}
//Add the product to the shopping Cart
function addItemToCart(title, price, image) {
var cartRow = document.createElement('div')
var cartItems = document.getElementsByClassName('cart-items')[0]
var cartItemsNames = cartItems.getElementsByClassName('cart-title')
//prevent the same product to be added twice
for (var i = 0; i < cartItemsNames.length; i++) {
if (cartItemsNames[i].innerText == title) {
alert('error')
return
}
}
var cartRowContents = `
<div class="sin-itme clearfix cart-row">
<i class="mdi mdi-close btn-danger"></i>
<a class="cart-img" href="cart.html"><img src="${image}" alt="" /></a>
<div class="menu-cart-text">
<h5 class="cart-title">${title}</h5>
<span class="product-color">Color : Black</span>
<span class="product-size">Size : SL</span>
<label for="quantity" class="quantity-text">Quantity: </label>
<input type="text" class="cart-quantity-input" name="quantity" type="number" value="1">
<strong class="price">${price}</strong>
</div>
</div>
`
cartRow.innerHTML = cartRowContents
cartItems.append(cartRow)
}
<html>
<head>
<title>shopping cart</title>
</head>
<body>
<div class="cart-items">
<div class="sin-itme clearfix cart-row">
<i class="mdi mdi-close btn-danger"></i>
<a class="cart-img" href="cart.html"><img src="img/cart/2.png" alt="" /></a>
<div class="menu-cart-text">
<h5 class="cart-title">product1</h5>
<label for="quantity" class="quantity-text">Quantity: </label>
<input type="text" class="cart-quantity-input" name="quantity" type="number" value="1">
<strong class="price">$12.00</strong>
</div>
</div>
</div>
<div class="row shop-item">
<div class="col-xs-12 col-md-4">
<div class="list-img">
<div class="product-img">
<div class="pro-type">
<span>new</span>
</div>
<img src="img/products/13.jpg" class="img" alt="Product Title" />
</div>
</div>
</div>
<div class="col-xs-12 col-md-8">
<div class="list-text">
<h3 class="shop-title">product1</h3>
<h5><span class="new-price">$69.30</span><del class="old-price">$79.30</del></h5>
<div class="list-btn">
add to cart
</div>
</div>
</div>
</div>
</body>
</html>
Here is the code what i did...can you please tell me what i did wrong in JS ?...thanks
ready function in code snippet not run,you have to call it at the bottom.
in addToCartClicked function, just use document instead shopItem
function addToCartClicked(event) {
event.preventDefault()
var title = document.getElementsByClassName('shop-title')[0].innerText
var price = document.getElementsByClassName('new-price')[0].innerText
var image = document.getElementsByClassName('img')[0].src
addItemToCart(title, price, image)
}
in addItemToCart function just use document instead cartItems
function addItemToCart(title, price, image) {
var cartRow = document.createElement('div')
var cartItemsNames = document.getElementsByClassName('cart-title')
//prevent the same product to be added twice
for (let i = 0; i < cartItemsNames.length; i++) {
if (cartItemsNames[i].innerText == title) {
alert('error')
return
}
}
// ....
// ....
}
The above changes are just to make your code clearer.
function ready() {
//REMOVE THE SHOPPING ITEM FROM THE CART
var removeCartItemButtons = document.getElementsByClassName('btn-danger')
for (var i = 0; i < removeCartItemButtons.length; i++) {
var button = removeCartItemButtons[i]
// button.addEventListener('click', removeCartItem)
}
var quantityInputs = document.getElementsByClassName('cart-quantity-input')
for (var i = 0; i < quantityInputs.length; i++) {
var input = quantityInputs[i]
// input.addEventListener('change', quantityChanged)
}
var addToCartButtons = document.getElementsByClassName('add-to-cart')
for (var i = 0; i < addToCartButtons.length; i++) {
var button = addToCartButtons[i]
button.addEventListener('click', addToCartClicked)
}
}
function addToCartClicked(event) {
event.preventDefault()
console.log(123)
var title = document.getElementsByClassName('shop-title')[0].innerText
var price = document.getElementsByClassName('new-price')[0].innerText
var image = document.getElementsByClassName('img')[0].src
addItemToCart(title, price, image)
}
//Add the product to the shopping Cart
function addItemToCart(title, price, image) {
var cartRow = document.createElement('div')
var cartItemsNames = document.getElementsByClassName('cart-title')
//prevent the same product to be added twice
for (let i = 0; i < cartItemsNames.length; i++) {
if (cartItemsNames[i].innerText == title) {
alert('error')
return
}
}
var cartRowContents = `
<div class="sin-itme clearfix cart-row">
<i class="mdi mdi-close btn-danger"></i>
<a class="cart-img" href="cart.html"><img src="${image}" alt="" /></a>
<div class="menu-cart-text">
<h5 class="cart-title">${title}</h5>
<span class="product-color">Color : Black</span>
<span class="product-size">Size : SL</span>
<label for="quantity" class="quantity-text">Quantity: </label>
<input type="text" class="cart-quantity-input" name="quantity" type="number" value="1">
<strong class="price">${price}</strong>
</div>
</div>
`
cartRow.innerHTML = cartRowContents
cartItems.append(cartRow)
}
ready()
<html>
<head>
<title>shopping cart</title>
</head>
<body>
<div class="cart-items">
<div class="sin-itme clearfix cart-row">
<i class="mdi mdi-close btn-danger"></i>
<a class="cart-img" href="cart.html"><img src="img/cart/2.png" alt="" /></a>
<div class="menu-cart-text">
<h5 class="cart-title">product1</h5>
<label for="quantity" class="quantity-text">Quantity: </label>
<input type="text" class="cart-quantity-input" name="quantity" type="number" value="1">
<strong class="price">$12.00</strong>
</div>
</div>
</div>
<div class="row shop-item">
<div class="col-xs-12 col-md-4">
<div class="list-img">
<div class="product-img">
<div class="pro-type">
<span>new</span>
</div>
<img src="img/products/13.jpg" class="img" alt="Product Title" />
</div>
</div>
</div>
<div class="col-xs-12 col-md-8">
<div class="list-text">
<h3 class="shop-title">product1</h3>
<h5><span class="new-price">$69.30</span><del class="old-price">$79.30</del></h5>
<div class="list-btn">
add to cart
</div>
</div>
</div>
</div>
</body>
</html>

Removing active class from button

I have 3 buttons that represent a product category on my site. I want to load the page with the "All Products" button having an active class and then have that class removed and added to another button when clicked. There seems to be an issue that is causing an active class to be added twice to a button or not removed and so two buttons will be active at the same time.
Two active buttons at once and Active class added twice
I can fix the problem if I remove the active class from the "All Products" button but again I want the page to load with it set to active. These buttons also have to control the visibility of elements depending on what category they belong to.
Here is my code:
HTML:
<div class="list-group" id="myBtnContainer">
<button class="btn list-group-item active" onclick="filterSelection('all')">All Products</button>
<button class="btn list-group-item" onclick="filterSelection('shirts')">Shirts</button>
<button class="btn list-group-item" onclick="filterSelection('pants')">Pants</button>
</div>
HTML - Example Element:
<div class="col-lg-4 col-md-6 mb-4 filterDiv shirts">
<div class="card h-100 ">
<img class="card-img-top" src="blackshirt.png" alt="">
<div class="card-body">
<h4 class="card-title">
Black Shirt
</h4>
<h5>$24.99</h5>
<p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet numquam aspernatur!</p>
</div>
<div class="card-footer">
<i class="fa fa-search"></i> View Product
</div>
</div>
</div>
JavaScript
filterSelection("all")
function filterSelection(c) {
var x, i;
x = document.getElementsByClassName("filterDiv");
if (c == "all") c = "";
for (i = 0; i < x.length; i++) {
w3RemoveClass(x[i], "show");
if (x[i].className.indexOf(c) > -1) w3AddClass(x[i], "show");
}
}
function w3AddClass(element, name) {
var i, arr1, arr2;
arr1 = element.className.split(" ");
arr2 = name.split(" ");
for (i = 0; i < arr2.length; i++) {
if (arr1.indexOf(arr2[i]) == -1) {element.className += " " + arr2[i];}
}
}
function w3RemoveClass(element, name) {
var i, arr1, arr2;
arr1 = element.className.split(" ");
arr2 = name.split(" ");
for (i = 0; i < arr2.length; i++) {
while (arr1.indexOf(arr2[i]) > -1) {
arr1.splice(arr1.indexOf(arr2[i]), 1);
}
}
element.className = arr1.join(" ");
}
// Add active class to the current button (highlight it)
var btnContainer = document.getElementById("myBtnContainer");
var btns = btnContainer.getElementsByClassName("btn");
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener("click", function(){
var current = document.getElementsByClassName("active");
current[0].className = current[0].className.replace(" active", "");
this.className += " active";
});
}
Two active buttons at once
Check the logic within this function filterSelection.
Active class added twice
You can use toggle function from the classList attribute.
Show products according to the selected button
Use the data attributes and work with the classList attribute.
I.e: Set to your buttons: data-target='shirts', data-target='pants' and so on.
Use a class hide with this style: display: none
var btnContainer = document.getElementById("myBtnContainer");
var btns = btnContainer.getElementsByClassName("btn");
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener("click", function() {
var current = document.getElementsByClassName("active");
current[0].classList.toggle('active');
this.classList.toggle('active');
var target = this.dataset.target;
filterSelection(target);
});
}
function filterSelection(target) {
document.querySelectorAll('.filterDiv').forEach((div) => {
if (target === 'all' || div.classList.contains(target)) {
div.classList.remove('hide');
} else {
div.classList.add('hide');
}
});
}
.active {
background-color: lightgreen;
}
.hide {
display: none
}
<div class="list-group" id="myBtnContainer">
<button class="btn list-group-item active" data-target='all'>Show all</button>
<button class="btn list-group-item" data-target='shirts'>Shirts</button>
<button class="btn list-group-item" data-target='pants'>Pants</button>
</div>
<div class="col-lg-4 col-md-6 mb-4 filterDiv shirts">
<div class="card h-100 ">
<img class="card-img-top" src="blackshirt.png" alt="">
<div class="card-body">
<h4 class="card-title">
Black Shirt
</h4>
<h5>$24.99</h5>
<p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet numquam aspernatur!</p>
</div>
<div class="card-footer">
<i class="fa fa-search"></i> View Product
</div>
</div>
</div>
<div class="col-lg-4 col-md-6 mb-4 filterDiv pants">
<div class="card h-100 ">
<img class="card-img-top" src="blackshirt.png" alt="">
<div class="card-body">
<h4 class="card-title">
Pants
</h4>
<h5>$44.99</h5>
<p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet numquam aspernatur!</p>
</div>
<div class="card-footer">
<i class="fa fa-search"></i> View Product
</div>
</div>
</div>
Resource
Element.classList

Categories

Resources