InfoTemplate

3637
4
Jump to solution
10-23-2013 10:31 AM
RobertHupp
New Contributor III
I am new to the Javascript API and have already got some help from tutorials and this forum for my map, but I desperately need help figuring out one last problem. I need info windows to pop up for my icons for my mainMapLayer. I added graphic.setInfoTemplate(new esri.InfoTemplate()) to my var graphic of my showResults function which shows pop-ups for my queried data but it doesn't show for the inactive points. Also, the pop-ups that do come up have a zoom to link which crashes the application when clicked on. This may be cleared up if I can figure out how to have info windows from the entire layer instead of the returned results. If not i need to diasble the zoom to action. Any help would be greatly appreciated!

Here is my code:
 <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");    dojo.require("esri.InfoTemplate");                  var findTask, findParams;       var map, center, minScale, zoom;       var grid, store;        function init() {         dojo.connect(grid, "onRowClick", onRowClickHandler);          center = [-98.495, 29.42];          zoom = 13;         map = new esri.Map("map", {            basemap: "streets",           center: center,           zoom: zoom         });   var transMapLayer = new esri.layers.ArcGISDynamicMapServiceLayer("http://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer", {           id: "trans",     minScale: "4500",     opacity: "0.5"              });             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", "Type1", "Type2", "Type3"];           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:"Points of Interest"}],    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.setInfoTemplate(new esri.InfoTemplate(     "Points of Interest", "<tr>Name:<td>${Name}</tr></td><br><tr>Category:<td>${Category}</tr></td><br><tr>Type 1:<td>${Type1}</tr></td><br><tr>Type 2:<td>${Type2}</tr></td><br><tr>Type 3:<td>${Type3}</tr></td><br><tr>Owner:<td>${Owner}</tr></td>"));           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 id="header" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'top'" style="border:1px solid #000;">      Bexar County Points of Interest 1896 (Beta) <div id="subheader"><a href="http://www.bexar.org/it/gis.html" target="_new">by Bexar County eServices GIS Group</a></div>     </div>       <div data-dojo-props="region:'left'" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title:'Legend'" style="width:19%; 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 id="search"><b>Point of Interest:</b> <input type="text" id="ownerName" size="20" value="The Alamo" />       <button data-dojo-type="dijit.form.Button"  data-dojo-props='onClick:function(){ doFind();}, value:"Search"'>         Search       </button> <i>Any name, place, category, keyword, etc. Results will be highlighted on map and in table below map. Clicking on table row in table results will zoom to point of interest </i></div></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="16%">Point of Interest</th>           <th field="Category">Category</th>     <th field="Owner">Owner</th>     <th field="Type1">Type 1</th>     <th field="Type2">Type 2</th>     <th field="Type2">Type 3</th>         </tr>       </thead>     </table>     </div>   </div>   </body> </html>
0 Kudos
1 Solution

Accepted Solutions
JanelYang
New Contributor III
I took your code and combined it with the code snippet I provided earlier. Also did some clean-up to make it more logical. Attached please find the complete code. Here is how I organized the the workflow in code:
var map, center, zoom, grid;  function init() {   center = [-98.495, 29.42];   zoom = 13;   map = new esri.Map("map", {     basemap: "streets",     center: center,     zoom: zoom   });      var mainMapLayer = new esri.layers.ArcGISDynamicMapServiceLayer("http://mapservices2.bexar.org/arcgis/rest/services/Historic/Historic_POI/MapServer");   map.addLayers([mainMapLayer]);      var legend = new esri.dijit.Legend({     map: map,     layerInfos: [{layer:mainMapLayer,title:"Points of Interest"}],     arrangement: esri.dijit.Legend.ALIGN_RIGHT   },"legendDiv");   legend.startup();      map.on("click", identifyPOI);   dojo.connect(grid, "onRowClick", onRowClickHandler); };



  1. Alway get static resources ready first: map, layer and then legend widget. All these are executed when your app is opened.


  2. After the initial view is loaded, a user can do two things with the app: #1 click a point to see the popup, or #2 search point by name. For #1, I created a function called identifyPOI and wrapped the code snippet I provided earlier in it. For #2, the existing doFind function can handle it very well. Only made some minor changes. Note that you won't need to set infoTemplate in showResults, as the popup has already been handled in #1.


  3. A minor tweak in HTML and CSS: moved map into a new div inside the central cententpane, next to the search div. Set the height to 100% in CSS.

  4. <div data-dojo-props="region:'center'" data-dojo-type="dijit.layout.ContentPane" style="border:1px solid #000;">   <div id="search"><b>Point of Interest:</b> <input type="text" id="ownerName" size="20" value="The Alamo" />     <button data-dojo-type="dijit.form.Button"  data-dojo-props='onClick:function(){ doFind();}, value:"Search"'>Search</button>       <i>Any name, place, category, keyword, etc. Results will be highlighted on map and in table below map. Clicking on table row in table results will zoom to point of interest </i>     </div>   <div id="map"></div> </div>

I hope this helps. Let us know if it works for you 🙂

View solution in original post

0 Kudos
4 Replies
JanelYang
New Contributor III
There are several ways to get popup for your layer, depending on the type of your layer and how you want to handle it. Given the code you already have, you need to use IdentifyTask to get features with the point you click on the map:
(I clear the search part to make it cleaner, but you can integrate the code below with the search part you already have. Please also consider coding in the AMD style.)
require([
  "esri/map", "esri/layers/ArcGISDynamicMapServiceLayer", "esri/tasks/IdentifyTask", "esri/tasks/IdentifyParameters", "dojo/_base/array", "esri/InfoTemplate", "dojo/domReady!"
], function(Map, ArcGISDynamicMapServiceLayer, IdentifyTask, IdentifyParameters, array, InfoTemplate) {
  var map = new Map("map", {
    basemap: "gray",
    center: [-98.544, 29.47],
    zoom: 12
  });

  var layer = new ArcGISDynamicMapServiceLayer("http://mapservices2.bexar.org/arcgis/rest/services/Historic/Historic_POI/MapServer");
  map.addLayer(layer);
  
  map.on("click", function(evt){
    var identify = new IdentifyTask("http://maps1.arcgisonline.com/ArcGIS/rest/services/USA_Federal_Lands/MapServer");
    var identifyParams = new IdentifyParameters();
    identifyParams.geometry = evt.mapPoint;
    identifyParams.mapExtent = map.extent;
    identifyParams.returnGeometry = true;
    identifyParams.tolerance = 3;
    
    map.infoWindow.clearFeatures();
    
    identify.execute(identifyParams, function(results){
      map.infoWindow.setFeatures(array.map(results, function(result){
        var feature = result.feature;
        feature.setInfoTemplate(new InfoTemplate());
        return feature;
      }));
      map.infoWindow.show(evt.mapPoint);
    });
  });
});


A more elegant way we strongly recommend is to use FeatureLayer, which allows you to identify features without sending extra requests to the server:
require(["esri/map", "esri/layers/FeatureLayer", "esri/InfoTemplate", "dojo/domReady!"], function(Map, FeatureLayer, InfoTemplate) {
  var map = new Map("map", {
    basemap: "gray",
    center: [-87.5, 42],
    zoom: 11,
  });
  
  var layer = new FeatureLayer("http://services.arcgis.com/V6ZHFr6zdgNZuVG0/ArcGIS/rest/services/CTAStation/FeatureServer/0", {
    outFields: ["*"],
    infoTemplate: new InfoTemplate()
  });
  map.addLayer(layer);
});
0 Kudos
RobertHupp
New Contributor III
There are several ways to get popup for your layer, depending on the type of your layer and how you want to handle it. Given the code you already have, you need to use IdentifyTask to get features with the point you click on the map:
(I clear the search part to make it cleaner, but you can integrate the code below with the search part you already have. Please also consider coding in the AMD style.)
require([
  "esri/map", "esri/layers/ArcGISDynamicMapServiceLayer", "esri/tasks/IdentifyTask", "esri/tasks/IdentifyParameters", "dojo/_base/array", "esri/InfoTemplate", "dojo/domReady!"
], function(Map, ArcGISDynamicMapServiceLayer, IdentifyTask, IdentifyParameters, array, InfoTemplate) {
  var map = new Map("map", {
    basemap: "gray",
    center: [-98.544, 29.47],
    zoom: 12
  });

  var layer = new ArcGISDynamicMapServiceLayer("http://mapservices2.bexar.org/arcgis/rest/services/Historic/Historic_POI/MapServer");
  map.addLayer(layer);
  
  map.on("click", function(evt){
    var identify = new IdentifyTask("http://maps1.arcgisonline.com/ArcGIS/rest/services/USA_Federal_Lands/MapServer");
    var identifyParams = new IdentifyParameters();
    identifyParams.geometry = evt.mapPoint;
    identifyParams.mapExtent = map.extent;
    identifyParams.returnGeometry = true;
    identifyParams.tolerance = 3;
    
    map.infoWindow.clearFeatures();
    
    identify.execute(identifyParams, function(results){
      map.infoWindow.setFeatures(array.map(results, function(result){
        var feature = result.feature;
        feature.setInfoTemplate(new InfoTemplate());
        return feature;
      }));
      map.infoWindow.show(evt.mapPoint);
    });
  });
});


A more elegant way we strongly recommend is to use FeatureLayer, which allows you to identify features without sending extra requests to the server:
require(["esri/map", "esri/layers/FeatureLayer", "esri/InfoTemplate", "dojo/domReady!"], function(Map, FeatureLayer, InfoTemplate) {
  var map = new Map("map", {
    basemap: "gray",
    center: [-87.5, 42],
    zoom: 11,
  });
  
  var layer = new FeatureLayer("http://services.arcgis.com/V6ZHFr6zdgNZuVG0/ArcGIS/rest/services/CTAStation/FeatureServer/0", {
    outFields: ["*"],
    infoTemplate: new InfoTemplate()
  });
  map.addLayer(layer);
});


I'm so close but yet so far! I am still learning and stuck in legacy for this project. I can get your code to work in sandbox but not in my app. All I need is to get pop ups for this layer var mainMapLayer = new esri.layers.ArcGISDynamicMapServiceLayer("http://mapservices2.bexar.org/arcgis/rest/services/Historic/Historic_POI/MapServer"
I apologize for my ignorance but you have been a big help so far, can you be a little bit more specific on the code and reference legacy? My next project will be in AMD.
0 Kudos
JanelYang
New Contributor III
I took your code and combined it with the code snippet I provided earlier. Also did some clean-up to make it more logical. Attached please find the complete code. Here is how I organized the the workflow in code:
var map, center, zoom, grid;  function init() {   center = [-98.495, 29.42];   zoom = 13;   map = new esri.Map("map", {     basemap: "streets",     center: center,     zoom: zoom   });      var mainMapLayer = new esri.layers.ArcGISDynamicMapServiceLayer("http://mapservices2.bexar.org/arcgis/rest/services/Historic/Historic_POI/MapServer");   map.addLayers([mainMapLayer]);      var legend = new esri.dijit.Legend({     map: map,     layerInfos: [{layer:mainMapLayer,title:"Points of Interest"}],     arrangement: esri.dijit.Legend.ALIGN_RIGHT   },"legendDiv");   legend.startup();      map.on("click", identifyPOI);   dojo.connect(grid, "onRowClick", onRowClickHandler); };



  1. Alway get static resources ready first: map, layer and then legend widget. All these are executed when your app is opened.


  2. After the initial view is loaded, a user can do two things with the app: #1 click a point to see the popup, or #2 search point by name. For #1, I created a function called identifyPOI and wrapped the code snippet I provided earlier in it. For #2, the existing doFind function can handle it very well. Only made some minor changes. Note that you won't need to set infoTemplate in showResults, as the popup has already been handled in #1.


  3. A minor tweak in HTML and CSS: moved map into a new div inside the central cententpane, next to the search div. Set the height to 100% in CSS.

  4. <div data-dojo-props="region:'center'" data-dojo-type="dijit.layout.ContentPane" style="border:1px solid #000;">   <div id="search"><b>Point of Interest:</b> <input type="text" id="ownerName" size="20" value="The Alamo" />     <button data-dojo-type="dijit.form.Button"  data-dojo-props='onClick:function(){ doFind();}, value:"Search"'>Search</button>       <i>Any name, place, category, keyword, etc. Results will be highlighted on map and in table below map. Clicking on table row in table results will zoom to point of interest </i>     </div>   <div id="map"></div> </div>

I hope this helps. Let us know if it works for you 🙂
0 Kudos
RobertHupp
New Contributor III
Helped out tremendously! I will study this code and learn from it. Thanks for cleaning it up and the lesson on logical structure, it's exactly what I needed. Next app I will definately code in AMD as well. Thanks so much!:D
0 Kudos