Uikit
Sidebar
Filtre
Catalogue
Off Canvas
Accordeon
Minimaliste
Responsive
Html
Snippet
Sidebar de filtres produits UIkit avec off-canvas mobile, accordéons natifs, checkboxes et design minimaliste pour boutique en ligne.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="copyright" content="AngularForAll" />
<meta name="author" content="AngularForAll" />
<meta name="robots" content="noindex, nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Cache-Control" content="public, max-age=604800" />
<title>Snippets Sidebarfilter Uikit 2026 05011600 | AngularForAll</title>
<!-- UIkit CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.17.11/dist/css/uikit.min.css" />
<!-- Font Awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<style>
/* Améliorations de spacing */
.filter-card .uk-accordion-title {
padding: 16px 20px !important;
font-weight: 600 !important;
font-size: 14px !important;
text-transform: uppercase;
letter-spacing: 0.5px;
background: #fafafa;
border-bottom: 1px solid #e5e5e5;
margin: 0 !important;
}
.filter-card .uk-accordion-title::before {
margin-right: 12px !important;
}
.filter-card .uk-accordion-content {
padding: 20px !important;
margin: 0 !important;
}
.filter-card .uk-accordion > li {
margin: 0 !important;
border: none !important;
}
.filter-card .uk-accordion > li:not(:last-child) {
border-bottom: 1px solid #f0f0f0 !important;
}
/* Catégories */
.filter-card .uk-nav-default > li > a {
padding: 10px 12px !important;
border-radius: 8px;
margin-bottom: 2px;
transition: all 0.2s ease;
}
.filter-card .uk-nav-default > li > a:hover {
background: #f0f0ff !important;
color: #1e87f0 !important;
}
.filter-card .uk-nav-default > li.uk-active > a {
background: #e8f0fe !important;
color: #1e87f0 !important;
font-weight: 600;
}
/* Badge dans catégories */
.filter-card .category-badge {
background: #e5e5e5;
color: #666;
padding: 2px 10px;
border-radius: 20px;
font-size: 12px;
font-weight: 500;
}
.filter-card .uk-active .category-badge {
background: #1e87f0;
color: white;
}
/* Prix */
.price-input-group {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 16px;
}
.price-input-group .uk-input {
flex: 1;
border-radius: 8px;
padding: 8px 12px;
}
.price-separator {
color: #999;
font-weight: 500;
}
.apply-price-btn {
width: 100%;
border-radius: 8px;
padding: 8px 16px;
font-weight: 500;
text-transform: none !important;
}
/* Notes */
.rating-option {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 0;
cursor: pointer;
border-radius: 8px;
transition: all 0.2s ease;
}
.rating-option:hover {
background: #f8f8f8;
}
.rating-option .uk-checkbox {
width: 18px;
height: 18px;
border-radius: 4px;
}
.stars-display {
color: #f59e0b;
font-size: 16px;
letter-spacing: 2px;
}
.stars-label {
color: #666;
font-size: 13px;
}
/* Couleurs */
.colors-container {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.color-circle {
width: 38px;
height: 38px;
border-radius: 50%;
cursor: pointer;
border: 3px solid transparent;
transition: all 0.3s ease;
position: relative;
outline: none;
}
.color-circle:hover {
transform: scale(1.15);
box-shadow: 0 4px 12px rgba(0,0,0,0.2);
}
.color-circle.uk-active {
border-color: #1e87f0;
box-shadow: 0 0 0 3px white, 0 0 0 5px #1e87f0;
}
.color-circle::after {
content: '✓';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
font-size: 14px;
font-weight: bold;
opacity: 0;
transition: opacity 0.2s ease;
text-shadow: 0 1px 2px rgba(0,0,0,0.5);
}
.color-circle.uk-active::after {
opacity: 1;
}
/* Tailles */
.sizes-container {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.size-btn {
min-width: 48px;
height: 40px;
border-radius: 8px;
font-weight: 500;
font-size: 14px;
cursor: pointer;
transition: all 0.2s ease;
border: 2px solid #e5e5e5;
background: white;
color: #333;
display: flex;
align-items: center;
justify-content: center;
}
.size-btn:hover:not(:disabled) {
border-color: #1e87f0;
color: #1e87f0;
background: #f8f8ff;
}
.size-btn.uk-active {
background: #1e87f0;
color: white;
border-color: #1e87f0;
font-weight: 600;
}
.size-btn:disabled {
background: #f5f5f5;
color: #ccc;
cursor: not-allowed;
border-color: #eee;
text-decoration: line-through;
}
/* Marques */
.brand-search-input {
border-radius: 8px;
padding: 8px 12px;
margin-bottom: 12px;
}
.brand-option {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 12px;
cursor: pointer;
border-radius: 8px;
transition: all 0.2s ease;
margin-bottom: 2px;
}
.brand-option:hover {
background: #f8f8f8;
}
.brand-option .uk-checkbox {
width: 18px;
height: 18px;
border-radius: 4px;
}
.brand-option .brand-name {
font-size: 14px;
color: #333;
}
.brand-option .brand-count {
margin-left: auto;
color: #999;
font-size: 12px;
}
/* Tags filtres actifs */
.active-filters-area {
padding: 16px 20px;
background: #f8f8f8;
border-bottom: 1px solid #e5e5e5;
}
.filter-tag {
display: inline-flex;
align-items: center;
gap: 6px;
background: white;
border: 1px solid #ddd;
padding: 5px 12px;
border-radius: 20px;
font-size: 13px;
font-weight: 500;
color: #333;
margin: 3px;
transition: all 0.2s ease;
}
.filter-tag:hover {
border-color: #1e87f0;
background: #f8f8ff;
}
.filter-tag .remove-tag {
cursor: pointer;
color: #999;
font-size: 16px;
line-height: 1;
transition: color 0.2s ease;
}
.filter-tag .remove-tag:hover {
color: #e74c3c;
}
.clear-all-link {
color: #1e87f0;
font-size: 13px;
font-weight: 500;
cursor: pointer;
margin-left: auto;
text-decoration: none;
white-space: nowrap;
}
.clear-all-link:hover {
text-decoration: underline;
}
/* Footer bouton */
.filter-footer {
padding: 16px 20px;
background: white;
border-top: 1px solid #e5e5e5;
}
.apply-all-btn {
width: 100%;
border-radius: 8px;
padding: 10px 20px;
font-weight: 600;
font-size: 15px;
text-transform: none !important;
}
/* Card */
.filter-card {
border-radius: 12px;
overflow: hidden;
box-shadow: 0 2px 15px rgba(0,0,0,0.08);
}
.filter-card .uk-card-header {
padding: 20px;
background: linear-gradient(135deg, #1e87f0, #0f6fd1);
color: white;
border-bottom: none;
}
.filter-card .uk-card-body {
padding: 0;
}
/* Responsive */
@media (max-width: 960px) {
.filter-card {
border-radius: 0;
}
}
/* Loading */
.loading-overlay {
background: rgba(255,255,255,0.9);
backdrop-filter: blur(2px);
border-radius: 12px;
}
/* Scrollbar */
.filter-card .uk-accordion-content::-webkit-scrollbar {
width: 5px;
}
.filter-card .uk-accordion-content::-webkit-scrollbar-thumb {
background: #ddd;
border-radius: 10px;
}
</style>
</head>
<body class="uk-background-muted" style="min-height: 100vh;">
<div class="uk-container uk-container-xlarge uk-padding">
<!-- Mobile Filter Toggle -->
<div class="uk-hidden@m uk-margin-bottom">
<button class="uk-button uk-button-primary uk-width-1-1" type="button" uk-toggle="target: #offcanvas-filter" style="border-radius: 12px; padding: 14px; font-weight: 600;">
<span uk-icon="icon: settings; ratio: 1.3"></span>
Filtres
<span class="uk-badge uk-margin-small-left" id="mobileFilterBadge" style="background: white; color: #1e87f0; font-weight: 600;">3</span>
</button>
</div>
<div class="uk-grid" uk-grid="margin: uk-grid-medium">
<!-- Desktop Sidebar -->
<div class="uk-width-1-4@m uk-visible@m">
<div uk-sticky="offset: 20; bottom: true; media: @m">
<div class="uk-card uk-card-default filter-card">
<!-- Header -->
<div class="uk-card-header uk-flex uk-flex-middle uk-flex-between">
<div>
<h3 class="uk-card-title uk-margin-remove" style="font-size: 1.25rem;">
<span uk-icon="icon: settings; ratio: 1"></span>
Filtres
</h3>
</div>
<button class="uk-button uk-button-text uk-light clear-all-link" id="clearAllUIkit" style="color: rgba(255,255,255,0.9);">
<span uk-icon="icon: close; ratio: 0.8"></span>
Effacer tout
</button>
</div>
<!-- Body -->
<div class="uk-card-body">
<!-- Active Filters -->
<div class="active-filters-area">
<div class="uk-flex uk-flex-middle uk-flex-wrap" style="gap: 6px;">
<span class="uk-text-small uk-text-muted uk-margin-small-right" id="noFiltersLabel">Aucun filtre actif</span>
<div class="uk-flex uk-flex-wrap" id="activeFilterTagsUIkit" style="gap: 6px;"></div>
</div>
</div>
<!-- Filter Accordion -->
<ul uk-accordion="multiple: true" style="margin: 0;">
<!-- 1. Catégories -->
<li class="uk-open">
<a class="uk-accordion-title" href="#">
<span uk-icon="icon: thumbnails; ratio: 0.9"></span>
Catégories
</a>
<div class="uk-accordion-content">
<ul class="uk-nav uk-nav-default" style="margin: 0;">
<li class="uk-active">
<a href="#" data-category="all" class="uk-flex uk-flex-middle uk-flex-between">
<span>Toutes les catégories</span>
<span class="category-badge">120</span>
</a>
</li>
<li>
<a href="#" data-category="electronics" class="uk-flex uk-flex-middle uk-flex-between">
<span>📱 Électronique</span>
<span class="category-badge">34</span>
</a>
</li>
<li>
<a href="#" data-category="clothing" class="uk-flex uk-flex-middle uk-flex-between">
<span>👕 Vêtements</span>
<span class="category-badge">28</span>
</a>
</li>
<li>
<a href="#" data-category="home" class="uk-flex uk-flex-middle uk-flex-between">
<span>🏠 Maison</span>
<span class="category-badge">22</span>
</a>
</li>
<li>
<a href="#" data-category="sports" class="uk-flex uk-flex-middle uk-flex-between">
<span>⚽ Sports</span>
<span class="category-badge">18</span>
</a>
</li>
<li>
<a href="#" data-category="beauty" class="uk-flex uk-flex-middle uk-flex-between">
<span>💄 Beauté</span>
<span class="category-badge">18</span>
</a>
</li>
</ul>
</div>
</li>
<!-- 2. Prix -->
<li class="uk-open">
<a class="uk-accordion-title" href="#">
<span uk-icon="icon: tag; ratio: 0.9"></span>
Fourchette de prix
</a>
<div class="uk-accordion-content">
<form onsubmit="return false;">
<div class="price-input-group">
<input class="uk-input uk-form-medium" type="number" placeholder="Min" id="priceMinUIkit" value="0" style="border-radius: 8px;">
<span class="price-separator">—</span>
<input class="uk-input uk-form-medium" type="number" placeholder="Max" id="priceMaxUIkit" value="1000" style="border-radius: 8px;">
</div>
<button class="uk-button uk-button-primary apply-price-btn" onclick="applyPriceUIkit()">
<span uk-icon="icon: check; ratio: 0.9"></span>
Appliquer le prix
</button>
</form>
</div>
</li>
<!-- 3. Notes -->
<li>
<a class="uk-accordion-title" href="#">
<span uk-icon="icon: star; ratio: 0.9"></span>
Notes minimum
</a>
<div class="uk-accordion-content">
<label class="rating-option">
<input class="uk-checkbox rating-checkbox-uikit" type="checkbox" value="4">
<span class="stars-display">★★★★</span><span style="color: #ddd;">☆</span>
<span class="stars-label">& plus (4.0+)</span>
</label>
<label class="rating-option">
<input class="uk-checkbox rating-checkbox-uikit" type="checkbox" value="3">
<span class="stars-display">★★★</span><span style="color: #ddd;">☆☆</span>
<span class="stars-label">& plus (3.0+)</span>
</label>
<label class="rating-option">
<input class="uk-checkbox rating-checkbox-uikit" type="checkbox" value="2">
<span class="stars-display">★★</span><span style="color: #ddd;">☆☆☆</span>
<span class="stars-label">& plus (2.0+)</span>
</label>
</div>
</li>
<!-- 4. Couleurs -->
<li>
<a class="uk-accordion-title" href="#">
<span uk-icon="icon: paint-bucket; ratio: 0.9"></span>
Couleurs
</a>
<div class="uk-accordion-content">
<div class="colors-container">
<button class="color-circle" data-color="noir" title="Noir" style="background: #1a1a1a;"></button>
<button class="color-circle" data-color="blanc" title="Blanc" style="background: #f5f5f5; border: 2px solid #ddd;"></button>
<button class="color-circle" data-color="rouge" title="Rouge" style="background: #dc2626;"></button>
<button class="color-circle" data-color="bleu" title="Bleu" style="background: #2563eb;"></button>
<button class="color-circle" data-color="vert" title="Vert" style="background: #16a34a;"></button>
<button class="color-circle" data-color="jaune" title="Jaune" style="background: #f59e0b;"></button>
<button class="color-circle" data-color="violet" title="Violet" style="background: #7c3aed;"></button>
<button class="color-circle" data-color="rose" title="Rose" style="background: #ec4899;"></button>
</div>
</div>
</li>
<!-- 5. Tailles -->
<li>
<a class="uk-accordion-title" href="#">
<span uk-icon="icon: ruler; ratio: 0.9"></span>
Tailles
</a>
<div class="uk-accordion-content">
<div class="sizes-container">
<button class="size-btn" data-size="XS">XS</button>
<button class="size-btn" data-size="S">S</button>
<button class="size-btn uk-active" data-size="M">M</button>
<button class="size-btn" data-size="L">L</button>
<button class="size-btn" data-size="XL">XL</button>
<button class="size-btn" data-size="XXL" disabled>XXL</button>
<button class="size-btn" data-size="3XL">3XL</button>
</div>
</div>
</li>
<!-- 6. Marques -->
<li>
<a class="uk-accordion-title" href="#">
<span uk-icon="icon: bookmark; ratio: 0.9"></span>
Marques
</a>
<div class="uk-accordion-content">
<input class="uk-input uk-form-medium brand-search-input" type="text" placeholder="🔍 Rechercher une marque..." oninput="searchBrandsUIkit(this.value)">
<div id="brandListUIkit" style="max-height: 200px; overflow-y: auto;">
<label class="brand-option">
<input class="uk-checkbox brand-checkbox-uikit" type="checkbox" value="apple">
<span class="brand-name">Apple</span>
<span class="brand-count">45</span>
</label>
<label class="brand-option">
<input class="uk-checkbox brand-checkbox-uikit" type="checkbox" value="samsung">
<span class="brand-name">Samsung</span>
<span class="brand-count">38</span>
</label>
<label class="brand-option">
<input class="uk-checkbox brand-checkbox-uikit" type="checkbox" value="nike">
<span class="brand-name">Nike</span>
<span class="brand-count">52</span>
</label>
<label class="brand-option">
<input class="uk-checkbox brand-checkbox-uikit" type="checkbox" value="adidas">
<span class="brand-name">Adidas</span>
<span class="brand-count">41</span>
</label>
<label class="brand-option">
<input class="uk-checkbox brand-checkbox-uikit" type="checkbox" value="sony">
<span class="brand-name">Sony</span>
<span class="brand-count">29</span>
</label>
<label class="brand-option">
<input class="uk-checkbox brand-checkbox-uikit" type="checkbox" value="lg">
<span class="brand-name">LG</span>
<span class="brand-count">22</span>
</label>
<label class="brand-option">
<input class="uk-checkbox brand-checkbox-uikit" type="checkbox" value="huawei">
<span class="brand-name">Huawei</span>
<span class="brand-count">18</span>
</label>
</div>
</div>
</li>
</ul>
</div>
<!-- Footer -->
<div class="filter-footer">
<button class="uk-button uk-button-primary apply-all-btn" id="applyAllUIkit">
<span uk-icon="icon: check; ratio: 1.1"></span>
Appliquer les filtres
</button>
</div>
</div>
</div>
</div>
<!-- Main Content -->
<div class="uk-width-3-4@m uk-width-1-1@s">
<div class="uk-padding-small uk-padding-remove-top">
<div class="uk-flex uk-flex-middle uk-flex-between uk-margin-bottom">
<div>
<h1 class="uk-heading-medium uk-margin-remove-bottom" style="font-size: 2rem;">Nos Produits</h1>
<p class="uk-text-meta uk-margin-remove-top">
<span id="resultsCountUIkit" class="uk-text-bold">120</span> résultats trouvés
</p>
</div>
<div>
<select class="uk-select uk-form-width-medium" style="border-radius: 8px;" id="sortSelect">
<option>Trier par</option>
<option>Prix croissant</option>
<option>Prix décroissant</option>
<option>Nouveautés</option>
<option>Popularité</option>
</select>
</div>
</div>
<!-- Loading -->
<div id="loadingUIkit" class="uk-text-center uk-padding-large loading-overlay" hidden>
<div uk-spinner="ratio: 2.5"></div>
<p class="uk-margin-top uk-text-muted">Chargement des produits...</p>
</div>
<!-- Products Grid Simulation -->
<div class="uk-grid uk-child-width-1-2@s uk-child-width-1-3@l" uk-grid="masonry: true; parallax: 0" id="productsGrid">
<!-- Simulated products would go here -->
</div>
<!-- Empty State -->
<div id="emptyState" class="uk-card uk-card-default uk-card-body uk-text-center uk-padding-large" style="border-radius: 12px;">
<span uk-icon="icon: arrow-left; ratio: 3" class="uk-text-muted"></span>
<h3 class="uk-text-muted uk-margin-top">Utilisez les filtres</h3>
<p class="uk-text-muted">
Sélectionnez vos critères dans la barre latérale pour affiner les résultats.
<br class="uk-visible@m">
Sur mobile, appuyez sur le bouton <strong>Filtres</strong>.
</p>
</div>
</div>
</div>
</div>
</div>
<!-- Mobile Offcanvas (même structure avec spacing) -->
<div id="offcanvas-filter" uk-offcanvas="overlay: true; flip: true">
<div class="uk-offcanvas-bar uk-background-default uk-text-dark" style="width: 340px; padding: 0;">
<div style="padding: 20px; background: linear-gradient(135deg, #1e87f0, #0f6fd1); color: white;">
<button class="uk-offcanvas-close" type="button" uk-close style="color: white;" aria-label="Fermer"></button>
<h3 style="margin: 0; font-size: 1.3rem;">
<span uk-icon="icon: settings; ratio: 1.1"></span>
Filtres
</h3>
</div>
<!-- Active Filters Mobile -->
<div style="padding: 16px 20px; background: #f8f8f8; border-bottom: 1px solid #e5e5e5;">
<div class="uk-flex uk-flex-wrap" style="gap: 6px;" id="activeFilterTagsMobileUIkit"></div>
</div>
<!-- Même accordéon que desktop -->
<ul uk-accordion="multiple: true" style="margin: 0;">
<!-- Mêmes sections que le desktop -->
</ul>
<div style="padding: 16px 20px; border-top: 1px solid #e5e5e5; background: white;">
<button class="uk-button uk-button-primary uk-width-1-1" id="applyMobileUIkit" style="border-radius: 8px; padding: 12px; font-weight: 600;">
<span uk-icon="icon: check; ratio: 1"></span>
Appliquer les filtres
</button>
<button class="uk-button uk-button-default uk-width-1-1 uk-margin-small-top" id="clearAllMobileUIkit" style="border-radius: 8px; padding: 12px; font-weight: 500;">
<span uk-icon="icon: close; ratio: 0.9"></span>
Effacer tout
</button>
</div>
</div>
</div>
<!-- UIkit JS -->
<script src="https://cdn.jsdelivr.net/npm/uikit@3.17.11/dist/js/uikit.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/uikit@3.17.11/dist/js/uikit-icons.min.js"></script>
<script>
// État des filtres
const state = {
categories: ['all'],
priceMin: 0,
priceMax: 1000,
ratings: [],
colors: [],
sizes: ['M'],
brands: []
};
// === GESTION DES CATÉGORIES ===
document.querySelectorAll('[data-category]').forEach(link => {
link.addEventListener('click', function(e) {
e.preventDefault();
const parent = this.closest('ul');
parent.querySelectorAll('li').forEach(li => li.classList.remove('uk-active'));
this.parentElement.classList.add('uk-active');
parent.querySelectorAll('.category-badge').forEach(badge => {
badge.style.background = '#e5e5e5';
badge.style.color = '#666';
});
this.querySelector('.category-badge').style.background = '#1e87f0';
this.querySelector('.category-badge').style.color = 'white';
state.categories = [this.dataset.category];
updateUI();
});
});
// === GESTION DU PRIX ===
function applyPriceUIkit() {
state.priceMin = parseFloat(document.getElementById('priceMinUIkit').value) || 0;
state.priceMax = parseFloat(document.getElementById('priceMaxUIkit').value) || 1000;
// Animation subtile
const btn = document.querySelector('.apply-price-btn');
btn.style.transform = 'scale(0.95)';
setTimeout(() => btn.style.transform = 'scale(1)', 150);
updateUI();
}
// === GESTION DES NOTES ===
document.querySelectorAll('.rating-checkbox-uikit').forEach(cb => {
cb.addEventListener('change', () => {
state.ratings = Array.from(document.querySelectorAll('.rating-checkbox-uikit:checked'))
.map(input => parseInt(input.value));
updateUI();
});
});
// === GESTION DES COULEURS ===
document.querySelectorAll('.color-circle').forEach(btn => {
btn.addEventListener('click', function() {
this.classList.toggle('uk-active');
const color = this.dataset.color;
if (this.classList.contains('uk-active')) {
if (!state.colors.includes(color)) state.colors.push(color);
} else {
state.colors = state.colors.filter(c => c !== color);
}
updateUI();
});
});
// === GESTION DES TAILLES ===
document.querySelectorAll('.size-btn:not([disabled])').forEach(btn => {
btn.addEventListener('click', function() {
const size = this.dataset.size;
if (this.classList.contains('uk-active')) {
this.classList.remove('uk-active');
state.sizes = state.sizes.filter(s => s !== size);
} else {
this.classList.add('uk-active');
if (!state.sizes.includes(size)) state.sizes.push(size);
}
updateUI();
});
});
// === GESTION DES MARQUES ===
document.querySelectorAll('.brand-checkbox-uikit').forEach(cb => {
cb.addEventListener('change', () => {
state.brands = Array.from(document.querySelectorAll('.brand-checkbox-uikit:checked'))
.map(input => input.value);
updateUI();
});
});
function searchBrandsUIkit(query) {
document.querySelectorAll('#brandListUIkit .brand-option').forEach(label => {
const text = label.textContent.toLowerCase();
label.style.display = text.includes(query.toLowerCase()) ? 'flex' : 'none';
});
}
// === MISE À JOUR UI ===
function updateUI() {
updateActiveTags();
updateMobileBadge();
simulateLoading();
}
function updateActiveTags() {
const desktopContainer = document.getElementById('activeFilterTagsUIkit');
const noFiltersLabel = document.getElementById('noFiltersLabel');
let tags = [];
if (state.categories[0] !== 'all') {
tags.push({ label: `Catégorie: ${state.categories[0]}`, clear: () => {
state.categories = ['all'];
document.querySelector('[data-category="all"]').click();
}});
}
if (state.priceMin > 0 || state.priceMax < 1000) {
tags.push({ label: `${state.priceMin}€ - ${state.priceMax}€`, clear: () => {
state.priceMin = 0; state.priceMax = 1000;
document.getElementById('priceMinUIkit').value = 0;
document.getElementById('priceMaxUIkit').value = 1000;
updateUI();
}});
}
state.colors.forEach(color => {
tags.push({ label: `Couleur: ${color}`, clear: () => {
state.colors = state.colors.filter(c => c !== color);
document.querySelector(`.color-circle[data-color="${color}"]`)?.classList.remove('uk-active');
updateUI();
}});
});
state.ratings.forEach(rating => {
tags.push({ label: `${rating}☆ & plus`, clear: () => {
state.ratings = state.ratings.filter(r => r !== rating);
document.querySelector(`.rating-checkbox-uikit[value="${rating}"]`).checked = false;
updateUI();
}});
});
state.sizes.forEach(size => {
tags.push({ label: `Taille: ${size}`, clear: () => {
state.sizes = state.sizes.filter(s => s !== size);
document.querySelector(`.size-btn[data-size="${size}"]`)?.classList.remove('uk-active');
updateUI();
}});
});
state.brands.forEach(brand => {
tags.push({ label: brand, clear: () => {
state.brands = state.brands.filter(b => b !== brand);
document.querySelector(`.brand-checkbox-uikit[value="${brand}"]`).checked = false;
updateUI();
}});
});
if (tags.length === 0) {
noFiltersLabel.style.display = 'inline';
desktopContainer.innerHTML = '';
} else {
noFiltersLabel.style.display = 'none';
desktopContainer.innerHTML = tags.map((tag, i) => `
<span class="filter-tag">
${tag.label}
<span class="remove-tag" data-index="${i}">×</span>
</span>
`).join('');
desktopContainer.querySelectorAll('.remove-tag').forEach((btn, i) => {
btn.addEventListener('click', (e) => {
e.stopPropagation();
tags[i].clear();
});
});
}
}
function updateMobileBadge() {
const count =
(state.categories[0] !== 'all' ? 1 : 0) +
(state.priceMin > 0 || state.priceMax < 1000 ? 1 : 0) +
state.ratings.length +
state.colors.length +
(state.sizes.length > 0 ? 1 : 0) +
state.brands.length;
document.getElementById('mobileFilterBadge').textContent = count || '0';
}
function simulateLoading() {
const spinner = document.getElementById('loadingUIkit');
const emptyState = document.getElementById('emptyState');
spinner.hidden = false;
setTimeout(() => {
spinner.hidden = true;
const count = Math.floor(Math.random() * 50) + 10;
document.getElementById('resultsCountUIkit').textContent = count;
}, 400);
}
// === BOUTONS APPLIQUER ===
document.getElementById('applyAllUIkit').addEventListener('click', () => {
simulateLoading();
UIkit.notification({
message: '<span uk-icon="icon: check"></span> Filtres appliqués avec succès !',
status: 'success',
pos: 'top-right',
timeout: 3000
});
});
document.getElementById('applyMobileUIkit')?.addEventListener('click', () => {
simulateLoading();
UIkit.offcanvas('#offcanvas-filter').hide();
UIkit.notification({
message: '<span uk-icon="icon: check"></span> Filtres appliqués !',
status: 'success',
pos: 'top-right',
timeout: 3000
});
});
// === EFFACER TOUT ===
document.getElementById('clearAllUIkit').addEventListener('click', resetAllFilters);
document.getElementById('clearAllMobileUIkit')?.addEventListener('click', () => {
resetAllFilters();
UIkit.offcanvas('#offcanvas-filter').hide();
});
function resetAllFilters() {
state.categories = ['all'];
state.priceMin = 0;
state.priceMax = 1000;
state.ratings = [];
state.colors = [];
state.sizes = ['M'];
state.brands = [];
// Reset UI
document.querySelectorAll('.uk-nav li').forEach(li => li.classList.remove('uk-active'));
document.querySelector('.uk-nav li:first-child').classList.add('uk-active');
document.querySelectorAll('.category-badge').forEach(badge => {
badge.style.background = '#e5e5e5';
badge.style.color = '#666';
});
document.querySelector('.uk-active .category-badge').style.background = '#1e87f0';
document.querySelector('.uk-active .category-badge').style.color = 'white';
document.getElementById('priceMinUIkit').value = 0;
document.getElementById('priceMaxUIkit').value = 1000;
document.querySelectorAll('.rating-checkbox-uikit').forEach(cb => cb.checked = false);
document.querySelectorAll('.color-circle').forEach(btn => btn.classList.remove('uk-active'));
document.querySelectorAll('.size-btn').forEach(btn => {
if (btn.dataset.size === 'M') btn.classList.add('uk-active');
else btn.classList.remove('uk-active');
});
document.querySelectorAll('.brand-checkbox-uikit').forEach(cb => cb.checked = false);
updateUI();
}
// === INITIALISATION ===
updateUI();
// Support clavier
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
const offcanvas = UIkit.offcanvas('#offcanvas-filter');
if (offcanvas) offcanvas.hide();
}
});
</script>
</body>
</html>
Télécharger le fichier source