MOBIL SAYA:
Semua Produk
BYD (Build Your Dreams) Seal
Spesifikasi Terpilih
CARI MOBIL LAIN:
1. Pilih Merk
⌄
2. Pilih Tipe
⌄
3. Pilih Varian / Kode B...
⌄
Filter Lengkap Produk & Layanan Otozip
0 Filter
Range Harga, Kategori, Merk Ban/Velg & Rim Size
Buka Filter
⌄
LANGKAH 2: RANGE HARGA & MERK
Filter Harga & Merk Produk
PILIH MERK BAN / VELG:
Semua Merk Ban & Velg
⌄
PILIH PRESET HARGA:
Semua Harga
< Rp 1 Jt
Rp 1 – 3 Jt
Rp 3 – 5 Jt
> Rp 5 Jt
URUTKAN:
Relevansi
Harga Termurah
Harga Termahal
LANGKAH 3: PILIH KATEGORI
Semua Produk
Ban Mobil
Velg Mobil
RIM SIZE (RING)
Semua Size
⌄
PCD - WIDTH
Semua PCD
⌄
MORE / LAYANAN OTOZIP
Semua
⌄
document.addEventListener('DOMContentLoaded', function() {
// FITMENT DATABASE FROM LIVE OTOZIP API (ASSET ASSET_URL)
var fitmentData = {
'BYD': {
'Seal': { pcd: '5x120', oem: ['235/45 R19'], alt: ['235/50 R19', '255/45 R19', '245/45 R19'] },
'Atto 3': { pcd: '5x114.3', oem: ['215/60 R17', '235/50 R18'], alt: ['225/55 R18'] },
'Dolphin': { pcd: '5x114.3', oem: ['195/60 R16', '205/50 R17'], alt: ['205/55 R16'] }
},
'Toyota': {
'Avanza / Veloz': { pcd: '4x100', oem: ['185/65 R15', '195/60 R16'], alt: ['195/65 R15', '205/55 R16'] },
'Innova / Zenix': { pcd: '5x114.3', oem: ['205/65 R16', '215/60 R17', '225/50 R18'], alt: ['215/65 R16', '225/55 R17'] },
'Fortuner': { pcd: '6x139.7', oem: ['265/60 R18', '265/65 R17'], alt: ['275/55 R20', '285/60 R18'] },
'Raize': { pcd: '4x100', oem: ['205/65 R16', '205/60 R17'], alt: ['215/60 R16', '215/55 R17'] },
'Yaris / Yaris Cross': { pcd: '4x100', oem: ['185/60 R15', '195/50 R16', '215/55 R18'], alt: ['205/50 R16'] },
'Rush': { pcd: '5x114.3', oem: ['215/60 R17'], alt: ['215/65 R16', '225/55 R17'] },
'Hilux': { pcd: '6x139.7', oem: ['265/65 R17', '265/60 R18'], alt: ['275/65 R17'] }
},
'Honda': {
'Brio / Jazz': { pcd: '4x100', oem: ['175/65 R14', '185/55 R15'], alt: ['185/60 R14', '195/50 R16'] },
'HR-V / CR-V': { pcd: '5x114.3', oem: ['215/60 R17', '225/50 R18', '235/60 R18', '235/55 R19'], alt: ['225/55 R18'] },
'WR-V / BR-V': { pcd: '5x114.3', oem: ['215/60 R17', '215/55 R17'], alt: ['225/55 R17'] },
'Civic / City': { pcd: '5x114.3', oem: ['215/50 R17', '235/40 R18', '265/30 R19'], alt: ['225/45 R17'] }
},
'Mitsubishi': {
'Pajero Sport': { pcd: '6x139.7', oem: ['265/60 R18', '265/65 R17'], alt: ['275/55 R20'] },
'Xpander / Xpander Cross': { pcd: '5x114.3', oem: ['195/65 R15', '205/55 R17'], alt: ['215/55 R17', '215/50 R18'] },
'Xforce': { pcd: '5x114.3', oem: ['225/50 R18'], alt: ['235/45 R18'] },
'Triton': { pcd: '6x139.7', oem: ['265/65 R17', '265/60 R18'], alt: ['275/65 R17'] }
},
'Suzuki': {
'Ertiga / XL7': { pcd: '5x114.3', oem: ['185/65 R15', '195/60 R16'], alt: ['195/65 R15', '205/55 R16'] },
'Jimny': { pcd: '5x139.7', oem: ['195/80 R15'], alt: ['215/75 R15', '235/70 R15'] },
'Baleno / Grand Vitara': { pcd: '4x100', oem: ['195/55 R16', '215/60 R17'], alt: ['205/55 R16'] }
},
'Hyundai': {
'Stargazer / Creta': { pcd: '5x114.3', oem: ['205/65 R16', '215/60 R17'], alt: ['215/55 R17', '225/50 R18'] },
'Ioniq 5 / Ioniq 6': { pcd: '5x114.3', oem: ['235/55 R19', '255/45 R20'], alt: ['245/50 R19'] },
'Palisade / Santa Fe': { pcd: '5x114.3', oem: ['245/50 R20', '235/60 R18'], alt: ['255/50 R20'] }
},
'Wuling': {
'Almaz / Binguo EV': { pcd: '5x114.3', oem: ['215/60 R17', '215/55 R18', '185/60 R15'], alt: ['225/55 R18'] },
'Air EV': { pcd: '4x100', oem: ['145/70 R12'], alt: ['155/65 R13'] }
},
'BMW': {
'Series 3 / 5': { pcd: '5x112', oem: ['225/45 R18', '245/40 R19'], alt: ['255/35 R19'] },
'X1 / X3 / X5': { pcd: '5x112', oem: ['225/50 R18', '245/50 R19', '275/45 R20'], alt: ['275/40 R21'] }
},
'Mercedes-Benz': {
'C-Class / E-Class': { pcd: '5x112', oem: ['225/45 R18', '245/40 R19'], alt: ['255/35 R19'] },
'GLC / GLE': { pcd: '5x112', oem: ['235/55 R19', '255/50 R19'], alt: ['275/45 R20'] }
}
};
var selectedMake = '';
var selectedModel = '';
var selectedVariant = '';
var selectedFitmentSize = '';
var selectedBrand = '';
var selectedRim = '';
var selectedPcd = '';
var selectedMore = '';
var carPillSaved = document.querySelector('[data-car-btn="saved"]');
var carPillAll = document.querySelector('[data-car-btn="all"]');
var carTitle = document.querySelector('[data-car-title]');
var carSubtitle = document.querySelector('[data-car-subtitle]');
var smartOemBox = document.getElementById('OtzSmartOemBox');
var smartCarNameSpan = document.querySelector('[data-smart-car-name]');
var smartCountSpan = document.querySelector('[data-smart-count]');
var oemPillsContainer = document.getElementById('OtzOemPillsContainer');
var pcdBadge = document.getElementById('OtzPcdBadge');
var resetSmartBtn = document.getElementById('OtzResetSmartCar');
// Restore saved car from LocalStorage
var savedCarRaw = localStorage.getItem('otz_user_car');
if (savedCarRaw) {
try {
var savedCar = JSON.parse(savedCarRaw);
if (savedCar && (savedCar.make || savedCar.model)) {
selectedMake = savedCar.make || '';
selectedModel = savedCar.model || '';
selectedVariant = savedCar.variant || '';
updateCarState();
}
} catch(e) {}
}
function updateCarState() {
var triggerMakeText = document.querySelector('[data-trigger-text="make"]');
var triggerModelText = document.querySelector('[data-trigger-text="model"]');
var triggerVariantText = document.querySelector('[data-trigger-text="variant"]');
var triggerModel = document.querySelector('[data-trigger-target="model"]');
var triggerVariant = document.querySelector('[data-trigger-target="variant"]');
if (triggerMakeText) triggerMakeText.textContent = selectedMake || '1. Pilih Merk';
if (triggerModelText) triggerModelText.textContent = selectedModel || '2. Pilih Tipe';
if (triggerVariantText) triggerVariantText.textContent = selectedVariant || '3. Pilih Varian / Kode B...';
if (triggerModel) triggerModel.disabled = !selectedMake;
if (triggerVariant) triggerVariant.disabled = !selectedModel;
if (selectedMake || selectedModel) {
var fullTitle = [selectedMake, selectedModel].filter(Boolean).join(' ');
var fullSub = selectedVariant || 'Spesifikasi Mobil';
if (carTitle) carTitle.textContent = fullTitle;
if (carSubtitle) carSubtitle.textContent = fullSub;
if (carPillSaved) {
carPillSaved.style.display = 'inline-flex';
carPillSaved.classList.add('is-active', 'is-selected');
}
if (carPillAll) carPillAll.classList.remove('is-active');
renderSmartOemBox(selectedMake, selectedModel);
localStorage.setItem('otz_user_car', JSON.stringify({ make: selectedMake, model: selectedModel, variant: selectedVariant }));
} else {
if (carPillSaved) {
carPillSaved.style.display = 'none';
carPillSaved.classList.remove('is-active', 'is-selected');
}
if (carPillAll) carPillAll.classList.add('is-active');
if (smartOemBox) smartOemBox.style.display = 'none';
}
autoFilterGrid();
}
function renderSmartOemBox(make, model) {
if (!smartOemBox || !oemPillsContainer) return;
var fit = (fitmentData[make] && fitmentData[make][model]) ? fitmentData[make][model] : null;
if (!fit) {
fit = { pcd: '5x114.3', oem: ['215/60 R17'], alt: ['225/50 R18', '205/65 R16'] };
}
if (smartCarNameSpan) smartCarNameSpan.textContent = [make, model].filter(Boolean).join(' ');
if (pcdBadge) pcdBadge.textContent = fit.pcd || 'Universal';
oemPillsContainer.innerHTML = '';
var totalCount = (fit.oem ? fit.oem.length : 0) + (fit.alt ? fit.alt.length : 0);
if (smartCountSpan) smartCountSpan.textContent = totalCount;
// OEM Pills
if (fit.oem) {
fit.oem.forEach(function(sz) {
var pill = document.createElement('button');
pill.type = 'button';
pill.className = 'otz-oem-pill otz-oem-pill--oem' + (selectedFitmentSize === sz ? ' is-active' : '');
pill.innerHTML = '
✓ ' + sz + ' OEM ';
pill.onclick = function() {
if (selectedFitmentSize === sz) selectedFitmentSize = '';
else selectedFitmentSize = sz;
renderSmartOemBox(make, model);
autoFilterGrid();
};
oemPillsContainer.appendChild(pill);
});
}
// Alternatif Pills
if (fit.alt) {
fit.alt.forEach(function(sz) {
var pill = document.createElement('button');
pill.type = 'button';
pill.className = 'otz-oem-pill otz-oem-pill--alt' + (selectedFitmentSize === sz ? ' is-active' : '');
pill.innerHTML = '
🔄 ' + sz + ' ALTERNATIF ';
pill.onclick = function() {
if (selectedFitmentSize === sz) selectedFitmentSize = '';
else selectedFitmentSize = sz;
renderSmartOemBox(make, model);
autoFilterGrid();
};
oemPillsContainer.appendChild(pill);
});
}
smartOemBox.style.display = 'block';
}
if (resetSmartBtn) {
resetSmartBtn.onclick = function() {
selectedMake = '';
selectedModel = '';
selectedVariant = '';
selectedFitmentSize = '';
updateCarState();
};
}
if (carPillAll) {
carPillAll.onclick = function() {
selectedMake = '';
selectedModel = '';
selectedVariant = '';
selectedFitmentSize = '';
updateCarState();
};
}
if (carPillSaved) {
carPillSaved.onclick = function() {
carPillSaved.classList.add('is-active');
if (carPillAll) carPillAll.classList.remove('is-active');
autoFilterGrid();
};
}
// MODAL LOGIC WITH BODY SCROLL LOCKING
var modalOverlay = document.getElementById('OtzOptionModal');
var modalTitle = document.getElementById('OtzModalTitle');
var modalSearchInput = document.getElementById('OtzModalSearchInput');
var modalOptionsList = document.getElementById('OtzModalOptionsList');
function openModal(title, options, currentVal, onSelect) {
if (modalTitle) modalTitle.textContent = title;
if (modalSearchInput) modalSearchInput.value = '';
renderOptions(options, currentVal, onSelect);
if (modalOverlay) modalOverlay.removeAttribute('hidden');
document.body.classList.add('otz-modal-open');
if (modalSearchInput) {
modalSearchInput.onkeyup = function() {
var q = modalSearchInput.value.toLowerCase().trim();
var filtered = options.filter(function(opt) {
return opt.toLowerCase().includes(q);
});
renderOptions(filtered, currentVal, onSelect);
};
}
}
function renderOptions(optionsList, currentVal, onSelect) {
if (!modalOptionsList) return;
modalOptionsList.innerHTML = '';
if (optionsList.length === 0) {
modalOptionsList.innerHTML = '
Tidak ada pilihan cocok
';
return;
}
optionsList.forEach(function(opt) {
var item = document.createElement('div');
item.className = 'otz-modal-option-item' + (opt === currentVal ? ' is-selected' : '');
item.innerHTML = '
' + opt + ' ' + (opt === currentVal ? '
✓ ' : '');
item.onclick = function() {
onSelect(opt);
closeModal();
};
modalOptionsList.appendChild(item);
});
}
function closeModal() {
if (modalOverlay) modalOverlay.setAttribute('hidden', '');
document.body.classList.remove('otz-modal-open');
}
document.querySelectorAll('[data-modal-close]').forEach(function(btn) {
btn.onclick = closeModal;
});
if (modalOverlay) {
modalOverlay.onclick = function(e) {
if (e.target === modalOverlay) closeModal();
};
}
// MODAL TRIGGERS
document.querySelectorAll('[data-trigger-target]').forEach(function(trigger) {
trigger.onclick = function() {
if (trigger.disabled) return;
var target = trigger.getAttribute('data-trigger-target');
if (target === 'make') {
var makes = Object.keys(fitmentData);
openModal('Pilih Merk Mobil', ['Semua Merk'].concat(makes), selectedMake, function(val) {
selectedMake = val === 'Semua Merk' ? '' : val;
selectedModel = '';
selectedVariant = '';
selectedFitmentSize = '';
updateCarState();
});
}
else if (target === 'model') {
var models = selectedMake && fitmentData[selectedMake] ? Object.keys(fitmentData[selectedMake]) : ['Avanza / Veloz', 'Innova / Zenix', 'Fortuner', 'Pajero Sport', 'HR-V', 'Brio', 'Xpander', 'Raize', 'Seal'];
openModal('Pilih Tipe Mobil (' + (selectedMake || 'Semua') + ')', ['Semua Tipe'].concat(models), selectedModel, function(val) {
selectedModel = val === 'Semua Tipe' ? '' : val;
selectedVariant = '';
selectedFitmentSize = '';
updateCarState();
});
}
else if (target === 'variant') {
var variants = ['Standard Trim', 'Type G / S', 'Type V / RS', 'Ultimate / Exceed', 'Performance AWD', 'Hybrid TSS'];
openModal('Pilih Varian / Trim (' + (selectedModel || 'Semua') + ')', ['Semua Varian'].concat(variants), selectedVariant, function(val) {
selectedVariant = val === 'Semua Varian' ? '' : val;
updateCarState();
});
}
else if (target === 'brand') {
var brands = ['Semua Merk Ban & Velg', 'Bridgestone', 'Michelin', 'Continental', 'Pirelli', 'Hankook', 'Dunlop', 'Yokohama', 'GT Radial', 'Accelera', 'Forceum', 'Enkei', 'Rays', 'Work Wheels', 'BBS', 'Lenso', 'Rotiform', 'SSR', 'OZ Racing'];
openModal('Pilih Merk Ban & Velg', brands, selectedBrand, function(val) {
selectedBrand = val === 'Semua Merk Ban & Velg' ? '' : val;
var t = document.querySelector('[data-trigger-text="brand"]');
if (t) t.textContent = val;
autoFilterGrid();
});
}
else if (target === 'rim') {
var rims = ['Semua Size', 'Ring 14', 'Ring 15', 'Ring 16', 'Ring 17', 'Ring 18', 'Ring 19', 'Ring 20', 'Ring 21', 'Ring 22'];
openModal('Pilih Rim Size (Ring)', rims, selectedRim, function(val) {
selectedRim = val === 'Semua Size' ? '' : val;
var t = document.querySelector('[data-trigger-text="rim"]');
if (t) t.textContent = val;
autoFilterGrid();
});
}
else if (target === 'pcd') {
var pcds = ['Semua PCD', '4x100', '4x114.3', '5x100', '5x108', '5x112', '5x114.3', '5x120', '6x139.7'];
openModal('Pilih PCD Width', pcds, selectedPcd, function(val) {
selectedPcd = val === 'Semua PCD' ? '' : val;
var t = document.querySelector('[data-trigger-text="pcd"]');
if (t) t.textContent = val;
autoFilterGrid();
});
}
else if (target === 'more') {
var mores = ['Semua', 'Tambal Ban TipTop Press (Rp 100k)', 'Tambal Payung (Rp 150k)', 'Tambal Tubeless (Rp 50k)', 'Pengisian Nitrogen (Rp 25k)', 'Pasang Ban Serep (Rp 50k)', 'Bongkar Pasang OEM (Rp 100k)', 'Bongkar Pasang Premium (Rp 150k)', 'Balancing (Rp 50k)', 'Rotasi Roda (Rp 100k)', 'Sensor TPMS (Rp 200k)'];
openModal('Layanan Otozip Home Service', mores, selectedMore, function(val) {
selectedMore = val === 'Semua' ? '' : val;
var t = document.querySelector('[data-trigger-text="more"]');
if (t) t.textContent = val;
autoFilterGrid();
});
}
};
});
// Toggle Collapsible Panel
var toggleBtn = document.querySelector('[data-otz-toggle-btn]');
var panel = document.querySelector('[data-otz-panel]');
var toggleLabel = document.querySelector('[data-otz-toggle-label]');
if (toggleBtn && panel) {
toggleBtn.onclick = function() {
var isExpanded = toggleBtn.getAttribute('aria-expanded') === 'true';
if (isExpanded) {
toggleBtn.setAttribute('aria-expanded', 'false');
panel.setAttribute('hidden', '');
if (toggleLabel) toggleLabel.textContent = 'Buka Filter';
} else {
toggleBtn.setAttribute('aria-expanded', 'true');
panel.removeAttribute('hidden');
if (toggleLabel) toggleLabel.textContent = 'Sembunyikan Filter';
}
};
}
// Price Presets
var pricePills = document.querySelectorAll('[data-price-preset]');
pricePills.forEach(function(pill) {
pill.onclick = function() {
pricePills.forEach(function(p) { p.classList.remove('is-active'); });
pill.classList.add('is-active');
var val = pill.getAttribute('data-price-preset');
var minInput = document.querySelector('[data-otz-min-price]');
var maxInput = document.querySelector('[data-otz-max-price]');
if (val === 'under-1m') { if(minInput) minInput.value = ''; if(maxInput) maxInput.value = '1000000'; }
else if (val === '1m-3m') { if(minInput) minInput.value = '1000000'; if(maxInput) maxInput.value = '3000000'; }
else if (val === '3m-5m') { if(minInput) minInput.value = '3000000'; if(maxInput) maxInput.value = '5000000'; }
else if (val === 'above-5m') { if(minInput) minInput.value = '5000000'; if(maxInput) maxInput.value = ''; }
else { if(minInput) minInput.value = ''; if(maxInput) maxInput.value = ''; }
autoFilterGrid();
};
});
// Category Tabs
var catTabs = document.querySelectorAll('.otz-category-tab');
catTabs.forEach(function(tab) {
tab.onclick = function() {
catTabs.forEach(function(t) { t.classList.remove('is-active'); });
tab.classList.add('is-active');
autoFilterGrid();
};
});
// Sort Pills
var sortPills = document.querySelectorAll('[data-sort]');
sortPills.forEach(function(pill) {
pill.onclick = function() {
sortPills.forEach(function(p) { p.classList.remove('is-active'); });
pill.classList.add('is-active');
autoFilterGrid();
};
});
// Inputs & Search Listener
document.querySelectorAll('[data-otz-min-price], [data-otz-max-price]').forEach(function(el) {
el.oninput = autoFilterGrid;
});
var sInput = document.querySelector('[data-otz-search-input]');
if (sInput) {
sInput.oninput = autoFilterGrid;
}
// INSTANT LIVE IN-PAGE PRODUCT GRID FILTER & ACTIVE FILTER BADGE COUNTER
function autoFilterGrid() {
var activeCount = 0;
var make = selectedMake.toLowerCase().trim();
var model = selectedModel.toLowerCase().trim();
var variant = selectedVariant.toLowerCase().trim();
var fitSize = selectedFitmentSize.toLowerCase().trim();
var brand = selectedBrand.toLowerCase().trim();
var rim = selectedRim.replace(/[^0-9]/g, '').trim();
var pcd = selectedPcd.toLowerCase().trim();
var more = selectedMore.toLowerCase().trim();
if (make) activeCount++;
if (model) activeCount++;
if (fitSize) activeCount++;
if (brand) activeCount++;
if (rim) activeCount++;
if (pcd) activeCount++;
if (more) activeCount++;
var minPrice = document.querySelector('[data-otz-min-price]') ? parseFloat(document.querySelector('[data-otz-min-price]').value) : 0;
var maxPrice = document.querySelector('[data-otz-max-price]') ? parseFloat(document.querySelector('[data-otz-max-price]').value) : 0;
if (minPrice > 0 || maxPrice > 0) activeCount++;
var searchKw = sInput ? sInput.value.toLowerCase().trim() : '';
if (searchKw) activeCount++;
var activeCat = document.querySelector('.otz-category-tab.is-active') ? document.querySelector('.otz-category-tab.is-active').getAttribute('data-cat') : 'all';
if (activeCat !== 'all') activeCount++;
// Update Filter Badge Count
var filterBadge = document.getElementById('OtzFilterCountBadge');
if (filterBadge) {
filterBadge.textContent = activeCount + ' Filter';
filterBadge.style.display = activeCount > 0 ? 'inline-block' : 'none';
}
var gridItems = document.querySelectorAll('#product-grid .grid-item, .product-grid .grid-item, .template-search__results .grid-item');
if (!gridItems || gridItems.length === 0) return;
gridItems.forEach(function(item) {
var text = item.textContent.toLowerCase();
var show = true;
if (make && !text.includes(make)) show = false;
if (model && !text.includes(model)) show = false;
if (variant && !text.includes(variant)) show = false;
if (fitSize && !text.includes(fitSize)) show = false;
if (brand && !text.includes(brand)) show = false;
if (rim && !text.includes('r' + rim) && !text.includes('ring ' + rim) && !text.includes(' ' + rim)) show = false;
if (pcd && !text.includes(pcd)) show = false;
if (more && !text.includes(more)) show = false;
if (searchKw && !text.includes(searchKw)) show = false;
if (activeCat === 'ban-mobil' && !text.includes('ban')) show = false;
if (activeCat === 'velg-mobil' && !text.includes('velg') && !text.includes('wheel')) show = false;
if (minPrice > 0 || maxPrice > 0) {
var priceEl = item.querySelector('.price, .price-item, .card__price');
if (priceEl) {
var rawPrice = priceEl.textContent.replace(/[^0-9]/g, '');
var numPrice = parseFloat(rawPrice);
if (numPrice) {
if (minPrice > 0 && numPrice < minPrice) show = false;
if (maxPrice > 0 && numPrice > maxPrice) show = false;
}
}
}