Objek Konfigurasi menggunakan Javascript untuk menampilkan data di HTML
Panduan Implementasi Banyak Objek Konfigurasi di JS
Saat membuat proyek web yang semakin besar, kita sering ingin memisahkan konfigurasi berdasarkan bagian (section), misalnya HERO_CONFIG dan FOOTER_CONFIG.
Ada dua pendekatan utama yang bisa Anda gunakan:
๐ Cara 1: Menggabungkan dalam Satu Objek Induk (Sangat Direkomendasikan)
Daripada membuat banyak variabel global terpisah, cara paling rapi adalah membuat satu Objek Induk (Parent Object) yang di dalamnya memiliki sub-objek untuk hero dan footer.
Kode JavaScript:
const SITE_CONFIG = {
// Objek Khusus Hero
hero: {
title: "Selamat Datang di Portal Kami",
subtitle: "Solusi Digital Terbaik untuk Bisnis Anda",
ctaText: "Mulai Sekarang"
},
// Objek Khusus Footer
footer: {
copyright: "2026 Toko Digital. All rights reserved.",
email: "support@tokodigital.com",
address: "Jakarta, Indonesia"
}
};
HTML & Script Render (Pakai Titik / Dot Notation):
<!-- Bagian Hero -->
<section>
<h1 data-config="hero.title"></h1>
<p data-config="hero.subtitle"></p>
<button data-config="hero.ctaText"></button>
</section>
<!-- Bagian Footer -->
<footer>
<p data-config="footer.copyright"></p>
<p>Email: <span data-config="footer.email"></span></p>
</footer>
<script>
function renderConfig() {
document.querySelectorAll('[data-config]').forEach(el => {
const path = el.getAttribute('data-config'); // contoh: "hero.title" atau "footer.copyright"
// Membaca path bertingkat seperti hero.title
const value = path.split('.').reduce((obj, key) => obj && obj[key], SITE_CONFIG);
if (value !== undefined) {
el.textContent = value;
}
});
}
document.addEventListener('DOMContentLoaded', renderConfig);
</script>
๐ Cara 2: Membuat Dua Objek Terpisah Lalu Menggabungkannya
Jika Anda benar-benar ingin memisahkan file atau variabelnya secara independen (misal HERO_CONFIG dan FOOTER_CONFIG berada di file .js terpisah), Anda bisa menggabungkannya di JavaScript menggunakan Spread Operator (...).
Kode JavaScript:
// File 1: hero-config.js
const HERO_CONFIG = {
title: "Promo Spesial Tahun Ini",
badge: "Diskon 50%"
};
// File 2: footer-config.js
const FOOTER_CONFIG = {
phone: "081234567890",
address: "Jl. Sudirman No. 10"
};
// Gabungkan keduanya menjadi satu objek utama
const MAIN_CONFIG = {
hero: HERO_CONFIG,
footer: FOOTER_CONFIG
};
๐งช Contoh Lengkap Siap Jalankan (HTML + JS)
Silakan copy-paste kode di bawah ini ke file .html Anda untuk melihat hasilnya secara langsung:
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<title>Latihan Multi Config JS</title>
<style>
body { font-family: Arial, sans-serif; margin: 0; padding: 0; }
.hero { background: #1e293b; color: white; padding: 40px; text-align: center; }
.footer { background: #0f172a; color: #94a3b8; padding: 20px; text-align: center; font-size: 14px; }
</style>
</head>
<body>
<!-- 1. SECTION HERO -->
<header class="hero">
<h1 data-config="hero.title"></h1>
<p data-config="hero.description"></p>
</header>
<!-- 2. SECTION FOOTER -->
<footer class="footer">
<p data-config="footer.copyright"></p> <p>Kontak: <span data-config="footer.email"></span> | <span data-config="footer.phone"></span></p>
</footer>
<script>
// Objek 1: Khusus Hero
const HERO_CONFIG = {
title: "Hero Banner Utama",
description: "Ini adalah deskripsi singkat dari objek HERO_CONFIG."
};
// Objek 2: Khusus Footer
const FOOTER_CONFIG = {
copyright: "© 2026 PT Website Indonesia",
email: "info@website.id",
phone: "+62 812-3456-7890"
};
// Menggabungkan kedua objek ke dalam satu wadah
const APP_CONFIG = {
hero: HERO_CONFIG,
footer: FOOTER_CONFIG
};
// Fungsi Pengisi Otomatis
function renderApp() {
document.querySelectorAll('[data-config]').forEach(el => {
const path = el.getAttribute('data-config');
const keys = path.split('.'); // memecah "hero.title" menjadi ["hero", "title"]
// Ambil nilai dari APP_CONFIG[hero][title]
const value = keys.reduce((acc, key) => acc && acc[key], APP_CONFIG);
if (value) {
el.textContent = value;
}
});
}
document.addEventListener('DOMContentLoaded', renderApp);
</script>
</body>
</html>
๐ก Kesimpulan Penting
Menggunakan titik (.) pada atribut HTML (seperti data-config="hero.title") mempermudah pemetaan data bertingkat.
Fungsi path.split('.').reduce(...) adalah rumus standar JavaScript untuk membaca data objek.anak.cucu secara aman tanpa takut error.
Panduan Implementasi Banyak Produk (Array of Objects) di JS
Ketika Anda ingin menampilkan banyak produk (misal 2, 10, atau 100 produk) yang memiliki atribut sama (Nama, Deskripsi, Kategori, Ukuran, Harga, Tombol Beli), kuncinya adalah menggunakan Array ([...]) dari Objek ({...}).
๐ Perbedaan Utama: Objek Tunggal vs Array Produk
๐ ️ Langkah 1: Struktur Data Array Produk
Setiap produk berupa objek yang dibungkus di dalam tanda kurung siku [ ... ].
const PRODUCTS_CONFIG = [
{
id: "prod-01",
nama: "Kaos Polos Cotton Combed 30s",
kategori: "Pakaian Pria",
deskripsi: "Bahan adem, menyerap keringat, cocok untuk pemakaian sehari-hari.",
ukuran: ["S", "M", "L", "XL", "XXL"],
harga: "Rp 65.000",
gambar: "https://images.unsplash.com/photo-1521572267360-ee0c2909d518?auto=format&fit=crop&w=500&q=80"
},
{
id: "prod-02",
nama: "Jaket Denim Oversize",
kategori: "Jaket",
deskripsi: "Gaya streetwear klasik dengan bahan jeans tebal dan jahitan kuat.",
ukuran: ["M", "L", "XL"],
harga: "Rp 220.000",
gambar: "https://images.unsplash.com/photo-1551028719-00167b16eac5?auto=format&fit=crop&w=500&q=80"
},
{
id: "prod-03",
nama: "Sepatu Sneaker Casual",
kategori: "Sepatu",
deskripsi: "Sol empuk anti slip dengan desain modern minimalis.",
ukuran: ["39", "40", "41", "42", "43"],
harga: "Rp 350.000",
gambar: "https://images.unsplash.com/photo-1542291026-7eec264c27ff?auto=format&fit=crop&w=500&q=80"
}
];
๐ก Langkah 2: Cara Kerja Loop / Render
Alih-alih menuliskan tag HTML satu per satu di file .html, kita cukup menyediakan satu wadah kosong (container):
<!-- Container tempat produk akan bermunculan -->
<div id="product-container"></div>
Lalu di JavaScript, kita gunakan fungsi .map() untuk mengubah daftar produk menjadi elemen HTML:
function renderProducts() {
const container = document.getElementById('product-container');
// Memetakan setiap objek produk menjadi tampilan HTML
const productCardsHTML = PRODUCTS_CONFIG.map(item => {
// Mengubah array ukuran ["S", "M", "L"] menjadi badge/tombol kecil
const sizeBadges = item.ukuran.map(sz => `<span class="size-badge">${sz}</span>`).join('');
// Membuat link WhatsApp kustom untuk tiap produk
const waText = encodeURIComponent(`Halo, saya berminat membeli produk *${item.nama}* (Harga: ${item.harga}).`);
const waLink = `https://wa.me/6281234567890?text=${waText}`;
return `
<div class="product-card">
<img src="${item.gambar}" alt="${item.nama}">
<div class="card-body">
<span class="category">${item.kategori}</span>
<h3>${item.nama}</h3>
<p class="description">${item.deskripsi}</p>
<div class="sizes">
<small>Ukuran Tersedia:</small>
<div>${sizeBadges}</div>
</div>
<div class="card-footer">
<span class="price">${item.harga}</span>
<a href="${waLink}" target="_blank" class="btn-buy">Beli via WA</a>
</div>
</div>
</div>
`;
}).join(''); // Menggabungkan semua kartu menjadi satu teks HTML
container.innerHTML = productCardsHTML;
}
๐งช Contoh Utuh Lengkap (HTML + CSS + JS)
Silakan copy-paste kode di bawah ini ke file .html Anda dan buka di browser:
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Katalog Produk Dinamis</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; font-family: Arial, sans-serif; }
body { background: #f8fafc; padding: 40px 20px; }
h1 { text-align: center; margin-bottom: 30px; color: #0f172a; }
/* Grid Layout untuk Produk */
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 24px;
max-width: 1100px;
margin: 0 auto;
}
/* Card Produk */
.product-card {
background: white;
border-radius: 16px;
overflow: hidden;
box-shadow: 0 4px 12px rgba(0,0,0,0.05);
border: 1px solid #e2e8f0;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.product-card img {
width: 100%;
height: 200px;
object-fit: cover;
}
.card-body {
padding: 20px;
display: flex;
flex-direction: column;
gap: 10px;
flex-grow: 1;
}
.category {
font-size: 11px;
font-weight: bold;
color: #2563eb;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.product-card h3 {
font-size: 18px;
color: #1e293b;
}
.description {
font-size: 13px;
color: #64748b;
line-height: 1.5;
}
/* Style Badges Ukuran */
.sizes { margin-top: 10px; }
.sizes small { display: block; color: #94a3b8; font-size: 11px; margin-bottom: 5px; }
.size-badge {
display: inline-block;
background: #f1f5f9;
border: 1px solid #cbd5e1;
padding: 3px 8px;
border-radius: 6px;
font-size: 11px;
font-weight: bold;
margin-right: 4px;
margin-bottom: 4px;
color: #334155;
}
/* Footer Card (Harga & Tombol) */
.card-footer {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 15px;
padding-top: 15px;
border-top: 1px solid #f1f5f9;
}
.price {
font-size: 18px;
font-weight: bold;
color: #059669;
}
.btn-buy {
background: #25d366;
color: white;
padding: 8px 16px;
border-radius: 8px;
text-decoration: none;
font-size: 13px;
font-weight: bold;
transition: background 0.2s;
}
.btn-buy:hover { background: #1eb857; }
</style>
</head>
<body>
<h1>Katalog Produk Pilihan</h1>
<!-- Kontainer tempat produk di-render -->
<div id="product-container" class="grid-container"></div>
<script>
// 1. DATA KONFIGURASI BANYAK PRODUK (ARRAY OF OBJECTS)
const PRODUCTS_CONFIG = [
{
id: "prod-01",
nama: "Kaos Polos Cotton Combed 30s",
kategori: "Pakaian Pria",
deskripsi: "Bahan adem, menyerap keringat, cocok untuk pemakaian sehari-hari.",
ukuran: ["S", "M", "L", "XL", "XXL"],
harga: "Rp 65.000",
gambar: "https://images.unsplash.com/photo-1521572267360-ee0c2909d518?auto=format&fit=crop&w=500&q=80"
},
{
id: "prod-02",
nama: "Jaket Denim Oversize",
kategori: "Jaket",
deskripsi: "Gaya streetwear klasik dengan bahan jeans tebal dan jahitan kuat.",
ukuran: ["M", "L", "XL"],
harga: "Rp 220.000",
gambar: "https://images.unsplash.com/photo-1551028719-00167b16eac5?auto=format&fit=crop&w=500&q=80"
},
{
id: "prod-03",
nama: "Sepatu Sneaker Casual",
kategori: "Sepatu",
deskripsi: "Sol empuk anti slip dengan desain modern minimalis cocok untuk nongkrong.",
ukuran: ["39", "40", "41", "42", "43"],
harga: "Rp 350.000",
gambar: "https://images.unsplash.com/photo-1542291026-7eec264c27ff?auto=format&fit=crop&w=500&q=80"
}
];
// 2. FUNGSI RENDER KE HTML
function renderApp() {
const container = document.getElementById('product-container');
// Loop semua produk
const htmlList = PRODUCTS_CONFIG.map(item => {
// Render sub-array untuk ukuran (size)
const sizeBadges = item.ukuran.map(s => `<span class="size-badge">${s}</span>`).join('');
// Link WhatsApp dinamis untuk tiap produk
const waMsg = encodeURIComponent(`Halo, saya mau beli *${item.nama}* (${item.harga}). Apakah ukuran masih ready?`);
const waUrl = `https://wa.me/6281234567890?text=${waMsg}`;
return `
<div class="product-card">
<div>
<img src="${item.gambar}" alt="${item.nama}">
<div class="card-body">
<span class="category">${item.kategori}</span>
<h3>${item.nama}</h3>
<p class="description">${item.deskripsi}</p>
<div class="sizes">
<small>Ukuran Tersedia:</small>
<div>${sizeBadges}</div>
</div>
</div>
</div>
<div class="card-body" style="padding-top:0;">
<div class="card-footer">
<span class="price">${item.harga}</span>
<a href="${waUrl}" target="_blank" class="btn-buy">Chat Beli</a>
</div>
</div>
</div>
`;
}).join('');
container.innerHTML = htmlList;
}
// Jalankan saat halaman selesai dimuat
document.addEventListener('DOMContentLoaded', renderApp);
</script>
</body>
</html>
๐ Kesimpulan Ringkas
Prinsip Sama: Tetap menggunakan Centralized Config agar data terpisah dari tampilan.
Bedanya di Struktur: Kalau hanya 1 item (seperti Hero/Footer), gunakan {}. Kalau lebih dari 1 item (seperti Produk), gunakan [ {}, {}, {} ].
Fleksibilitas: Dengan cara ini, menambah produk ke-4 atau ke-100 cukup menambahkan satu blok { ... } baru di dalam PRODUCTS_CONFIG tanpa perlu menyentuh CSS atau HTML!
