Project HTML CSS JavaScript: Product Filter dan Search

Project HTML CSS JavaScript: Product Filter dan Search

Project HTML CSS JavaScript: Product Filter dan Search (Lengkap dengan Code & Gambar Online)

Membuat sistem filter dan pencarian produk adalah komponen penting untuk e-commerce atau website katalog produk. Dalam panduan ini, kita akan membangun:

✅ Tampilan produk dengan gambar online
✅ Fitur pencarian real-time
✅ Filter berdasarkan kategori & harga
✅ Tampilan responsive
✅ Animasi interaktif

Kita akan menggunakan API dummy untuk gambar produk agar tidak perlu mendownload gambar secara manual.

Struktur Proyek

/product-filter  
│── index.html  
│── style.css  
│── script.js

1. File HTML (index.html)

html
<!DOCTYPE html>
<html lang="id">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Filter & Pencarian Produk - Azroi</title>
    <link rel="stylesheet" href="style.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
</head>
<body>
    <div class="container">
        <header>
            <h1><i class="fas fa-filter"></i> Filter Produk</h1>
            <div class="search-container">
                <input type="text" id="searchInput" placeholder="Cari produk...">
                <i class="fas fa-search"></i>
            </div>
        </header>

        <div class="filter-container">
            <div class="filter-section">
                <h3>Kategori</h3>
                <div class="filter-options">
                    <label><input type="checkbox" name="category" value="elektronik" checked> Elektronik</label>
                    <label><input type="checkbox" name="category" value="fashion"> Fashion</label>
                    <label><input type="checkbox" name="category" value="makanan"> Makanan</label>
                    <label><input type="checkbox" name="category" value="perabotan"> Perabotan</label>
                </div>
            </div>

            <div class="filter-section">
                <h3>Harga</h3>
                <div class="price-range">
                    <input type="range" id="priceRange" min="0" max="5000000" value="5000000">
                    <span id="priceValue">Rp 5.000.000+</span>
                </div>
            </div>

            <button id="resetFilters">Reset Filter</button>
        </div>

        <main class="products-container" id="productsContainer">
            <!-- Produk akan dimuat via JavaScript -->
        </main>

        <footer>
            <p>© 2025 Product Filter | Azroi</p>
        </footer>
    </div>

    <script src="script.js"></script>
</body>
</html>

2. File CSS (style.css)

css
/* Reset & Base Styles */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

body {
    background-color: #f5f5f7;
    color: #333;
    line-height: 1.6;
}

.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 20px;
}

/* Header Styles */
header {
    text-align: center;
    margin-bottom: 30px;
    padding: 20px;
    background: white;
    border-radius: 10px;
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
}

header h1 {
    font-size: 2rem;
    margin-bottom: 15px;
    color: #2c3e50;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
}

.search-container {
    position: relative;
    max-width: 500px;
    margin: 0 auto;
}

.search-container input {
    width: 100%;
    padding: 12px 20px;
    padding-left: 45px;
    border: 1px solid #ddd;
    border-radius: 50px;
    font-size: 1rem;
    outline: none;
    transition: all 0.3s;
}

.search-container input:focus {
    border-color: #3498db;
    box-shadow: 0 0 10px rgba(52, 152, 219, 0.2);
}

.search-container i {
    position: absolute;
    left: 15px;
    top: 50%;
    transform: translateY(-50%);
    color: #7f8c8d;
}

/* Filter Container */
.filter-container {
    background: white;
    padding: 20px;
    border-radius: 10px;
    margin-bottom: 30px;
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
}

.filter-section {
    margin-bottom: 20px;
}

.filter-section h3 {
    margin-bottom: 15px;
    color: #2c3e50;
    font-size: 1.1rem;
}

.filter-options {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 10px;
}

.filter-options label {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    padding: 8px;
    border-radius: 5px;
    transition: background 0.3s;
}

.filter-options label:hover {
    background: #f1f1f1;
}

.price-range {
    padding: 0 10px;
}

.price-range input[type="range"] {
    width: 100%;
    margin: 15px 0;
    -webkit-appearance: none;
    height: 8px;
    border-radius: 5px;
    background: #ddd;
    outline: none;
}

.price-range input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: #3498db;
    cursor: pointer;
}

#priceValue {
    display: block;
    text-align: center;
    font-weight: bold;
    color: #3498db;
}

#resetFilters {
    background: #e74c3c;
    color: white;
    border: none;
    padding: 10px 20px;
    border-radius: 5px;
    cursor: pointer;
    font-weight: 500;
    transition: all 0.3s;
    display: block;
    margin: 20px auto 0;
}

#resetFilters:hover {
    background: #c0392b;
    transform: translateY(-2px);
}

/* Products Container */
.products-container {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 25px;
}

.product-card {
    background: white;
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
    transition: all 0.3s;
}

.product-card:hover {
    transform: translateY(-5px);
    box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
}

.product-image {
    width: 100%;
    height: 200px;
    object-fit: cover;
}

.product-info {
    padding: 15px;
}

.product-title {
    font-size: 1.1rem;
    margin-bottom: 8px;
    color: #2c3e50;
    font-weight: 600;
}

.product-category {
    display: inline-block;
    background: #ecf0f1;
    color: #7f8c8d;
    padding: 3px 8px;
    border-radius: 5px;
    font-size: 0.8rem;
    margin-bottom: 10px;
}

.product-price {
    font-size: 1.2rem;
    font-weight: 700;
    color: #27ae60;
}

.no-products {
    grid-column: 1 / -1;
    text-align: center;
    padding: 50px;
    color: #7f8c8d;
}

/* Footer */
footer {
    text-align: center;
    margin-top: 50px;
    padding: 20px;
    color: #7f8c8d;
    font-size: 0.9rem;
}

footer a {
    color: #3498db;
    text-decoration: none;
}

/* Responsive Design */
@media (max-width: 768px) {
    .products-container {
        grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    }
}

@media (max-width: 480px) {
    .filter-options {
        grid-template-columns: 1fr 1fr;
    }
    
    .products-container {
        grid-template-columns: 1fr;
    }
}

/* Animations */
@keyframes fadeIn {
    from { opacity: 0; transform: translateY(20px); }
    to { opacity: 1; transform: translateY(0); }
}

.product-card {
    animation: fadeIn 0.5s ease forwards;
    opacity: 0;
}

.product-card:nth-child(1) { animation-delay: 0.1s; }
.product-card:nth-child(2) { animation-delay: 0.2s; }
.product-card:nth-child(3) { animation-delay: 0.3s; }
.product-card:nth-child(4) { animation-delay: 0.4s; }
.product-card:nth-child(5) { animation-delay: 0.5s; }
.product-card:nth-child(6) { animation-delay: 0.6s; }

3. File JavaScript (script.js)

javascript
document.addEventListener('DOMContentLoaded', function() {
    // DOM Elements
    const productsContainer = document.getElementById('productsContainer');
    const searchInput = document.getElementById('searchInput');
    const categoryCheckboxes = document.querySelectorAll('input[name="category"]');
    const priceRange = document.getElementById('priceRange');
    const priceValue = document.getElementById('priceValue');
    const resetBtn = document.getElementById('resetFilters');

    // Product Data (dengan gambar online dari Lorem Picsum)
    const products = [
        {
            id: 1,
            title: "Smartphone X",
            category: "elektronik",
            price: 4999000,
            image: "https://picsum.photos/id/20/500/300"
        },
        {
            id: 2,
            title: "Laptop Pro",
            category: "elektronik",
            price: 12999000,
            image: "https://picsum.photos/id/48/500/300"
        },
        {
            id: 3,
            title: "Kemeja Flanel",
            category: "fashion",
            price: 299000,
            image: "https://picsum.photos/id/21/500/300"
        },
        {
            id: 4,
            title: "Sepatu Sneakers",
            category: "fashion",
            price: 599000,
            image: "https://picsum.photos/id/203/500/300"
        },
        {
            id: 5,
            title: "Kopi Premium",
            category: "makanan",
            price: 99000,
            image: "https://picsum.photos/id/30/500/300"
        },
        {
            id: 6,
            title: "Coklat Belgia",
            category: "makanan",
            price: 129000,
            image: "https://picsum.photos/id/312/500/300"
        },
        {
            id: 7,
            title: "Meja Kerja",
            category: "perabotan",
            price: 1499000,
            image: "https://picsum.photos/id/31/500/300"
        },
        {
            id: 8,
            title: "Kursi Ergonomis",
            category: "perabotan",
            price: 899000,
            image: "https://picsum.photos/id/33/500/300"
        }
    ];

    // Initialize
    displayProducts(products);
    setupEventListeners();

    // Functions
    function displayProducts(productsToDisplay) {
        productsContainer.innerHTML = '';

        if (productsToDisplay.length === 0) {
            productsContainer.innerHTML = `
                <div class="no-products">
                    <i class="fas fa-search" style="font-size: 3rem; margin-bottom: 15px;"></i>
                    <h3>Tidak ada produk yang sesuai</h3>
                    <p>Coba ubah filter pencarian Anda</p>
                </div>
            `;
            return;
        }

        productsToDisplay.forEach(product => {
            const productCard = document.createElement('div');
            productCard.className = 'product-card';
            productCard.innerHTML = `
                <img src="${product.image}" alt="${product.title}" class="product-image">
                <div class="product-info">
                    <h3 class="product-title">${product.title}</h3>
                    <span class="product-category">${product.category}</span>
                    <p class="product-price">Rp ${product.price.toLocaleString('id-ID')}</p>
                </div>
            `;
            productsContainer.appendChild(productCard);
        });
    }

    function filterProducts() {
        const searchTerm = searchInput.value.toLowerCase();
        const selectedCategories = Array.from(categoryCheckboxes)
            .filter(checkbox => checkbox.checked)
            .map(checkbox => checkbox.value);
        const maxPrice = parseInt(priceRange.value);

        const filteredProducts = products.filter(product => {
            // Filter by search term
            const matchesSearch = product.title.toLowerCase().includes(searchTerm);
            
            // Filter by category
            const matchesCategory = selectedCategories.length === 0 || 
                                  selectedCategories.includes(product.category);
            
            // Filter by price
            const matchesPrice = product.price <= maxPrice;
            
            return matchesSearch && matchesCategory && matchesPrice;
        });

        displayProducts(filteredProducts);
    }

    function setupEventListeners() {
        // Search input
        searchInput.addEventListener('input', filterProducts);
        
        // Category checkboxes
        categoryCheckboxes.forEach(checkbox => {
            checkbox.addEventListener('change', filterProducts);
        });
        
        // Price range
        priceRange.addEventListener('input', function() {
            const value = parseInt(this.value);
            priceValue.textContent = value === 5000000 ? 
                'Rp 5.000.000+' : 
                `Rp ${value.toLocaleString('id-ID')}`;
            filterProducts();
        });
        
        // Reset button
        resetBtn.addEventListener('click', function() {
            searchInput.value = '';
            categoryCheckboxes.forEach(checkbox => {
                checkbox.checked = true;
            });
            priceRange.value = 5000000;
            priceValue.textContent = 'Rp 5.000.000+';
            filterProducts();
        });
    }
});

Cara Menggunakan

  1. Buka file index.html di browser

  2. Gunakan fitur:

    • 🔍 Kotak pencarian untuk cari produk

    • ✔️ Centang kategori untuk filter

    • 💰 Geser slider untuk filter harga

    • 🔄 Tombol reset untuk menghapus semua filter


 

Kesimpulan

  1. Pencarian Real-time

    • Cari produk berdasarkan kata kunci

    • Pencarian langsung saat mengetik

  2. Filter Multi-Kategori

    • Pilih satu atau beberapa kategori sekaligus

    • Elektronik, Fashion, Makanan, Perabotan

  3. Filter Harga

    • Slider range harga

    • Tampilan nilai harga yang user-friendly

  4. Tampilan Produk

    • Grid layout responsif

    • Animasi saat muncul

    • Gambar produk dari API online

  5. Reset Filter

    • Tombol reset untuk mengembalikan semua filter

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *