Add per-band filter checkboxes with All/None to contacts map

This commit is contained in:
Graham McIntire 2026-04-11 14:46:14 -05:00
parent ff1b2d0cbe
commit ab8773acd0

View file

@ -113,22 +113,65 @@ export const ContactsMap = {
}
dotLayer.addTo(this.map)
// Build legend
const legend = L.control({position: "bottomright"})
legend.onAdd = function() {
// Build interactive band filter
const bandControl = L.control({position: "bottomright"})
const self = this
bandControl.onAdd = function(map) {
const div = L.DomUtil.create("div")
div.style.cssText = "background:rgba(30,30,40,0.9);color:#fff;padding:8px 12px;border-radius:8px;font-size:11px;line-height:1.6;"
div.style.cssText = "background:rgba(30,30,40,0.95);color:#fff;padding:8px 12px;border-radius:8px;font-size:11px;line-height:1.8;"
L.DomEvent.disableClickPropagation(div)
L.DomEvent.disableScrollPropagation(div)
const sorted = Object.entries(byBand).sort((a, b) => parseInt(a[0]) - parseInt(b[0]))
let html = "<div style='font-weight:700;margin-bottom:4px;'>Bands</div>"
let html = `<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:4px;">
<span style="font-weight:700;">Bands</span>
<span style="display:flex;gap:6px;">
<button id="bands-all" style="background:none;border:none;color:#7dd;cursor:pointer;font-size:10px;text-decoration:underline;">All</button>
<button id="bands-none" style="background:none;border:none;color:#d77;cursor:pointer;font-size:10px;text-decoration:underline;">None</button>
</span>
</div>`
for (const [band, entries] of sorted) {
const color = bandColor(parseInt(band))
const label = bandLabel(parseInt(band))
html += `<div><span style="display:inline-block;width:14px;height:3px;background:${color};margin-right:6px;vertical-align:middle;border-radius:1px;"></span>${label} (${entries.length.toLocaleString()})</div>`
html += `<label style="display:flex;align-items:center;gap:6px;cursor:pointer;">
<input type="checkbox" data-band="${band}" checked style="accent-color:${color};cursor:pointer;">
<span style="display:inline-block;width:14px;height:3px;background:${color};border-radius:1px;flex-shrink:0;"></span>
<span>${label} (${entries.length.toLocaleString()})</span>
</label>`
}
div.innerHTML = html
// Wire up checkboxes
div.querySelectorAll("input[data-band]").forEach(cb => {
cb.addEventListener("change", () => {
const band = cb.dataset.band
if (cb.checked) {
bandLayers[band].addTo(map)
} else {
bandLayers[band].remove()
}
})
})
div.querySelector("#bands-all").addEventListener("click", () => {
div.querySelectorAll("input[data-band]").forEach(cb => {
cb.checked = true
bandLayers[cb.dataset.band].addTo(map)
})
})
div.querySelector("#bands-none").addEventListener("click", () => {
div.querySelectorAll("input[data-band]").forEach(cb => {
cb.checked = false
bandLayers[cb.dataset.band].remove()
})
})
return div
}
legend.addTo(this.map)
bandControl.addTo(this.map)
}
}