Select to view content in your preferred language

Help with Legend Widget

1229
6
Jump to solution
10-21-2013 10:20 AM
RobertHupp
Deactivated User
I am new to the Javascript API, but have been able to put together this map from examples and forums and it all works fine except for when I try to add a Legend. Can someone please help get the legend to display?

Here is my code:

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=7, IE=9, IE=10">
    <!--The viewport meta tag is used to improve the presentation and behavior of the samples
      on iOS devices-->
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
    <title>San Antonio 1896 Points of  Interest</title>

    <link rel="stylesheet" href="http://js.arcgis.com/3.7/js/dojo/dijit/themes/claro/claro.css">
    <link rel="stylesheet" href="http://js.arcgis.com/3.7/js/dojo/dojox/grid/resources/Grid.css">
    <link rel="stylesheet" href="http://js.arcgis.com/3.7/js/dojo/dojox/grid/resources/claroGrid.css">
    <link rel="stylesheet" href="http://js.arcgis.com/3.7/js/esri/css/esri.css">
    <style>
      html, body { height: 100%; width: 100%; margin: 0; padding: 0; }
    </style>

    <script>var dojoConfig = { parseOnLoad:true }</script>
    <script src="http://js.arcgis.com/3.7/"></script>
    <script>
      dojo.require("esri.map");
      dojo.require("dojox.grid.DataGrid");
      dojo.require("dojo.data.ItemFileReadStore");
      dojo.require("esri.tasks.find");
      dojo.require("dijit.layout.BorderContainer");
      dojo.require("dijit.layout.ContentPane");
      dojo.require("dijit.form.Button");
   dojo.require("esri.dijit.Legend");
     
      var findTask, findParams;
      var map, center, zoom;
      var grid, store;

      function init() {
        dojo.connect(grid, "onRowClick", onRowClickHandler);

        center = [-98.544, 29.47];
        zoom = 11;
        map = new esri.Map("map", {
          basemap: "hybrid",
          center: center,
          zoom: zoom
        });
  var transMapLayer = new esri.layers.ArcGISDynamicMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer", {
          id: "trans"
        });
        map.addLayer(transMapLayer);
 
  var mainMapLayer = new esri.layers.ArcGISDynamicMapServiceLayer("http://mapservices2.bexar.org/arcgis/rest/services/Historic/Historic_POI/MapServer", {
          id: "1896"
        });
        map.addLayer(mainMapLayer);
 
        //Create Find Task using the URL of the map service to search
        findTask = new esri.tasks.FindTask("http://mapservices2.bexar.org/arcgis/rest/services/Historic/Historic_POI/MapServer");

        dojo.connect(map, "onLoad", function() {
          //Create the find parameters
          findParams = new esri.tasks.FindParameters();
          findParams.returnGeometry = true;
          findParams.layerIds = [0];
          findParams.searchFields = [ "Name", "Owner", "Category"];
          findParams.outSpatialReference = map.spatialReference;
          console.log("find sr: ", findParams.outSpatialReference);
        });
 
   dojo.connect(map, "onLayersAddResult", function(results) {
  var legend = new esri.dijit.Legend({
   map:map,
   layerInfos:[{layer:mainMapLayer,title:"1896"}],
   arrangement:esri.dijit.Legend.ALIGN_RIGHT
   },"legendDiv");
   legend.startup();
  });
      }

      function doFind() {
        //Set the search text to the value in the box
        findParams.searchText = dojo.byId("ownerName").value;
        findTask.execute(findParams,showResults);
      }

      function showResults(results) {
        //This function works with an array of FindResult that the task returns
        map.graphics.clear();
        var symbol =  new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_SQUARE, 25, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255, 0, 0]), 1), new dojo.Color([0, 255, 0, 0.25]));

        //create array of attributes
        var items = dojo.map(results,function(result){
          var graphic = result.feature;
          graphic.setSymbol(symbol);
          map.graphics.add(graphic);
          return result.feature.attributes;
        });
       
        //Create data object to be used in store
        var data = {
          identifier: "OBJECTID",  //This field needs to have unique values
          label: "OBJECTID", //Name field for display. Not pertinent to a grid but may be used elsewhere.
          items: items
        };

         //Create data store and bind to grid.
        store = new dojo.data.ItemFileReadStore({ data:data });
        var grid = dijit.byId('grid');
        grid.setStore(store);

        //Zoom back to the initial map extent
        map.centerAndZoom(center, zoom);
      }

      //Zoom to the parcel when the user clicks a row
      function onRowClickHandler(evt){
        var clickedTaxLotId = grid.getItem(evt.rowIndex).OBJECTID;
        var selectedTaxLot;
  var distance = 100;

        dojo.forEach(map.graphics.graphics,function(graphic){
          if((graphic.attributes) && graphic.attributes.OBJECTID === clickedTaxLotId){
            selectedTaxLot = graphic.geometry;
            return;
          }
        });
  var newExtent = new esri.geometry.Extent({
        "xmin": selectedTaxLot.x - distance,
        "ymin": selectedTaxLot.y - distance,
        "xmax": selectedTaxLot.x + distance,
        "ymax": selectedTaxLot.y + distance,
        "spatialReference": {
            "wkid": 102100
        }
    });

        map.setExtent(newExtent);
  console.log(map.graphics.graphics);
      }

      dojo.ready(init);
    </script>
  </head>
  <body class="claro">
  <div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design:'headline'"  style="width:100%;height:100%;margin:0;">
    <div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'top'" style="height:40px;">
      Point of Interest: <input type="text" id="ownerName" size="20" value="Koehler" />
      <button data-dojo-type="dijit.form.Button"  data-dojo-props='onClick:function(){ doFind();}, value:"Search"'>
        Search
      </button>
    </div>
<div data-dojo-props="region:'left'" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title:'Legend'" style="border:1px solid #000;">
<div id="legendDiv"></div>
</div>
    <div id="map" data-dojo-props="region:'center'" data-dojo-type="dijit.layout.ContentPane" style="border:1px solid #000;"></div>
    <div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'bottom'" style="height:150px;">
     <table data-dojo-type="dojox.grid.DataGrid" data-dojo-id="grid"  id="grid" data-dojo-props="rowsPerPage:'5', rowSelector:'20px'">
      <thead>
        <tr>
         
          <th field="Name" width="50%">Point of Interest</th>
          <th field="Category">Category</th>
    <th field="Owner">Owner</th>
        </tr>
      </thead>
    </table>
    </div>
  </div>
  </body>
</html>
0 Kudos
1 Solution

Accepted Solutions
RobertHupp
Deactivated User
Hi,

The problem in your code is with the map.onLayersAddResult event, since your legend is created inside the callback of this event. This event is fired when map.addLayers(<an array of layers>) is executed. map.addLayer() will NOT fire this event.

The only thing you need to do is to change:
map.addLayer(transMapLayer);  ... map.addLayer(mainMapLayer);

to:
map.addLayers([transMapLayer, mainMapLayer]);


You may need to tweak your CSS styles a bit to adjust the layout afterward.


Makes perfect sense, but when I add that code it still doesn't fire. ???

View solution in original post

0 Kudos
6 Replies
JanelYang
Deactivated User
Hi,

The problem in your code is with the map.onLayersAddResult event, since your legend is created inside the callback of this event. This event is fired when map.addLayers(<an array of layers>) is executed. map.addLayer() will NOT fire this event.

The only thing you need to do is to change:
map.addLayer(transMapLayer);
 ...
map.addLayer(mainMapLayer);

to:
map.addLayers([transMapLayer, mainMapLayer]);


You may need to tweak your CSS styles a bit to adjust the layout afterward.
0 Kudos
RobertHupp
Deactivated User
Hi,

The problem in your code is with the map.onLayersAddResult event, since your legend is created inside the callback of this event. This event is fired when map.addLayers(<an array of layers>) is executed. map.addLayer() will NOT fire this event.

The only thing you need to do is to change:
map.addLayer(transMapLayer);  ... map.addLayer(mainMapLayer);

to:
map.addLayers([transMapLayer, mainMapLayer]);


You may need to tweak your CSS styles a bit to adjust the layout afterward.


Makes perfect sense, but when I add that code it still doesn't fire. ???
0 Kudos
JanelYang
Deactivated User
Here is a couple of things to can check:

1. Make sure map.onLayersAddResult is fired.
2. Adjust your layout. You can set a width for the legend div to make sure there is space for legend when it is started.
<div data-dojo-props="region:'left'" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title:'Legend'" style="border:1px solid #000; width: 200px">
0 Kudos
RobertHupp
Deactivated User
Perfect, works like a charm, Thanks so much Jerome. Now only if I knew a quick way to have the pop-ups for my POI layer show on the map, any ideas would be greatly appreciated.

 <script>var dojoConfig = { parseOnLoad:true }</script>
    <script src="http://js.arcgis.com/3.7/"></script>
    <script>
      dojo.require("esri.map");
      dojo.require("dojox.grid.DataGrid");
      dojo.require("dojo.data.ItemFileReadStore");
      dojo.require("esri.tasks.find");
      dojo.require("dijit.layout.BorderContainer");
      dojo.require("dijit.layout.ContentPane");
      dojo.require("dijit.form.Button");
   dojo.require("esri.dijit.Legend");
      
      var findTask, findParams;
      var map, center, zoom;
      var grid, store;

      function init() {
        dojo.connect(grid, "onRowClick", onRowClickHandler);

        center = [-98.544, 29.47]; 
        zoom = 11;
        map = new esri.Map("map", { 
          basemap: "hybrid",
          center: center,
          zoom: zoom
        });
  var transMapLayer = new esri.layers.ArcGISDynamicMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer", {
          id: "trans"
        });
      
  
  var mainMapLayer = new esri.layers.ArcGISDynamicMapServiceLayer("http://mapservices2.bexar.org/arcgis/rest/services/Historic/Historic_POI/MapServer", {
          id: "1896"
        });
       

  map.addLayers([transMapLayer, mainMapLayer]);
  
        //Create Find Task using the URL of the map service to search
        findTask = new esri.tasks.FindTask("http://mapservices2.bexar.org/arcgis/rest/services/Historic/Historic_POI/MapServer");

        dojo.connect(map, "onLoad", function() {
          //Create the find parameters
          findParams = new esri.tasks.FindParameters();
          findParams.returnGeometry = true;
          findParams.layerIds = [0];
          findParams.searchFields = [ "Name", "Owner", "Category"];
          findParams.outSpatialReference = map.spatialReference;
          console.log("find sr: ", findParams.outSpatialReference);
        });
  
   dojo.connect(map, "onLayersAddResult", function(result) {
  var legend = new esri.dijit.Legend({
   map:map,
   layerInfos:[{layer:mainMapLayer,title:"San Antonio Points of Interest 1896"}],
   arrangement:esri.dijit.Legend.ALIGN_RIGHT
   },"legendDiv");
   legend.startup();
  });
      }

      function doFind() {
        //Set the search text to the value in the box
        findParams.searchText = dojo.byId("ownerName").value;
        findTask.execute(findParams,showResults);
      }

      function showResults(results) {
        //This function works with an array of FindResult that the task returns
        map.graphics.clear();
        var symbol =  new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_SQUARE, 25, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255, 0, 0]), 1), new dojo.Color([0, 255, 0, 0.25]));

        //create array of attributes
        var items = dojo.map(results,function(result){
          var graphic = result.feature;
          graphic.setSymbol(symbol);
          map.graphics.add(graphic);
          return result.feature.attributes;
        });
        
        //Create data object to be used in store
        var data = {
          identifier: "OBJECTID",  //This field needs to have unique values
          label: "OBJECTID", //Name field for display. Not pertinent to a grid but may be used elsewhere.
          items: items
        };

         //Create data store and bind to grid.
        store = new dojo.data.ItemFileReadStore({ data:data });
        var grid = dijit.byId('grid');
        grid.setStore(store);

        //Zoom back to the initial map extent
        map.centerAndZoom(center, zoom);
      }

      //Zoom to the parcel when the user clicks a row
      function onRowClickHandler(evt){
        var clickedTaxLotId = grid.getItem(evt.rowIndex).OBJECTID;
        var selectedTaxLot;
  var distance = 100;

        dojo.forEach(map.graphics.graphics,function(graphic){
          if((graphic.attributes) && graphic.attributes.OBJECTID === clickedTaxLotId){
            selectedTaxLot = graphic.geometry;
            return;
          }
        });
  var newExtent = new esri.geometry.Extent({
        "xmin": selectedTaxLot.x - distance,
        "ymin": selectedTaxLot.y - distance,
        "xmax": selectedTaxLot.x + distance,
        "ymax": selectedTaxLot.y + distance,
        "spatialReference": {
            "wkid": 102100
        }
    });

        map.setExtent(newExtent);
  console.log(map.graphics.graphics);
      }

      dojo.ready(init);
    </script>
  </head>
  <body class="claro">
  <div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design:'headline'"  style="width:100%;height:100%;margin:0;">
    <div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'top'" style="height:40px;">
      Point of Interest: <input type="text" id="ownerName" size="20" value="Koehler" />
      <button data-dojo-type="dijit.form.Button"  data-dojo-props='onClick:function(){ doFind();}, value:"Search"'>
        Search
      </button>
    </div>
 <div data-dojo-props="region:'left'" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title:'Legend'" style="width:18%; border:1px solid #000;">
 <div id="legendDiv"></div>
 </div>
    <div id="map" data-dojo-props="region:'center'" data-dojo-type="dijit.layout.ContentPane" style="border:1px solid #000;"></div>
    <div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'bottom'" style="height:150px;">
     <table data-dojo-type="dojox.grid.DataGrid" data-dojo-id="grid"  id="grid" data-dojo-props="rowsPerPage:'5', rowSelector:'20px'">
      <thead>
        <tr>
          
          <th field="Name" width="50%">Point of Interest</th>
          <th field="Category">Category</th>
    <th field="Owner">Owner</th>
        </tr>
      </thead>
    </table>
    </div>
  </div>
  </body>
</html>
0 Kudos
JanelYang
Deactivated User
Now only if I knew a quick way to have the pop-ups for my POI layer show on the map, any ideas would be greatly appreciated.


A simple way to do this with your existing code is to set InfoTemplate for the graphic in your showResults(results) function:
graphic.setInfoTemplate(new esri.InfoTemplate());

You can further customized the text in your pop-ups. Refer to Graphic.setInfoTemplate(infoTemplate) for more information.
0 Kudos
RobertHupp
Deactivated User
A simple way to do this with your existing code is to set InfoTemplate for the graphic in your showResults(results) function:
graphic.setInfoTemplate(new esri.InfoTemplate());

You can further customized the text in your pop-ups. Refer to Graphic.setInfoTemplate(infoTemplate) for more information.


It shows the info window for the search results of the layer but not the non returned results. How can I get a pop up for all the items in the mainMapLayer when clicked on?
0 Kudos