I have a Leaflet map with a long legend of relevant points.
The legend is just a div
with text (no icons, no markers, no layers on the map).
You can see it here.
I add the legend to the map with this code:
<script>
var legend = L.control({position: 'bottomright'});
legend.onAdd = function (map) {
var div = L.DomUtil.create('div', 'info legend'),
grades = ["1: ","2: "],
labels = ["via Roma/Portela","piazza S. Maria Maggiore"];
for (var i = 0; i < grades.length; i++) {
div.innerHTML +=
grades[i] + labels[i] +'<br>';
}
return div;
};
legend.addTo(map);
</script>
I would like to make the legend collapsible, so that users can see it if they need to. I found this plugin on Github, which unluckily seems to work with markers in the legend. In mine I only have text strings.
No plugins needed, you can really build it yourself. The following code doesn't need much explanation. We just create two containers. The first contains the button and the second consists of legend elements. The second container is hidden, only clicking on the first one causes it to be shown.
let config = {
minZoom: 7,
maxZoom: 18,
};
const zoom = 18;
const lat = 52.22977;
const lng = 21.01178;
const map = L.map("map", config).setView([lat, lng], zoom);
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution:
'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
}).addTo(map);
L.Control.Button = L.Control.extend({
options: {
position: "bottomright",
},
onAdd: function (map) {
const container = L.DomUtil.create(
"div",
"leaflet-bar leaflet-control leaflet-legend"
);
container.title = "Legends";
const button = L.DomUtil.create(
"div",
"leaflet-control-button leaflet-legend-action",
container
);
button.insertAdjacentHTML(
"afterbegin",
"<div class='action'>LEGENDS <div class='arrow'>↑</div></div>"
);
const legendWrapper = L.DomUtil.create(
"div",
"legend-wrapper hidden",
container
);
const labels = ["via Roma/Portela", "piazza S. Maria Maggiore"];
labels.forEach((label, index) => {
const row = `<div>${index + 1}: ${label}</div>`;
legendWrapper.insertAdjacentHTML("beforeend", row);
});
L.DomEvent.disableClickPropagation(button);
L.DomEvent.on(button, "click", function (e) {
const parent = e.target;
parent.parentNode.classList.toggle("is-active");
parent.parentNode.nextElementSibling.classList.toggle("hidden");
});
return container;
},
onRemove: function (map) {},
});
const control = new L.Control.Button();
control.addTo(map);
*,
:after,
:before {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html {
height: 100%;
}
body,
html,
#map {
width: 100%;
height: 100%;
}
body {
position: relative;
min-height: 100%;
margin: 0;
padding: 0;
background-color: #f1f1f1;
}
.leaflet-legend {
background: #fff;
padding: 2px 5px;
border-radius: 5px;
min-width: 200px;
}
.hidden {
display: none;
}
.action {
cursor: pointer;
}
.arrow {
display: inline-block;
pointer-events: none;
line-height: 100%;
}
.is-active .arrow {
rotate: 180deg;
}
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.2/dist/leaflet.css"/>
<script src="https://unpkg.com/leaflet@1.9.2/dist/leaflet.js"></script>
<div id="map"></div>
<script src="script.js"></script>