ITSkillsCenter
Développement Web

Comment créer un système de filtrage en JavaScript

5 دقائق للقراءة

Le filtrage en temps réel : indispensable pour toute liste

Un système de filtrage permet aux utilisateurs de trouver rapidement ce qu’ils cherchent dans une liste de produits, articles, contacts ou tout autre type de données. Dans ce tutoriel, vous construisez un système complet avec recherche textuelle, filtres par catégorie, tri, et mise à jour en temps réel — le tout en JavaScript pur.

Les données

const produits = [
  { id: 1, nom: 'MacBook Pro', catégorie: 'laptop', prix: 850000, stock: true },
  { id: 2, nom: 'iPhone 15', catégorie: 'téléphone', prix: 650000, stock: true },
  { id: 3, nom: 'AirPods Pro', catégorie: 'accessoire', prix: 150000, stock: false },
  { id: 4, nom: 'Galaxy S24', catégorie: 'téléphone', prix: 550000, stock: true },
  { id: 5, nom: 'Dell XPS 15', catégorie: 'laptop', prix: 700000, stock: true },
  { id: 6, nom: 'Clavier Logitech', catégorie: 'accessoire', prix: 35000, stock: true },
  { id: 7, nom: 'ThinkPad X1', catégorie: 'laptop', prix: 900000, stock: false },
  { id: 8, nom: 'Souris MX Master', catégorie: 'accessoire', prix: 45000, stock: true },
  { id: 9, nom: 'iPad Pro', catégorie: 'tablette', prix: 600000, stock: true },
  { id: 10, nom: 'Pixel 8', catégorie: 'téléphone', prix: 450000, stock: true }
];

Le HTML

<div class="filter-app">
  <!-- Barre de recherche -->
  <input type="text" id="searchInput" placeholder="Rechercher un produit...">
  
  <!-- Filtres par catégorie -->
  <div class="filter-buttons" id="categoryFilters">
    <button class="filter-btn activé" data-category="all">Tous</button>
    <button class="filter-btn" data-category="laptop">Laptops</button>
    <button class="filter-btn" data-category="téléphone">Téléphones</button>
    <button class="filter-btn" data-category="tablette">Tablettes</button>
    <button class="filter-btn" data-category="accessoire">Accessoires</button>
  </div>
  
  <!-- Options supplémentaires -->
  <div class="filter-options">
    <label><input type="checkbox" id="stockOnly"> En stock uniquement</label>
    <select id="sortSelect">
      <option value="nom">Trier par nom</option>
      <option value="prix-asc">Prix croissant</option>
      <option value="prix-desc">Prix décroissant</option>
    </select>
  </div>
  
  <!-- Résultats -->
  <p id="resultCount"></p>
  <div id="productGrid" class="product-grid"></div>
</div>

Le JavaScript : moteur de filtrage

// État des filtres
let filters = {
  search: '',
  category: 'all',
  stockOnly: false,
  sort: 'nom'
};

// Éléments DOM
const searchInput = document.getElementById('searchInput');
const categoryBtns = document.querySelectorAll('.filter-btn');
const stockCheckbox = document.getElementById('stockOnly');
const sortSelect = document.getElementById('sortSelect');
const grid = document.getElementById('productGrid');
const countEl = document.getElementById('resultCount');

// Appliquer tous les filtres
function getFilteredProducts() {
  let result = [...produits];
  
  // 1. Filtre texte
  if (filters.search) {
    const query = filters.search.toLowerCase();
    result = result.filter(p => 
      p.nom.toLowerCase().includes(query)
    );
  }
  
  // 2. Filtre catégorie
  if (filters.category !== 'all') {
    result = result.filter(p => p.catégorie === filters.category);
  }
  
  // 3. Filtre stock
  if (filters.stockOnly) {
    result = result.filter(p => p.stock);
  }
  
  // 4. Tri
  result.sort((a, b) => {
    switch (filters.sort) {
      case 'prix-asc': return a.prix - b.prix;
      case 'prix-desc': return b.prix - a.prix;
      default: return a.nom.localeCompare(b.nom);
    }
  });
  
  return result;
}

// Afficher les produits
function render() {
  const filtered = getFilteredProducts();
  
  countEl.textContent = filtered.length + ' produit(s) trouvé(s)';
  
  if (filtered.length === 0) {
    grid.innerHTML = '<p class="no-results">Aucun produit ne correspond à vos critères.</p>';
    return;
  }
  
  grid.innerHTML = filtered.map(p => 
    '<div class="product-card ' + (!p.stock ? 'out-of-stock' : '') + '">' +
      '<h3>' + p.nom + '</h3>' +
      '<span class="category">' + p.catégorie + '</span>' +
      '<p class="price">' + p.prix.toLocaleString('fr-FR') + ' FCFA</p>' +
      '<span class="stock ' + (p.stock ? 'in-stock' : '') + '">' +
        (p.stock ? 'En stock' : 'Rupture') +
      '</span>' +
    '</div>'
  ).join('');
}

// Écouteurs d'événements
searchInput.addEventListener('input', (e) => {
  filters.search = e.target.value;
  render();
});

categoryBtns.forEach(btn => {
  btn.addEventListener('click', () => {
    categoryBtns.forEach(b => b.classList.remove('activé'));
    btn.classList.add('activé');
    filters.category = btn.dataset.category;
    render();
  });
});

stockCheckbox.addEventListener('change', (e) => {
  filters.stockOnly = e.target.checked;
  render();
});

sortSelect.addEventListener('change', (e) => {
  filters.sort = e.target.value;
  render();
});

// Affichage initial
render();

Comment ça fonctionne

Le système suit un pattern simple :

  1. L’utilisateur interagit avec un contrôle (recherche, filtré, tri)
  2. L’état filters est mis à jour
  3. La fonction render() est appelée
  4. getFilteredProducts() applique TOUS les filtres dans l’ordre
  5. Le DOM est mis à jour avec les résultats

Tous les filtres sont cumulatifs : si vous cherchez « Mac » dans la catégorie « laptop » avec « en stock uniquement », les 3 filtres s’appliquent ensemble.

Exercice

  1. Ajoutez un filtré de prix avec un double slider (min/max)
  2. Ajoutez un compteur de filtres actifs sur chaque catégorie
  3. Sauvegardez les filtres dans l’URL (query params) pour que l’utilisateur puisse partager une recherche filtrée
  4. Ajoutez une animation de transition quand les cartes apparaissent/disparaissent
Besoin d'un site web ?

Confiez-nous la Création de Votre Site Web

Site vitrine, e-commerce ou application web — nous transformons votre vision en réalité digitale. Accompagnement personnalisé de A à Z.

À partir de 250.000 FCFA
Parlons de Votre Projet
Publicité