I’m having an issue with my sidebars. I have two sidebars – one for filters and the other for the cart. When I open the cart sidebar, it automatically closes the filters sidebar. However, when I open the filters sidebar again, the cart sidebar stays open. How can I modify my JavaScript code to close one sidebar when the other is open? I have one sidebar <div id="mySidebar" class="sidebar">
and other is <div class="cart">
I also have a script in html code for closing navbar
<script>
function openNav() {
document.getElementById("mySidebar").style.width = "250px";
}
function closeNav() {
document.getElementById("mySidebar").style.width = "0";
}
</script>
let iconCart = document.querySelector('.iconCart');
let cart = document.querySelector('.cart');
let container = document.querySelector('.container');
let close = document.querySelector('.close');
let sidebarFilters = document.getElementById('mySidebar');
iconCart.addEventListener('click', function() {
if (cart.style.right == '-100%') {
cart.style.right = '0';
container.style.transform = 'translateX(-400px)';
closeSidebar(sidebarFilters);
} else {
cart.style.right = '-100%';
container.style.transform = 'translateX(0)';
}
});
close.addEventListener('click', function() {
cart.style.right = '-100%';
container.style.transform = 'translateX(0)';
});
function closeSidebar(sidebar) {
sidebar.style.width = "0";
}
let products = null;
// Fetch data from JSON file
fetch('product.json')
.then(response => response.json())
.then(data => {
products = data;
addDataToHTML(products);
addDataToHTML1(products);
setupFilters(products);
setupSearch(products); // Setup search functionality
});
// Show product data in the list
function addDataToHTML(products) {
let listProductHTML = document.querySelector('.listProduct');
listProductHTML.innerHTML = '';
if (products != null) {
products.forEach(product => {
let newProduct = document.createElement('div');
newProduct.classList.add('item');
newProduct.innerHTML =
`<img src="${product.image}" alt="">
<h2>${product.name}</h2>
<div class="price">${product.price}rsd</div>
<a style="cursor: pointer" onclick="redirectToDetailsPage(${product.id})">View Details</a><br>
<button onclick="addCart(${product.id})">
<span class="spann">Add to cart</span>
<div class="cartt">
<svg viewBox="0 0 36 26">
<polyline points="1 2.5 6 2.5 10 18.5 25.5 18.5 28.5 7.5 7.5 7.5"></polyline>
<polyline points="15 13.5 17 15.5 22 10.5"></polyline>
</svg>
</div>
</button>`;
listProductHTML.appendChild(newProduct);
// Add event listener for the rotation animation
let button = newProduct.querySelector('button');
button.addEventListener('click', function() {
button.classList.add('loading');
// Remove the class after animation to allow re-triggering the animation on next click
button.addEventListener('animationend', () => {
button.classList.remove('loading');
}, { once: true });
});
});
}
}
function addDataToHTML1(products) {
let klimaProductHTML = document.querySelector('.klimaProduct');
let pumpaProductHTML = document.querySelector('.pumpaProduct');
let televizorProductHTML = document.querySelector('.televizorProduct');
if (klimaProductHTML) klimaProductHTML.innerHTML = '';
if (pumpaProductHTML) pumpaProductHTML.innerHTML = '';
if (televizorProductHTML) televizorProductHTML.innerHTML = '';
if (products != null) {
products.forEach(product => {
let newProduct = document.createElement('div');
newProduct.classList.add('item');
newProduct.innerHTML =
`<img src="${product.image}" alt="">
<h2>${product.name}</h2>
<div class="price">${product.price}rsd</div>
<a style="cursor: pointer" onclick="redirectToDetailsPage(${product.id})">View Details</a><br>
<button onclick="addCart(${product.id})">
<span class="spann">Add to cart</span>
<div class="cartt">
<svg viewBox="0 0 36 26">
<polyline points="1 2.5 6 2.5 10 18.5 25.5 18.5 28.5 7.5 7.5 7.5"></polyline>
<polyline points="15 13.5 17 15.5 22 10.5"></polyline>
</svg>
</div>
</button>`;
switch (product.category) {
case 'klima':
if (klimaProductHTML) klimaProductHTML.appendChild(newProduct);
break;
case 'pumpa':
if (pumpaProductHTML) pumpaProductHTML.appendChild(newProduct);
break;
case 'televizor':
if (televizorProductHTML) televizorProductHTML.appendChild(newProduct);
break;
}
// Add event listener for the rotation animation
let button = newProduct.querySelector('button');
button.addEventListener('click', function() {
button.classList.add('loading');
// Remove the class after animation to allow re-triggering the animation on next click
button.addEventListener('animationend', () => {
button.classList.remove('loading');
}, { once: true });
});
});
}
}
function redirectToDetailsPage(productId) {
window.location.href = `details.html?id=${productId}`;
}
// Use cookie so the cart doesn't get lost on refresh page
let listCart = [];
function checkCart() {
var cookieValue = document.cookie
.split('; ')
.find(row => row.startsWith('listCart='));
if (cookieValue) {
listCart = JSON.parse(cookieValue.split('=')[1]);
} else {
listCart = [];
}
}
checkCart();
function addCart($idProduct) {
let productsCopy = JSON.parse(JSON.stringify(products));
if (!listCart[$idProduct]) {
listCart[$idProduct] = productsCopy.filter(product => product.id == $idProduct)[0];
listCart[$idProduct].quantity = 1;
} else {
listCart[$idProduct].quantity++;
}
document.cookie = "listCart=" + JSON.stringify(listCart) + "; expires=Thu, 31 Dec 2025 23:59:59 UTC; path=/;";
addCartToHTML();
}
addCartToHTML();
function addCartToHTML() {
let listCartHTML = document.querySelector('.listCart');
listCartHTML.innerHTML = '';
let totalHTML = document.querySelector('.totalQuantity');
let totalQuantity = 0;
if (listCart) {
listCart.forEach(product => {
if (product) {
let newCart = document.createElement('div');
newCart.classList.add('item');
newCart.innerHTML =
`<img src="${product.image}">
<div class="content">
<div class="name">${product.name}</div>
<div class="price">${product.price}rsd / 1 product</div>
</div>
<div class="quantity">
<button onclick="changeQuantity(${product.id}, '-')">-</button>
<span class="value">${product.quantity}</span>
<button onclick="changeQuantity(${product.id}, '+')">+</button>
</div>`;
listCartHTML.appendChild(newCart);
totalQuantity = totalQuantity + product.quantity;
}
});
}
totalHTML.innerText = totalQuantity;
}
function changeQuantity($idProduct, $type) {
switch ($type) {
case '+':
listCart[$idProduct].quantity++;
break;
case '-':
listCart[$idProduct].quantity--;
if (listCart[$idProduct].quantity <= 0) {
delete listCart[$idProduct];
}
break;
default:
break;
}
document.cookie = "listCart=" + JSON.stringify(listCart) + "; expires=Thu, 31 Dec 2025 23:59:59 UTC; path=/;";
addCartToHTML();
}
// Function to set up filters
function setupFilters(products) {
const categoryCheckboxes = document.querySelectorAll('input[type="checkbox"][id^="category-"]');
const sizeCheckboxes = document.querySelectorAll('input[type="checkbox"][id^="size-"]');
const colorCheckboxes = document.querySelectorAll('input[type="checkbox"][id^="color-"]');
function applyFilters() {
const selectedCategories = Array.from(categoryCheckboxes)
.filter(checkbox => checkbox.checked)
.map(checkbox => checkbox.value);
const selectedSizes = Array.from(sizeCheckboxes)
.filter(checkbox => checkbox.checked)
.map(checkbox => checkbox.value);
const selectedColors = Array.from(colorCheckboxes)
.filter(checkbox => checkbox.checked)
.map(checkbox => checkbox.value);
const filteredProducts = products.filter(product => {
const categoryMatch = selectedCategories.length === 0 || selectedCategories.includes(product.category);
const sizeMatch = selectedSizes.length === 0 || selectedSizes.includes(product.size);
const colorMatch = selectedColors.length === 0 || selectedColors.includes(product.color);
return categoryMatch && sizeMatch && colorMatch;
});
addDataToHTML(filteredProducts);
addDataToHTML1(filteredProducts);
}
categoryCheckboxes.forEach(checkbox => {
checkbox.addEventListener("change", applyFilters);
});
sizeCheckboxes.forEach(checkbox => {
checkbox.addEventListener("change", applyFilters);
});
colorCheckboxes.forEach(checkbox => {
checkbox.addEventListener("change", applyFilters);
});
}
// Function to set up search
document.addEventListener("DOMContentLoaded", function() {
// Funkcija za pretragu
function searchProducts() {
var input = document.getElementById("search-bar");
var filter = input.value.toLowerCase();
var products = document.querySelectorAll('.klimaProduct .item, .listProduct .item');
products.forEach(function(product) {
var productName = product.querySelector('h2').innerText.toLowerCase();
if (productName.indexOf(filter) > -1) {
product.style.display = "";
} else {
product.style.display = "none";
}
});
}
// Dodavanje event listener-a na click događaj za dugme pretrage
document.getElementById("search-btn").addEventListener("click", function(event) {
event.preventDefault(); // Da bismo sprečili podrazumevanu akciju dugmeta
searchProducts(); // Pozivamo funkciju za pretragu kada se klikne na dugme
});
// Onemogućavanje podrazumevane akcije pritiska tastera prilikom unosa u polje za pretragu
document.getElementById("search-bar").addEventListener("keydown", function(event) {
if (event.key === 'Enter') {
event.preventDefault(); // Da bismo sprečili podrazumevanu akciju pritiska tastera Enter
searchProducts(); // Pozivamo funkciju za pretragu kada se pritisne taster Enter
}
});
});
//animacija za search
document.addEventListener('DOMContentLoaded', function() {
const searchButton = document.getElementById('search-button');
const searchInput = document.getElementById('search-bar');
searchButton.addEventListener('click', searchProducts);
searchInput.addEventListener('keypress', function(event) {
if (event.key === 'Enter') {
event.preventDefault();
searchProducts();
}
});
const observerOptions = {
root: null, // koristi viewport kao root
rootMargin: '0px',
threshold: 0.1 // 10% elementa treba biti vidljivo
};
const observer = new IntersectionObserver(handleIntersect, observerOptions);
function handleIntersect(entries, observer) {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
entry.target.classList.remove('fade-up');
} else {
entry.target.classList.remove('visible');
entry.target.classList.add('fade-up');
}
});
}
function searchProducts() {
const searchQuery = document.getElementById('search-bar').value.toLowerCase();
const allProducts = document.querySelectorAll('.listProduct .item, .klimaProduct .item, .pumpaProduct .item, .televizorProduct .item');
allProducts.forEach(product => {
const productName = product.textContent.toLowerCase();
if (productName.includes(searchQuery)) {
product.classList.remove('hidden');
product.classList.add('fade-up');
if (!product.classList.contains('visible')) {
observer.observe(product); // Dodaj proizvod u observer samo ako nije već vidljiv
}
} else {
product.classList.remove('visible');
product.classList.add('hidden');
observer.unobserve(product); // Ukloni proizvod iz observer-a
}
});
}
// Inicijalno dodaj sve proizvode u observer
const allProducts = document.querySelectorAll('.listProduct .item, .klimaProduct .item, .pumpaProduct .item, .televizorProduct .item');
allProducts.forEach(product => {
if (!product.classList.contains('visible')) {
observer.observe(product);
}
});
});
2
Answers
Great, now it works if one is open to closing the other one. Now it doesn't work with the X button; when I click it, it doesn't close the sidebar because we changed and deleted the function for the closenav. When I insert it, the code broke.
Using the same logic, when opening the sidebar, close the cart (I’m trying to re-use the code for closing the cart with a function called
closeCart
)