Legend not updating when layers are reordered/added

2845
3
Jump to solution
07-13-2012 12:08 PM
GeorgeSimpson
Occasional Contributor
I've modified the sample for reordering layers found at: http://help.arcgis.com/en/webapi/javascript/arcgis/help/jssamples_start.htm#jssamples/layers_dynamic... to include a legend.  When the layers are reordered or when the lakes layer is added, the legend does not reflect the change.

Here's my code:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=7,IE=9" />
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
    <title>dynamic layer in legend</title>
    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.0/js/dojo/dijit/themes/tundra/tundra.css" />
    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.0/js/esri/dijit/css/Popup.css" />
    <style>
      html, body { height: 100%; width: 100%; margin: 0; padding: 0; }
      h3 { margin: 0 0 5px 0; border-bottom: 1px solid #444; }
      .shadow {
        -moz-box-shadow: 0 0 5px #888;
        -webkit-box-shadow: 0 0 5px #888;
        box-shadow: 0 0 5px #888;
      }
      #map{ margin: 0; padding: 0; }
      #feedback {
        background: #fff;
        color: #444;
        position: absolute;
        font-family: arial;
        
        left: 30px;
        margin: 5px;
        padding: 10px;
        top: 30px;
        width: 300px;
        z-index: 40;
      }      
      
      #layerList {
        width: 200px;
      }
      .dojoDndItemOver {
        background: #ccc;
      }
    </style>
    <script>        var dojoConfig = { parseOnLoad: true };</script>
    <script src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=3.0"></script>
    <script>
        dojo.require("dojo.dnd.Source");
        dojo.require("dijit.layout.BorderContainer");
        dojo.require("dijit.layout.ContentPane");
        dojo.require("dijit.form.Button");
        dojo.require("esri.map");
        dojo.require("esri.dijit.Popup");
        dojo.require("esri.dijit.Legend");

        // one global for persistent app variables
        var app = {};

        function init() {
            var ext = new esri.geometry.Extent({ "xmin": -11080843, "ymin": 5585370, "xmax": -9766126, "ymax": 6260462, "spatialReference": { "wkid": 102100} });
            var popup = new esri.dijit.Popup(null, dojo.create("div"));
            var legend;

            app.map = new esri.Map("map", {
                "extent": ext,
                "infoWindow": popup,
                "slider": false
            });
            

            urlDyn = "http://servicesbeta2.esri.com/arcgis/rest/services/USA/MapServer";
            usaLayer = new esri.layers.ArcGISDynamicMapServiceLayer(urlDyn, { "id": "usa" });
            app.map.addLayers([usaLayer]);

            // build the layer list
            if (usaLayer.loaded) {
                buildList(usaLayer);
            } else {
                dojo.connect(usaLayer, "onLoad", buildList);
            }

            // hide the loading icon when the counties layer finishes updating
            dojo.connect(usaLayer, "onUpdateEnd", function () {
                dojo.style(dojo.byId("loading"), "display", "none");
                // rebuild the layer list
                buildList(app.map.getLayer("usa"));
            });

            // add the lakes layer to the existing map service
            dojo.connect(dijit.byId("lakes"), "onClick", addLakes);

            dojo.connect(app.map, 'onLayersAddResult', function (results) {
                //esri.show(dojo.byId('legendDiv'));
                if (!app.legend) {
                    //add the legend to show the resulting layer. 
                    var layerInfo = dojo.map(results, function (layer, index) {
                        return { layer: layer.layer, title: layer.layer.name };
                    });

                    app.legend = new esri.dijit.Legend({
                        map: app.map,
                        layerInfos: layerInfo
                    }, "legendDiv");
                    app.legend.startup();
                }

            });
        }

        function buildList(lyr) {
            var lyrInfos, lyrs;

            // remove the existing layer list
            if (app.hasOwnProperty("dndSource")) {
                app.dndSource.destroy();
                dojo.empty(dojo.byId("layerList"));
            }

            app.layerLookup = {};
            // use dynamicLayerInfos if present
            // fallback to layerInfos to build the layer list
            lyrInfos = lyr.hasOwnProperty("dynamicLayerInfos") ?
          lyr.dynamicLayerInfos : lyr.layerInfos;

            lyrs = dojo.map(lyrInfos, function (li, idx) {
                var lyrName = li.name.split(".")[li.name.split(".").length - 1];
                app.layerLookup[lyrName] = idx;
                return lyrName;
            });
            app.dndSource = new dojo.dnd.Source("layerList");
            app.dndSource.insertNodes(false, lyrs);

            dojo.connect(app.dndSource, "onDndDrop", reorderLayers);
        }

        function reorderLayers(source, nodes, copy, target) {
            // show loading icon
            dojo.style(dojo.byId("loading"), "display", "inline-block");

            // get layer name nodes
            var lyrs = dojo.query("#layerList .dojoDndItem");
            var layerOrder = dojo.map(lyrs, function (l) {
                return app.layerLookup[l.innerHTML];
            });

            if (!app.hasOwnProperty("dynLyrInfos")) {
                app.dynLyrInfos = app.map.getLayer("usa").createDynamicLayerInfosFromLayerInfos();
            }
            var newOrder = dojo.map(layerOrder, function (idx) {
                return app.dynLyrInfos[idx];
            });
            app.dynLyrInfos = newOrder;
            app.map.getLayer("usa").setDynamicLayerInfos(app.dynLyrInfos);
            app.legend.refresh();
        }

        function addLakes() {
            var layerName, dataSource, layerSource, options, drawingOptions;

            // disable the "Add Lakes" button
            dijit.byId("lakes").set("disabled", true);

            // show a loading icon
            dojo.style(dojo.byId("loading"), "visibility", "visible");

            // layer name in the workspace
            layerName = "egdb.SDE.USLakes";
            // get existing layer info
            // lakes info will be appeneded to this object so it shows up in the map service image
            //
            // only use createDynamicLayerInfosFromLayerInfos
            // if layers haven't been re-ordered yet
            if (!app.hasOwnProperty("dynLyrInfos")) {
                app.dynLyrInfos = app.map.getLayer("usa").createDynamicLayerInfosFromLayerInfos();
            }

            // create a new dynamic layer info object for the lakes layer
            dynamicLayerInfo = new esri.layers.DynamicLayerInfo();
            dynamicLayerInfo.id = app.dynLyrInfos.length;
            dynamicLayerInfo.name = "George's Lakes";
            
            // create a table data source to access the lakes layer
            dataSource = new esri.layers.TableDataSource();
            dataSource.workspaceId = "MyDatabaseWorkspaceIDSSR2"; // not exposed via REST, sad face :(
            dataSource.dataSourceName = layerName;
            // and now a layer source
            layerSource = new esri.layers.LayerDataSource();
            layerSource.dataSource = dataSource;
            dynamicLayerInfo.source = layerSource;
            app.dynLyrInfos.push(dynamicLayerInfo);
            // set new infos, but don't refresh
            // map will be updated when the drawing options are set
            app.map.getLayer("usa").setDynamicLayerInfos(app.dynLyrInfos, true);

            options = [];
            drawingOptions = new esri.layers.LayerDrawingOptions();
            drawingOptions.renderer = new esri.renderer.SimpleRenderer(
          new esri.symbol.SimpleFillSymbol(
            "solid",
            null,
            new dojo.Color([255, 0, 255, 0.75]) // fuschia lakes!
          )
        );
            options[4] = drawingOptions;

            app.map.getLayer("usa").setLayerDrawingOptions(options);

            //refresh the legend
            app.legend.refresh();
        }

        function errorHandler(err) {
            console.log("Error: ", err);
        }        

        dojo.ready(init);
    </script>
  </head>

  <body class="tundra">
    <div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design:'headline',gutters:false" style="width: 100%; height: 100%; margin: 0;">
      <div id="map" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'center'">
        <div id="feedback" class="shadow">
          <h3>Add and Re-order Layers</h3>
          <div id="info">           
            <div id="hint">
              Click and drag a map layer name below to re-order layers.
            </div>
            <strong>Map Layers</strong>
            <img id="loading" src="http://dl.dropbox.com/u/2654618/loading_black.gif" />
            <br />
            <div id="layerList"></div>
            <button id="lakes"data-dojo-type="dijit.form.Button">Add Lakes</button>
            <div id="legendDiv"></div>
          </div>
        </div>        
      </div>
    </div>
  </body>
</html>
0 Kudos
1 Solution

Accepted Solutions
JianHuang
Occasional Contributor III
This is a bug. We will fix that in the release of 3.2.
Thanks for reporting this.

View solution in original post

0 Kudos
3 Replies
JianHuang
Occasional Contributor III
This is a bug. We will fix that in the release of 3.2.
Thanks for reporting this.
0 Kudos
deleted-user-ugCMpXci8bn5
New Contributor III
I am having a similar problem.  I removed a layer and restarted the map service, and while other edits I made in the mxd are reflected in my webapp, the legend still contains the removed layer.  Is this also related to this bug?  I am using v3.1.
0 Kudos
JörgPossin
New Contributor III
Same problem with Javascript API 3.2. If I add a Layer to the visibleLayers-Array of a DynamicMapServiceLayer the legend does not automatically refresh. I must call legend.refresh() to refresh it. In the legend only the Layers are displayed which are loaded at the start of the webmp 😞

But my main problem is that the legend does not refreshes at the print task. There is always shown the original legend with the maps from the webMap after loading 😞
0 Kudos