Collapsible Layer List

2306
13
Jump to solution
11-14-2018 08:08 AM
jaykapalczynski
Frequent Contributor

Looking for any examples of a collapsible layer list that Auto fills with my layers.

I have seen some really basic layer list examples on the api page but nothing that allows collapsible areas and auto filling of your layers.

I am trying to create 3 different areas as seen below.  Were the box next to the ------------- would collapse that section.

But I want it to auto fill the layers from my .js page.

Right now I am adding layers to the list and adding check boxes BUT THERE it is not collapsible 

legendLayers.push({ layer: FloodZonelayer, title: 'Flood Zones' });


 // ADD CHECK BOXES FOR LAYERS
 map.on('layers-add-result', function () {
 //add check boxes
 arrayUtils.forEach(legendLayers, function (layer) {
 var layerName = layer.title;
 var checkBox = new CheckBox({
 name: "checkBox" + layer.layer.id,
 value: layer.layer.id,
 checked: layer.layer.visible
 });
 checkBox.on("change", function () {
 var targetLayer = map.getLayer(this.value);
 targetLayer.setVisibility(!targetLayer.visible);
 this.checked = targetLayer.visible;
 });
 //add the check box and label to the toc
 domConstruct.place(checkBox.domNode, dom.byId("toggle"), "after");
 var checkLabel = domConstruct.create('label', {
 'for': checkBox.name,
 innerHTML: layerName
 }, checkBox.domNode, "after");
 domConstruct.place("<br />", checkLabel, "after");
 });
});

 //ADD THE LEGEND AND XY COORDINATES
 map.on("layers-add-result", function (evt) {

 // CYCLE through and grab all the layer names to add to the LEGEND PLUS
 // Remove layers not inteneted for the legend.
 var layerInfo = arrayUtils.map(evt.layers, function (layer, index) {
 if (layer.layer.id === "PastLocations" || layer.layer.id === "District" || layer.layer.id === "weatherlayer") { return { }; } //Hides Layers in the Legend
 else { return { layer: layer.layer, title: layer.layer.name }; } //Else return All others
 });
 // CYCLE through and grab all the layer names to add to the LEGEND
 if (layerInfo.length > 0) {
 var legendDijit = new Legend({
 map: map,
 layerInfos: layerInfo,
 }, "legend");
 legendDijit.startup();
 legendDijit.refresh();
 }

 });
0 Kudos
13 Replies
RobertScheitlin__GISP
MVP Emeritus

Not possible.

0 Kudos
jaykapalczynski
Frequent Contributor

So there is no way to build a layer list that includes specific layers from multiple features and have the ability to collapse?

I guess I can create my own accordions and add 3 different Layer Lists (like I am using now)....seems like a lot of code for something so small...

Thanks for your help

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Yep it has been requested by many for a very long time now...

0 Kudos
jaykapalczynski
Frequent Contributor

I know this is not the way to do this although I don know of any other way to accomplish what I am looking for...

This is how I put on a large band-aid

  1. I still have to clean up the CSS to hide the clumsiness of this approach...especially with nesting the accordion panes..
  2. I still have to clean up my code so don't be too judgmental I repeated the code to build the legend layers in each of the accordion panes.
  3. I can put if then statements in this section to decrease the amount of code - map.on('layers-add-result', function () {

This gives you something like this in your panel... I have a container for Weather, Incidents, Other Layers.

If I do a little CSS work I can get ride of the frames and color backgrounds and make this look a little more appealing.

The example below does not have all the layers in the image.  In my below example it would simply put one feature layer in each of the 3 accordions

Follow the "legendLayers1.push" below from each FeatureLayer to the function below it.

legendLayers1.push({ layer: WeatherImpactWashout, title: 'WeatherImpact Washout' });

legendLayers2.push({ layer: WeatherImpactWashout, title: 'WeatherImpact Washout' });

legendLayers2.push({ layer: WeatherImpactWashout, title: 'WeatherImpact Washout' });

<div id="IDAccordionPaneLayers" data-dojo-type="dijit.layout.AccordionContainer" style="color:black; height:90%; width:90%;">                    
     <div id="idLayers2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title:'Weather'" >
         <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="title:'Natural Disasters'">
          <div id="toggle2" style="padding: 2px 2px; color:Black;"></div>
         </div>
     </div>          
     <div id="idLayers3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title:'Incidents & Traffic'" >
         <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="title:'Natural Disasters'">
          <div id="toggle3" style="padding: 2px 2px; color:Black;"></div>
         </div>
     </div>     
     <div id="idLayers1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title:'Layers1'" >
         <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="title:'Natural Disasters'">
          <div id="toggle1" style="padding: 2px 2px; color:Black;"></div>
         </div>
     </div>                    
</div>
var WeatherImpactPowerLines = new FeatureLayer("https://arcgis.vdem.virginia.gov/ArcGIS/rest/services/Traffic/VATraffic_WeatherImpactPoints/MapServe...", {
     mode: FeatureLayer.MODE_ONDEMAND,
     visible: false,
     outFields:["*"],
     infoTemplate: infoWeatherImpact
});
legendLayers1.push({ layer: WeatherImpactPowerLines, title: 'WeatherImpact Power Lines' });

var WeatherImpactOther = new FeatureLayer("https://arcgis.vdem.virginia.gov/ArcGIS/rest/services/Traffic/VATraffic_WeatherImpactPoints/MapServe...", {
     mode: FeatureLayer.MODE_ONDEMAND,
     visible: false,
     outFields:["*"],
     infoTemplate: infoWeatherImpact
});
legendLayers2.push({ layer: WeatherImpactOther, title: 'WeatherImpact Other' });
          
var WeatherImpactPassable = new FeatureLayer("https://arcgis.vdem.virginia.gov/ArcGIS/rest/services/Traffic/VATraffic_WeatherImpactPoints/MapServe...", {
     mode: FeatureLayer.MODE_ONDEMAND,
     visible: false,
     outFields:["*"],
     infoTemplate: infoWeatherImpact
});
legendLayers3.push({ layer: WeatherImpactPassable, title: 'WeatherImpact Passable' });




// ADD CHECK BOXES FOR LAYERS
map.on('layers-add-result', function () {
     //add check boxes
     arrayUtils.forEach(legendLayers1, function (layer) {
          var layerName = layer.title;
          var checkBox = new CheckBox({
               name: "checkBox" + layer.layer.id,
               value: layer.layer.id,
               checked: layer.layer.visible
          });
          checkBox.on("change", function () {
                var targetLayer = map.getLayer(this.value);
               targetLayer.setVisibility(!targetLayer.visible);
               this.checked = targetLayer.visible;
          });
          //add the check box and label to the toc
          //domConstruct.place(checkBox.domNode, dom.byId("toggle"), "after");
          domConstruct.place(checkBox.domNode, dom.byId("toggle1"), "after");
                  var checkLabel = domConstruct.create('label', {
                   'for': checkBox.name,
                   innerHTML: layerName
               }, checkBox.domNode, "after");
               domConstruct.place("<br />", checkLabel, "after");
     });
     arrayUtils.forEach(legendLayers2, function (layer) {
          var layerName = layer.title;
          var checkBox = new CheckBox({
               name: "checkBox" + layer.layer.id,
               value: layer.layer.id,
               checked: layer.layer.visible
          });
          checkBox.on("change", function () {
                var targetLayer = map.getLayer(this.value);
               targetLayer.setVisibility(!targetLayer.visible);
               this.checked = targetLayer.visible;
          });
          //add the check box and label to the toc
          //domConstruct.place(checkBox.domNode, dom.byId("toggle"), "after");
          domConstruct.place(checkBox.domNode, dom.byId("toggle1"), "after");
                  var checkLabel = domConstruct.create('label', {
                   'for': checkBox.name,
                   innerHTML: layerName
               }, checkBox.domNode, "after");
               domConstruct.place("<br />", checkLabel, "after");
     });               
     arrayUtils.forEach(legendLayers3, function (layer) {
          var layerName = layer.title;
          var checkBox = new CheckBox({
               name: "checkBox" + layer.layer.id,
               value: layer.layer.id,
               checked: layer.layer.visible
          });
          checkBox.on("change", function () {
                var targetLayer = map.getLayer(this.value);
               targetLayer.setVisibility(!targetLayer.visible);
               this.checked = targetLayer.visible;
          });
          //add the check box and label to the toc
          //domConstruct.place(checkBox.domNode, dom.byId("toggle"), "after");
          domConstruct.place(checkBox.domNode, dom.byId("toggle1"), "after");
                  var checkLabel = domConstruct.create('label', {
                   'for': checkBox.name,
                   innerHTML: layerName
               }, checkBox.domNode, "after");
               domConstruct.place("<br />", checkLabel, "after");
     });     
               
});     

          
//ADD THE LEGEND AND XY COORDINATES 
map.on("layers-add-result", function (evt) {

// CYCLE through and grab all the layer names to add to the LEGEND PLUS 
// Remove layers not inteneted for the legend.
     var layerInfo = arrayUtils.map(evt.layers, function (layer, index) {
          if (layer.layer.id === "PastLocations" || layer.layer.id === "District" || layer.layer.id === "weatherlayer") { return { }; } //Hides Layers in the Legend 
                else { return { layer: layer.layer, title: layer.layer.name }; } //Else return All others
     }); 
// CYCLE through and grab all the layer names to add to the LEGEND
     if (layerInfo.length > 0) {
          var legendDijit = new Legend({
          map: map,
          layerInfos: layerInfo,
          }, "legend");
          legendDijit.startup(); 
             legendDijit.refresh(); 
          }
});


map.addLayers([
WeatherImpactPassable,WeatherImpactOther,WeatherImpactPowerLines
]);‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍