All,
This is a Proof of Concept sample that I was working on. I have taken the LayerList widget and enhanced it to allow for collapsing the widget layers and sublayers. It is simple css and dom manipulation. I have tested this with a deeply nested map service layer and it works well. I am not sure esri will be spending time on the 3.x version to add enhancements like this so I did.
Here is the Live Preview Site
And Attached is the sample code:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
<title>Layer List Dijit</title>
<link rel="stylesheet" href="http://js.arcgis.com/3.14/dijit/themes/claro/claro.css">
<link rel="stylesheet" href="http://js.arcgis.com/3.14/esri/css/esri.css">
<style>
html,
body,
.container,
#map {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
margin: 0;
font-family: "Open Sans";
}
#map {
padding: 0;
}
#layerListPane {
width: 25%;
}
.esriLayer {
background-color: #fff;
}
.esriLayerList .esriList {
border-top: none;
}
.esriLayerList .esriTitle {
background-color: #fff;
border-bottom: none;
}
.esriLayerList .esriList ul {
background-color: #fff;
}
/*css rules for the expand div*/
.esriLayerExpand {
width: 16px;
height: 16px;
float: left;
margin: 12px 0;
}
.esriLayerExpand.expand {
background-image: url(images/v_right.png);
background-repeat: no-repeat;
background-position: center;
cursor: pointer;
}
.esriLayerExpand.collapse{
background-image: url(images/v.png);
background-repeat: no-repeat;
background-position: center;
cursor: pointer;
}
/*narrow the margin of the checkbox for aesthetics*/
.esriLayerList .esriCheckbox {
margin: 12px 5px 12px 5px;
}
</style>
<script>
var dojoConfig = {
parseOnLoad: true
};
</script>
<script src="http://js.arcgis.com/3.14/"></script>
<script>
require([
"esri/map",
"esri/layers/ArcGISDynamicMapServiceLayer",
"esri/dijit/LayerList",
"dojo/query",
"dojo/dom-construct",
"dojo/dom-class",
"dojo/dom-style",
"dojo/on",
"dojo/_base/array",
"dijit/layout/BorderContainer",
"dijit/layout/ContentPane",
"dojo/domReady!"
], function (
Map,
ArcGISDynamicMapServiceLayer,
LayerList,
query,
domConstruct,
domClass,
domStyle,
on,
array
) {
var map = new Map("map", {
basemap: "topo",
center: [-123, 47],
zoom: 8,
sliderStyle: "small"
});
var atlasLayer = new ArcGISDynamicMapServiceLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer", {
"id": "atlasLayer",
"showAttribution": false
});
var recreationLayer = new ArcGISDynamicMapServiceLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Recreation/MapServer", {
"id": "recreationLayer",
"showAttribution": false
});
var waterNetLayer = new ArcGISDynamicMapServiceLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Water_Network/MapServer", {
"id": "waterNetworkLayer",
"showAttribution": false
})
map.addLayers([atlasLayer, recreationLayer, waterNetLayer]);
var llWidget = new LayerList({
map: map,
layers: [{
layer: atlasLayer,
id: "Atlas layers",
subLayers: true
},
{
layer: recreationLayer,
id: "Recreation layers",
subLayers: true
},
{
layer: waterNetLayer,
id: "Water Network layers",
subLayers: true
}]
},"layerList");
llWidget.startup();
/*When the LayerList is loaded enhance it to add collapse capabilities*/
llWidget.on('load', function(){
enhanceLayerList();
});
/*Work with all the layers*/
function enhanceLayer(layerNode){
layerExpand = domConstruct.create('div');
domClass.add(layerExpand, 'esriLayerExpand collapse');
domConstruct.place(layerExpand, layerNode, 'first');
on(layerExpand, 'click', function(evt){
var LayerNodes = query('.esriLayer');
var SubList = query('.esriSubList', evt.target.parentNode);
if(domClass.contains(evt.target, 'collapse')){
domClass.replace(evt.target, 'expand', 'collapse');
domStyle.set(SubList[0], 'display', 'none');
}else{
domClass.replace(evt.target, 'collapse', 'expand');
domStyle.set(SubList[0], 'display', '');
}
});
var subListNodes = query('.esriSubListLayer', layerNode);
if(subListNodes.length > 0){
array.map(subListNodes, function(subListNode){
enhanceSubList(subListNode);
});
}
}
/*Now work with all the sublayers*/
function enhanceSubList(subLayerNode){
var subLayerExpand;
var subListNodes = query('.esriSubListLayer', subLayerNode);
if(subListNodes.length > 0){
subLayerExpand = domConstruct.create('div');
domClass.add(subLayerExpand, 'esriLayerExpand collapse');
domConstruct.place(subLayerExpand, subLayerNode, 'first');
on(subLayerExpand, 'click', function(evt){
var cState = '';
var subListLayerNodes = query('.esriSubListLayer', evt.target.parentNode);
if(domClass.contains(evt.target, 'collapse')){
domClass.replace(evt.target, 'expand', 'collapse');
cState = 'collapse';
}else{
domClass.replace(evt.target, 'collapse', 'expand');
cState = 'expand';
}
array.map(subListLayerNodes, function(subListLayerNode){
if(cState === 'collapse'){
domStyle.set(subListLayerNode, 'display', 'none');
}else{
domStyle.set(subListLayerNode, 'display', 'block');
}
});
});
}else{
subLayerExpand = domConstruct.create('div');
domClass.add(subLayerExpand, 'esriLayerExpand');
domConstruct.place(subLayerExpand, subLayerNode, 'first');
}
}
/*Begin with the individual layers*/
function enhanceLayerList() {
var layerExpand, subLayerExpand;
var LayerNodes = query('.esriLayer');
array.map(LayerNodes, function(layerNode){
enhanceLayer(layerNode);
});
}
});
</script>
</head>
<body class="claro">
<div class="container" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline',gutters:false">
<div id="layerListPane" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'right'">
<div id="layerList"></div>
</div>
<div id="map" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'"></div>
</div>
</body>
</html>