Skip to content

Commit 883f4ba

Browse files
committed
Adding feature to make individual groups collapsable
ismyrnow#46 squashed + lint fixed Collapsable Groups. Added a config option "groupsCollapsable" which if set to true, will make each group header individually collapsable. This is useful when dealing with either small map elements, or a larger number of layers within the groups. Also added two supporting config settings: "groupsCollapseClass" and "groupsExpandClass" which control the css styles used for the toggle indicators, allowing users to override the default +/- indicators. Setting one to "glyphicon glyphicon-chevron-right" will use the glyphicon provided with bootstrap for example.
1 parent 992abb8 commit 883f4ba

File tree

6 files changed

+152
-3
lines changed

6 files changed

+152
-3
lines changed

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,25 @@ L.control.groupedLayers(baseLayers, groupedOverlays, options).addTo(map);
5959

6060
![advanced preview](preview-advanced.png)
6161

62+
#### Collapsable Groups
63+
64+
Enabling collapsable groups in the switcher can be done with the following options
65+
66+
```javascript
67+
var options = {
68+
// enable basic collapsability
69+
groupsCollapsable: true,
70+
// (Optional) The css class(es) used to indicated the group is expanded
71+
groupsExpandedClass: "glyphicon glyphicon-chevron-down",
72+
// (Optional) The css class(es) used to indicated the group is collapsed
73+
groupsCollapsedClass: "glyphicon glyphicon-chevron-right"
74+
};
75+
76+
L.control.groupedLayers(baseLayers, groupedOverlays, options).addTo(map);
77+
```
78+
79+
![collapsable preview](preview-collapsable.png)
80+
6281
### Adding a layer
6382

6483
Adding a layer individually works similarly to the default layer control,

example/collapsable-advanced.html

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>Collapsable Example (Bootstrap Glyphicons)</title>
5+
<meta charset="utf-8" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.3/leaflet.css" />
8+
<link rel="stylesheet" href="../src/leaflet.groupedlayercontrol.css" />
9+
10+
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
11+
12+
</head>
13+
<body>
14+
<div id="map" style="width: 600px; height: 400px"></div>
15+
16+
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.3/leaflet.js"></script>
17+
<script src="../src/leaflet.groupedlayercontrol.js"></script>
18+
<script src="exampledata.js"></script>
19+
<script>
20+
var map = L.map('map', {
21+
center: [39.73, -104.99],
22+
zoom: 10,
23+
layers: [ExampleData.Basemaps.Grayscale, ExampleData.LayerGroups.cities]
24+
});
25+
26+
// Overlay layers are grouped
27+
var groupedOverlays = {
28+
"Landmarks": {
29+
"Cities": ExampleData.LayerGroups.cities,
30+
"Restaurants": ExampleData.LayerGroups.restaurants
31+
},
32+
"Random": {
33+
"Dogs": ExampleData.LayerGroups.dogs,
34+
"Cats": ExampleData.LayerGroups.cats
35+
}
36+
};
37+
38+
// Use the custom grouped layer control, not "L.control.layers"
39+
L.control.groupedLayers(ExampleData.Basemaps, groupedOverlays, {groupsCollapsable: true, groupsExpandedClass: "glyphicon glyphicon-chevron-down", groupsCollapsedClass: "glyphicon glyphicon-chevron-right"}).addTo(map);
40+
</script>
41+
</body>
42+
</html>

example/collapsable-basic.html

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>Collapsable Example</title>
5+
<meta charset="utf-8" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.3/leaflet.css" />
8+
<link rel="stylesheet" href="../src/leaflet.groupedlayercontrol.css" />
9+
</head>
10+
<body>
11+
<div id="map" style="width: 600px; height: 400px"></div>
12+
13+
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.3/leaflet.js"></script>
14+
<script src="../src/leaflet.groupedlayercontrol.js"></script>
15+
<script src="exampledata.js"></script>
16+
<script>
17+
var map = L.map('map', {
18+
center: [39.73, -104.99],
19+
zoom: 10,
20+
layers: [ExampleData.Basemaps.Grayscale, ExampleData.LayerGroups.cities]
21+
});
22+
23+
// Overlay layers are grouped
24+
var groupedOverlays = {
25+
"Landmarks": {
26+
"Cities": ExampleData.LayerGroups.cities,
27+
"Restaurants": ExampleData.LayerGroups.restaurants
28+
},
29+
"Random": {
30+
"Dogs": ExampleData.LayerGroups.dogs,
31+
"Cats": ExampleData.LayerGroups.cats
32+
}
33+
};
34+
35+
// Use the custom grouped layer control, not "L.control.layers"
36+
L.control.groupedLayers(ExampleData.Basemaps, groupedOverlays, {groupsCollapsable: true}).addTo(map);
37+
</script>
38+
</body>
39+
</html>

preview-collapsable.png

4.65 KB
Loading

src/leaflet.groupedlayercontrol.css

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,23 @@
1212
overflow-y: scroll;
1313
padding-right: 10px;
1414
}
15+
16+
.leaflet-control-layers-group.group-collapsable.collapsed .leaflet-control-layers-group-collapse,
17+
.leaflet-control-layers-group.group-collapsable:not(.collapsed) .leaflet-control-layers-group-expand,
18+
.leaflet-control-layers-group.group-collapsable.collapsed label:not(.leaflet-control-layers-group-label){
19+
display: none;
20+
}
21+
22+
.leaflet-control-layers-group-expand-default:before{
23+
content: "+";
24+
width: 12px;
25+
display: inline-block;
26+
text-align: center;
27+
}
28+
29+
.leaflet-control-layers-group-collapse-default:before{
30+
content: "-";
31+
width: 12px;
32+
display: inline-block;
33+
text-align: center;
34+
}

src/leaflet.groupedlayercontrol.js

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@ L.Control.GroupedLayers = L.Control.extend({
1010
autoZIndex: true,
1111
exclusiveGroups: [],
1212
groupCheckboxes: false,
13+
groupsCollapsable: false,
14+
groupsExpandedClass: 'leaflet-control-layers-group-collapse-default',
15+
groupsCollapsedClass: 'leaflet-control-layers-group-expand-default',
1316
// Whether to sort the layers. When `false`, layers will keep the order
1417
// in which they were added to the control.
1518
sortLayers: false,
16-
// A [compare function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)
19+
// A [compare function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)
1720
// that will be used for sorting the layers, when `sortLayers` is `true`.
1821
// The function receives both the `L.Layer` instances and their names, as in
1922
// `sortFunction(layerA, layerB, nameA, nameB)`.
@@ -83,7 +86,7 @@ L.Control.GroupedLayers = L.Control.extend({
8386
var id = L.Util.stamp(layer);
8487
var _layer = this._getLayer(id);
8588
if (_layer) {
86-
delete this.layers[this.layers.indexOf(_layer)];
89+
this._layers.splice(this._layers.indexOf(_layer), 1);
8790
}
8891
this._update();
8992
return this;
@@ -296,6 +299,21 @@ L.Control.GroupedLayers = L.Control.extend({
296299
}
297300
}
298301

302+
if (this.options.groupsCollapsable) {
303+
groupContainer.classList.add('group-collapsable');
304+
groupContainer.classList.add('collapsed');
305+
306+
var groupMin = document.createElement('span');
307+
groupMin.className = 'leaflet-control-layers-group-collapse '+this.options.groupsExpandedClass;
308+
groupLabel.appendChild(groupMin);
309+
310+
var groupMax = document.createElement('span');
311+
groupMax.className = 'leaflet-control-layers-group-expand '+this.options.groupsCollapsedClass;
312+
groupLabel.appendChild(groupMax);
313+
314+
L.DomEvent.on(groupLabel, 'click', this._onGroupCollapseToggle, groupContainer);
315+
}
316+
299317
var groupName = document.createElement('span');
300318
groupName.className = 'leaflet-control-layers-group-name';
301319
groupName.innerHTML = obj.group.name;
@@ -317,7 +335,18 @@ L.Control.GroupedLayers = L.Control.extend({
317335
return label;
318336
},
319337

320-
_onGroupInputClick: function () {
338+
_onGroupCollapseToggle: function (event) {
339+
L.DomEvent.stopPropagation(event);
340+
L.DomEvent.preventDefault(event);
341+
if (this.classList.contains('group-collapsable') && this.classList.contains('collapsed')) {
342+
this.classList.remove('collapsed');
343+
} else if (this.classList.contains('group-collapsable') && !this.classList.contains('collapsed')) {
344+
this.classList.add('collapsed');
345+
}
346+
},
347+
348+
_onGroupInputClick: function (event) {
349+
L.DomEvent.stopPropagation(event);
321350
var i, input, obj;
322351

323352
var this_legend = this.legend;

0 commit comments

Comments
 (0)