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>
Thanks Robert!
The 3.15 version of the LayerList widget has some additional functionality, including collapsible layers. It also includes the legend items. One thing I did notice is that this legend list is only updated when the view is zoomed in or out (but not when it is panned), not when the checkbox is clicked.
Hi, so the layerlist is collapsible out of the box? I didn't see that in the API...Can you point me in the right direction?
it is a property called showsublayers:
https://developers.arcgis.com/javascript/3/jsapi/layerlist-amd.html#showsublayers
or the widgets ui has arrows for expanding and collapsing.
Rob,
Have you created a enhanced layer list widget for the WAB from this?
Thanks!
Daniel,
No I have not as this was more of a proof of concept. I have considered creating a eLayerList widget but my widget development list is pretty big already.
Rob,
Thanks for the reply. Another poster mentioned an "Enhanced Layer List Widget" here in this post:
Any idea what they are referring to?
~ D
Daniel,
No there is not an enhanced Layer list widget out there that I am aware of.
Hi Robert ! Another amazing solution but how can i set this up in my Webappbuilder ? Should i unzip this as new widget or update the current LayerList ? I could not find a LayerListWidget.html to replace on the source code. Thank you.