// ==========================================
// 1. INISIALISASI PETA & LAYER
// ==========================================
var map = L.map('map', { zoomControl: false }).setView([-0.0227, 109.3425], 14);
// Zoom control di kanan bawah
L.control.zoom({ position: 'bottomright' }).addTo(map);
// OpenStreetMap Tile Layer
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
// Layer Groups
var spbu24JamLayer = L.layerGroup().addTo(map);
var spbuRegulerLayer = L.layerGroup().addTo(map);
var drawnItems = new L.FeatureGroup().addTo(map);
// Layer Control (Checkbox di kanan atas)
var overlayMaps = {
"⛽ SPBU Buka 24 Jam": spbu24JamLayer,
"⛽ SPBU Reguler": spbuRegulerLayer
};
L.control.layers(null, overlayMaps, { collapsed: true, position: 'bottomleft' }).addTo(map);
// Standard Leaflet Marker Icons
var greenIcon = new L.Icon({
iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-green.png',
shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
iconSize: [25, 41], iconAnchor: [12, 41], popupAnchor: [1, -34], shadowSize: [41, 41]
});
var redIcon = new L.Icon({
iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-red.png',
shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
iconSize: [25, 41], iconAnchor: [12, 41], popupAnchor: [1, -34], shadowSize: [41, 41]
});
// Global Variables
var databasePencarian = [];
var spbuMarkers = {};
var sidebarPickMode = false;
var sidebarTempLat = 0.0;
var sidebarTempLng = 0.0;
// ==========================================
// 2. FUNGSI LOAD DATA DARI DATABASE
// ==========================================
function loadSPBU() {
spbu24JamLayer.clearLayers();
spbuRegulerLayer.clearLayers();
spbuMarkers = {};
databasePencarian = [];
fetch('load.php?jenis=spbu')
.then(res => res.json())
.then(data => {
data.forEach(item => {
var is24Jam = item.kategori === 'Ya';
var statusBuka = is24Jam ? 'Buka 24 Jam' : 'Reguler';
var icon = is24Jam ? greenIcon : redIcon;
var statusColor = is24Jam ? '#10b981' : '#ef4444';
var viewHTML = `
`;
var marker = L.marker([item.latitude, item.longitude], { icon: icon, draggable: false });
if (is24Jam) {
marker.addTo(spbu24JamLayer);
} else {
marker.addTo(spbuRegulerLayer);
}
marker.bindPopup(viewHTML);
spbuMarkers[String(item.id)] = marker;
marker.on('click', function () {
map.flyTo(marker.getLatLng(), 16, { animate: true });
});
// Update coordinates input on marker drag end (during edit)
marker.on('dragend', function (e) {
var position = marker.getLatLng();
if (document.getElementById('edit_lat')) {
document.getElementById('edit_lat').value = position.lat.toFixed(6);
document.getElementById('edit_lng').value = position.lng.toFixed(6);
}
marker.openPopup();
});
databasePencarian.push({
namaLower: item.nama_spbu.toLowerCase(),
namaAsli: item.nama_spbu,
kategori: 'SPBU',
ikon: '⛽',
tipe: 'titik',
layer: marker
});
});
})
.catch(e => console.log('Belum ada data SPBU', e));
}
// Load data awal
loadSPBU();
// ==========================================
// 3. EDIT & UPDATE DATA
// ==========================================
function formEditSPBU(id, nama, hp, kategori) {
var markerId = String(id);
var currentMarker = spbuMarkers[markerId];
if (currentMarker) {
currentMarker.dragging.enable();
}
setTimeout(function () {
var container = document.getElementById(`popup-spbu-${id}`);
if (!container) return;
var lat = currentMarker.getLatLng().lat.toFixed(6);
var lng = currentMarker.getLatLng().lng.toFixed(6);
container.innerHTML = `
`;
}, 50);
}
function updateData(e, tabel, id) {
e.preventDefault();
var formData = new FormData();
formData.append('tabel', tabel);
formData.append('id', id);
formData.append('nama_spbu', document.getElementById('edit_nama').value);
formData.append('no_hp', document.getElementById('edit_hp').value);
formData.append('kategori', document.getElementById('edit_kategori').value);
// Get current dragged position
var markerPosisi = spbuMarkers[String(id)].getLatLng();
formData.append('latitude', markerPosisi.lat);
formData.append('longitude', markerPosisi.lng);
fetch('update_data.php', { method: 'POST', body: formData })
.then(r => r.text())
.then(res => {
alert(res);
map.closePopup();
loadSPBU();
})
.catch(error => console.error("Error updating data:", error));
}
// ==========================================
// 4. HAPUS DATA
// ==========================================
function deleteData(tabel, id) {
if (confirm('Apakah Anda yakin ingin menghapus data SPBU ini?')) {
var formData = new FormData();
formData.append('id', id);
formData.append('tabel', tabel);
fetch('delete_data.php', { method: 'POST', body: formData })
.then(r => r.text())
.then(res => {
alert(res);
map.closePopup();
loadSPBU();
})
.catch(error => console.error("Error deleting data:", error));
}
}
// ==========================================
// 5. SISTEM PENCARIAN & ZOOM
// ==========================================
function jalankanPencarian() {
var kataKunci = document.getElementById('search-input').value.toLowerCase();
var kategori = document.getElementById('search-category').value;
var wadahHasil = document.getElementById('search-results');
wadahHasil.innerHTML = '';
if (kataKunci.length < 2) {
wadahHasil.style.display = 'none';
return;
}
var hasil = databasePencarian.filter(function (item) {
var cocokNama = item.namaLower.includes(kataKunci);
var cocokKategori = (kategori === 'Semua') || (item.kategori === kategori);
return cocokNama && cocokKategori;
});
if (hasil.length > 0) {
wadahHasil.style.display = 'block';
wadahHasil.innerHTML = ``;
hasil.forEach(function (item) {
var div = document.createElement('div');
div.className = 'result-item';
div.innerHTML = `
${item.ikon}
${item.namaAsli}
Klik untuk zoom ke lokasi
${item.kategori}`;
div.onclick = function () {
map.flyTo(item.layer.getLatLng(), 16, { animate: true, duration: 1.5 });
item.layer.openPopup();
wadahHasil.style.display = 'none';
document.getElementById('search-input').value = item.namaAsli;
toggleClearBtn();
};
wadahHasil.appendChild(div);
});
} else {
wadahHasil.style.display = 'block';
wadahHasil.innerHTML = `
`;
}
}
function toggleClearBtn() {
var input = document.getElementById('search-input');
var clearBtn = document.getElementById('search-clear');
clearBtn.style.display = input.value.length > 0 ? 'flex' : 'none';
}
function clearSearch() {
document.getElementById('search-input').value = '';
document.getElementById('search-results').style.display = 'none';
document.getElementById('search-clear').style.display = 'none';
}
// Tutup hasil saat klik di luar
document.addEventListener('click', function (e) {
var wrapper = document.querySelector('.search-wrapper');
if (wrapper && !wrapper.contains(e.target)) {
document.getElementById('search-results').style.display = 'none';
}
});
// Shortcut Ctrl + K untuk fokus ke pencarian
document.addEventListener('keydown', function (e) {
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
e.preventDefault();
document.getElementById('search-input').focus();
}
if (e.key === 'Escape') {
clearSearch();
document.getElementById('search-input').blur();
}
});
// ==========================================
// 6. LOGIKA INPUT SIDEBAR & PROGRAMMATIC PICK
// ==========================================
// Buka/Tutup Sidebar
document.getElementById('sidebar-toggle').addEventListener('click', function () {
var sidebar = document.getElementById('input-sidebar');
sidebar.classList.toggle('open');
this.classList.toggle('open');
});
document.getElementById('sidebar-close').addEventListener('click', function () {
document.getElementById('input-sidebar').classList.remove('open');
document.getElementById('sidebar-toggle').classList.remove('open');
});
// Aktifkan mode pilih titik di peta
function activatePickMode() {
sidebarPickMode = true;
document.getElementById('pick-overlay').classList.add('active');
document.getElementById('btn-pick-spbu').classList.add('active-pick');
map.getContainer().style.cursor = 'crosshair';
}
// Batalkan mode pick
function deactivatePickMode() {
sidebarPickMode = false;
document.getElementById('pick-overlay').classList.remove('active');
document.getElementById('btn-pick-spbu').classList.remove('active-pick');
map.getContainer().style.cursor = '';
}
// Tangkap klik peta untuk mendapatkan koordinat
map.on('click', function (e) {
if (!sidebarPickMode) return;
var lat = e.latlng.lat;
var lng = e.latlng.lng;
sidebarTempLat = lat;
sidebarTempLng = lng;
var el = document.getElementById('coords-spbu-val');
el.textContent = lat.toFixed(6) + ', ' + lng.toFixed(6);
el.classList.add('has-coords');
// Tempatkan penanda sementara
drawnItems.clearLayers();
L.marker([lat, lng], { icon: redIcon }).addTo(drawnItems);
deactivatePickMode();
});
// ==========================================
// 7. SIMPAN DATA DARI SIDEBAR
// ==========================================
function saveSPBUSidebar() {
if (!sidebarTempLat || !sidebarTempLng) {
alert('Silakan pilih lokasi SPBU di peta terlebih dahulu!');
return;
}
var nama = document.getElementById('sb_nama_spbu').value.trim();
if (!nama) {
alert('Nama SPBU wajib diisi!');
return;
}
var formData = new FormData();
formData.append('nama_spbu', nama);
formData.append('no_hp', document.getElementById('sb_nohp_spbu').value.trim());
formData.append('kategori', document.getElementById('sb_kategori_spbu').value);
formData.append('latitude', sidebarTempLat);
formData.append('longitude', sidebarTempLng);
fetch('save.php', { method: 'POST', body: formData })
.then(r => r.text())
.then(res => {
alert(res);
document.getElementById('sb_nama_spbu').value = '';
document.getElementById('sb_nohp_spbu').value = '';
document.getElementById('coords-spbu-val').textContent = 'Belum dipilih';
document.getElementById('coords-spbu-val').classList.remove('has-coords');
sidebarTempLat = 0.0;
sidebarTempLng = 0.0;
drawnItems.clearLayers();
loadSPBU();
})
.catch(e => console.error("Error saving SPBU:", e));
}
// ==========================================
// 8. DROPDOWN KATEGORI DI HEADER
// ==========================================
document.addEventListener('DOMContentLoaded', function () {
var wrap = document.getElementById('custom-select-wrap');
var trigger = document.getElementById('custom-select-trigger');
var options = document.getElementById('custom-select-options');
var hiddenInput = document.getElementById('search-category');
var optionItems = document.querySelectorAll('.custom-option');
// Toggle dropdown
wrap.addEventListener('click', function (e) {
e.stopPropagation();
options.classList.toggle('show');
});
// Pilihan dropdown diklik
optionItems.forEach(function (item) {
item.addEventListener('click', function (e) {
e.stopPropagation();
optionItems.forEach(opt => opt.classList.remove('selected'));
this.classList.add('selected');
trigger.textContent = this.textContent;
hiddenInput.value = this.getAttribute('data-value');
options.classList.remove('show');
jalankanPencarian();
});
});
// Tutup dropdown jika klik di luar
document.addEventListener('click', function () {
options.classList.remove('show');
});
});