JSAPI 4.x LayerList and Legend Together

3166
1
01-23-2017 10:54 AM
DavidColey
Frequent Contributor

Hi - so we found a way to enable the legend to work with the layer list at 4.2 using the 'trigger-action' info from the layer list sample code.  First, we set up a defineActions function to store the returns in an array of the layerLists' items:

function defineActions(event) {
    //console.log(event);
    // The event object contains properties of the layer in the LayerList widget.
    var item = event.item;
    //console.log(item);
       if (item.title === "Environmental Project"){
          return [
             [{
                title: "Show Legend",
                className: "esri-icon-layer-list",
                id: "show-environmental"
             }]
           ];
          } else if (item.title === "Facilities Project"){
             return [
             [{
                title: "Show Legend",
                className: "esri-icon-layer-list",
                id: "show-facilities"
             }]
            ];
 
          } else if (item.title === "Mobility Project"){
               return [
                [{
                      title: "Show Legend",
                      className: "esri-icon-layer-list",
                      id: "show-transportation"
                }]
           ];
    }
}

Then set up a function that, upon view load, (1) sets up the layerList with it's createActionsFunction and a layerInfo nested array that contains the layerInfos as would be defined in the legend and an initial layerInfoIndex, (2) sets up the legend with the layerInfo var, (3) sets up a index function that will set (via a modulus) the layer info index each time it's called as part of (4), the layerList.on trigger-action event:

app.mapView.then(function(result) {
       layerList = new LayerList({ //LayerList
          container: "collapseList",
          view: app.mapView,
          createActionsFunction: defineActions
    });
       var layerInfo = [
          {layerInfos: [{
             layer: lyrEnvBnds,
             title: "Environmental Project"
         }]},
          {layerInfos: [{
             layer: lyrFacBnds,
             title: "Facilities Project"
          }]}
      ],
 layerInfoIndex = 0; //initial

 legend = new Legend({
       container: "collapseLegend",
       view: app.activeView,
       layerInfos: [{
          layer: layerInfo[layerInfoIndex].layerInfos.layer,
          title: layerInfo[layerInfoIndex].layerInfos.title
       }]
    });
 function changeLegend(layerInfoIndex) {
    console.log(layerInfoIndex);
    legend.set(layerInfo[layerInfoIndex % layerInfo.length]); // % Modulus
    console.log(layerInfo);
 }
 layerList.on("trigger-action", function(event) {
    console.log(event);
    var id = event.action.id;
       if (id === "show-environmental"){
          changeLegend(0); 
          query("#collapseLegend").toggleClass("collapse in");
       } else if (id === "show-facilities"){
          changeLegend(1);
          query("#collapseLegend").toggleClass("collapse in");
       }
    });
 });

There's alot going on here and I likely haven't decribed things fully or even fully accurate.  We are working in Calcite maps and as such taking advantage of the css classes for 'collapse in' for the dojo query's toggleClass method.  But it seems to work well in that each trigger-action fires the changeLegend funtion, getting the correct legend layer to display below the layerList widget:

Great job mstranovsky‌ for setting the initial index; for handling the super-tricky layerInfo and layerInfos arrays; and for the modulus method for the changeLegend function.

Hopefully this is just a workaround until the legend is properly incorporated into the layerList widget and please feel free to add your comments

Cheers-

David

Tags (1)
1 Reply
DavidColey
Frequent Contributor

An Update:

Turns out we don't need these dojo\query for css classes in the trigger-action event 

layerList.on("trigger-action", function(event) {
 console.log(event);
 var id = event.action.id;
 if (id === "show-environmental"){
 changeLegend(0); 
 //query("#collapseLegend").toggleClass("collapse in");‍‍‍‍‍‍

and we can also set the layer list and legend in the same container:

layerList = new LayerList({ //LayerList
          container: "collapseLegend",

legend = new Legend({
       container: "collapseLegend",‍‍‍‍‍

in our calcite-bootstrap maps project you can then bring in the panel:

<div id="panelLegend" class="panel collapse">
    <div id="headingLegend" class="panel-heading" role="tab">
       <div class="panel-title">
          <a class="panel-toggle collapsed" role="button" data-toggle="collapse" href="#collapseLegend" aria-expanded="false" aria-controls="collapseLegend">
             <span class="glyphicon glyphicon-list" aria-hidden="true"></span>
             <span class="panel-label visible-mobile-only">Legend</span>
          </a> 
          <a class="panel-close visible-mobile-only" role="button" data-toggle="collapse" data-target="#panelLegend">
             <span class="esri-icon esri-icon-close" aria-hidden="true"></span>
          </a> 
       </div>
 </div>
    <div id="collapseLegend" class="panel-collapse collapse esri-layer-list esri-legend esri-widget" role="tabpanel" aria-labelledby="headingLegend"></div>
 </div>
0 Kudos