Issue with Popup and multiple graphics (features)

2550
6
05-22-2012 02:35 PM
AaronConnolly
Occasional Contributor
Hello,

I'm creating and adding a pop up to my map that displays a graphic's attributes or the individual attributes for a set of graphics using the left/right arrows. I'm basing my work off this sample:

http://help.arcgis.com/en/webapi/javascript/arcgis/demos/find/find_popup.html

I've got this *mostly* working. For a single symbol on the map, the pop up works well. But when I have multiple symbols at one location the initial click on the symbol brings up an empty pop up window, with one right-arrow. It looks like the pop up doesn't load the very first graphic's attributes, nor does it know how many graphics were loaded.

When I add the graphics to the map I store an array of attribute objects when I'm dealing with multiple points at one location and then add one graphic to the map. I know then to look for an attribute array when I listen for the layer's onClick event. Next, I create a new graphic for each attribute in the array and send the graphics array to the setFeatures method.

Why does the popup not load the first graphic's attributes? If I have 5 records at one location the pop up opens with no attribute data and provides me with a right-arrow. Clicking the right arrow will show me the second attribute object and the title then correctly reads (2 of 5) and also gives me a left-arrow. Clicking the left arrow will display the first attribute object that should have been displayed on the original click.

Here is my click event handler and yes I know I'm creating a graphics array and adding that to the popup rather than the results of a task. setFeatures takes a Graphic[] so it shouldn't matter how it gets those graphics, right?

Any thoughts?


    dojo.connect(crimeGraphicsLayer, "onClick", function(evt){
           
           // create lits of graphics from attribute array
           var graphics = [];

           if (evt.graphic.attributes.length != undefined && evt.graphic.attributes.length > 0)
           {
                for(var i=0;i < evt.graphic.attributes.length; i++)
                {   
                    graphics.push(new esri.Graphic(evt.graphic.geometry, evt.graphic.symbol, evt.graphic.attributes, popupTemplate));
                }
           }
           else
           {    
                graphics.push(evt.graphic);
           }
           
           map.infoWindow.show(graphics[0].geometry);
           map.infoWindow.setFeatures(graphics);
    });



Thanks,
- Aaron
0 Kudos
6 Replies
derekswingley1
Frequent Contributor
Is your map.infoWindow an instance of the popup? If so, use setFeatures instead of show.
0 Kudos
ChristopherPollard
Occasional Contributor
Aaron,
Any way that you could post more of your *almost* working sample?
I've been trying to re-work some of my projects/samples and have been running into some issue dealing with multiple graphic layers.
My sample has two query tasks retuning 2 different graphic layers with different attributes.
What I'd love to do is return ALL results of the graphics layers that are found at the 'clicked' location.
Same functionality as the Identify popup on a dynamic may service layer but on my diiferent graphics layers.

Here's my bare bones sample that I have so far. Any help/advice would be great.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=7,IE=9" />
    <!--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>QueryTask with geometry, results as an InfoWindow onClick</title>
    
    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.8/js/dojo/dijit/themes/claro/claro.css">
     <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.8/js/esri/dijit/css/Popup.css"/>
  
    <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.8"></script>
    
    <script type="text/javascript" language="Javascript">
      dojo.require("esri.map");
      dojo.require("esri.tasks.query");
   dojo.require("esri.dijit.Popup");
   
   var map;
   var cityLayer, portLayer;
   var infoTemplate;

      function init() {

        var startExtent = new esri.geometry.Extent({"xmin":-8513951.985121,"ymin":4786968.660565,"xmax":-8248256.864588,"ymax":4996406.126118,"spatialReference":{"wkid":102100}});
        
        //create a popup to replace the map's info window
        var popup = new esri.dijit.Popup(null, dojo.create("div"));
  
  //create map
         map = new esri.Map("mapDiv",{
  extent:startExtent,
  infoWindow: popup
  });
 
        //create and add new layer
        var layer = new esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer");
        map.addLayer(layer);
   
   //build query task
        var GCqueryTask = new esri.tasks.QueryTask("http://gis.dvrpc.org/ArcGIS/rest/services/DVRPC_Freight/MapServer/0");
        //build query filter
        var GCquery = new esri.tasks.Query();
        GCquery.returnGeometry = true;
        GCquery.outFields = ["NAME_GC","GC_Id","Name","Owner","Operators","Cargo","Report","StrView","Sview","LAT","LONG"];
        GCquery.where = "Name <>'*'";
        GCquery.outSpatialReference = {"wkid":102100};
        GCqueryTask.execute(GCquery,addGCFeatureSetToMap);
  
  var queryTask = new esri.tasks.QueryTask("http://gis.dvrpc.org/ArcGIS/rest/services/DVRPC_Freight/MapServer/1");
        //build query filter
        var query = new esri.tasks.Query();
        query.returnGeometry = true;
        query.outFields = ["NAME_GC","GC_Id","Name","Owner","Operators","Cargo","Report","StrView","Sview","LAT","LONG"];
        query.where = "Name <>'*'";
        query.outSpatialReference = {"wkid":102100};
  queryTask.execute(query,addPortFeatureSetToMap);
   
      }
   
    // Initialize function  
 function addGCFeatureSetToMap(featureSet) {
      var symbol = new esri.symbol.PictureMarkerSymbol({ "angle": 0,"xoffset": 0,"yoffset": 0,"type": "esriPMS","url": "http://www.dvrpc.org/webmaps/KML/images/RailCrossing.png","contentType": "image/png","width": 24,"height": 24 });    

        //Create graphics layer for cities
        cityLayer = new esri.layers.GraphicsLayer({id:'cityLayer'});
        map.addLayer(cityLayer); 
       var infoTemplate = new esri.InfoTemplate("${Name}","${*}");
        //Add cities to the graphics layer
        dojo.forEach(featureSet.features, function(feature) {
         cityLayer.add(feature.setSymbol(symbol).setInfoTemplate(infoTemplate));
        });
      } 
   
 // Initialize function  
 function addPortFeatureSetToMap(featureSet) {
      var symbol = new esri.symbol.PictureMarkerSymbol({ "angle": 0,"xoffset": 0,"yoffset": 0,"type": "esriPMS","url": "http://www.dvrpc.org/webmaps/KML/images/Ferry.png","contentType": "image/png","width": 24,"height": 24 });    

        //Create graphics layer for cities
        portLayer = new esri.layers.GraphicsLayer({id:'portLayer'});
        map.addLayer(portLayer); 
        var infoTemplate = new esri.InfoTemplate("${NAME}","${*}");
        //Add cities to the graphics layer
        dojo.forEach(featureSet.features, function(feature) {
         portLayer.add(feature.setSymbol(symbol).setInfoTemplate(infoTemplate));
        });
      } 
   

      dojo.addOnLoad(init);
    </script>
  </head>
  <body class="claro">
    Single click a county in South Carolina to get more information.
    <div id="mapDiv" style="width:900px; height:600px; border:1px solid #000;"></div>
  </body>
</html>


Thanks,
Chris
0 Kudos
KellyHutchins
Esri Frequent Contributor
Chris,

Take a look at this fiddle for an example that shows displaying the attributes for the selected features in a poupup window. This sample uses feature layers instead of graphics layers because it simplifies the code - no need to query and add the graphics to a graphics layer.

http://jsfiddle.net/xHRSE/
0 Kudos
AaronConnolly
Occasional Contributor
Is your map.infoWindow an instance of the popup? If so, use setFeatures instead of show.


Derek,

Thanks for the quick reply and being available on Twitter. Using only setFeatures and passing in the Graphic[] doesn't work. I am using a PopUp and not an InfoWindow. What else do you think I should look at?

I'm using a GraphicsLayer and whenever I determine that there are multiple points at one location I add only one graphic, but add an array of attributes to the attributes property of the esri.Graphic constructor like this. Could this be causing my problem?

         attributes = [];

                        for (var j = 0; j < dataPoints[key].length; j++) {

                            attributes.push({
                                "Address": dataPoints[key].Address,
                                "Date": dataPoints[key].Date,
                                "ID": dataPoints[key].ID,
                                "Legend": dataPoints[key].Legend,
                                "X": dataPoints[key].X,
                                "Y": dataPoints[key].Y
                            });
                        }
                    
                        //- Add symbol graphic
                        graphic = new esri.Graphic(geometry, symbol, attributes);
                        graphicsLayer.add(graphic);


Then my click looks for that attribute array and parses it into seperate graphics then adds those graphics to the Popup's setFeatures method. According to the API Reference setFeatures takes Deferred[] or Feature[]. It doesn't explicitly say that it takes Graphic[] but if you look at the API Reference for FeatureSet you'll notice that it's property 'features' is of type Graphic[], this means that there shouldn't be a problem passing in an Graphic[] to setFeatures.

Thoughts?
0 Kudos
AaronConnolly
Occasional Contributor
Aaron,
Any way that you could post more of your *almost* working sample?
I've been trying to re-work some of my projects/samples and have been running into some issue dealing with multiple graphic layers.
My sample has two query tasks retuning 2 different graphic layers with different attributes.
What I'd love to do is return ALL results of the graphics layers that are found at the 'clicked' location.
Same functionality as the Identify popup on a dynamic may service layer but on my diiferent graphics layers.

Here's my bare bones sample that I have so far. Any help/advice would be great.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=7,IE=9" />
    <!--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>QueryTask with geometry, results as an InfoWindow onClick</title>
    
    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.8/js/dojo/dijit/themes/claro/claro.css">
     <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.8/js/esri/dijit/css/Popup.css"/>
  
    <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.8"></script>
    
    <script type="text/javascript" language="Javascript">
      dojo.require("esri.map");
      dojo.require("esri.tasks.query");
   dojo.require("esri.dijit.Popup");
   
   var map;
   var cityLayer, portLayer;
   var infoTemplate;

      function init() {

        var startExtent = new esri.geometry.Extent({"xmin":-8513951.985121,"ymin":4786968.660565,"xmax":-8248256.864588,"ymax":4996406.126118,"spatialReference":{"wkid":102100}});
        
        //create a popup to replace the map's info window
        var popup = new esri.dijit.Popup(null, dojo.create("div"));
  
  //create map
         map = new esri.Map("mapDiv",{
  extent:startExtent,
  infoWindow: popup
  });
 
        //create and add new layer
        var layer = new esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer");
        map.addLayer(layer);
   
   //build query task
        var GCqueryTask = new esri.tasks.QueryTask("http://gis.dvrpc.org/ArcGIS/rest/services/DVRPC_Freight/MapServer/0");
        //build query filter
        var GCquery = new esri.tasks.Query();
        GCquery.returnGeometry = true;
        GCquery.outFields = ["NAME_GC","GC_Id","Name","Owner","Operators","Cargo","Report","StrView","Sview","LAT","LONG"];
        GCquery.where = "Name <>'*'";
        GCquery.outSpatialReference = {"wkid":102100};
        GCqueryTask.execute(GCquery,addGCFeatureSetToMap);
  
  var queryTask = new esri.tasks.QueryTask("http://gis.dvrpc.org/ArcGIS/rest/services/DVRPC_Freight/MapServer/1");
        //build query filter
        var query = new esri.tasks.Query();
        query.returnGeometry = true;
        query.outFields = ["NAME_GC","GC_Id","Name","Owner","Operators","Cargo","Report","StrView","Sview","LAT","LONG"];
        query.where = "Name <>'*'";
        query.outSpatialReference = {"wkid":102100};
  queryTask.execute(query,addPortFeatureSetToMap);
   
      }
   
    // Initialize function  
 function addGCFeatureSetToMap(featureSet) {
      var symbol = new esri.symbol.PictureMarkerSymbol({ "angle": 0,"xoffset": 0,"yoffset": 0,"type": "esriPMS","url": "http://www.dvrpc.org/webmaps/KML/images/RailCrossing.png","contentType": "image/png","width": 24,"height": 24 });    

        //Create graphics layer for cities
        cityLayer = new esri.layers.GraphicsLayer({id:'cityLayer'});
        map.addLayer(cityLayer); 
       var infoTemplate = new esri.InfoTemplate("${Name}","${*}");
        //Add cities to the graphics layer
        dojo.forEach(featureSet.features, function(feature) {
         cityLayer.add(feature.setSymbol(symbol).setInfoTemplate(infoTemplate));
        });
      } 
   
 // Initialize function  
 function addPortFeatureSetToMap(featureSet) {
      var symbol = new esri.symbol.PictureMarkerSymbol({ "angle": 0,"xoffset": 0,"yoffset": 0,"type": "esriPMS","url": "http://www.dvrpc.org/webmaps/KML/images/Ferry.png","contentType": "image/png","width": 24,"height": 24 });    

        //Create graphics layer for cities
        portLayer = new esri.layers.GraphicsLayer({id:'portLayer'});
        map.addLayer(portLayer); 
        var infoTemplate = new esri.InfoTemplate("${NAME}","${*}");
        //Add cities to the graphics layer
        dojo.forEach(featureSet.features, function(feature) {
         portLayer.add(feature.setSymbol(symbol).setInfoTemplate(infoTemplate));
        });
      } 
   

      dojo.addOnLoad(init);
    </script>
  </head>
  <body class="claro">
    Single click a county in South Carolina to get more information.
    <div id="mapDiv" style="width:900px; height:600px; border:1px solid #000;"></div>
  </body>
</html>


Thanks,
Chris


Chris, I can't post all the working code I have. Do you have a specific question about what I might be doing? Did you take a look at the Feature Layer example that Kelly recommended?

Thanks,
- Aaron
0 Kudos
ChristopherPollard
Occasional Contributor
Aaron,
Thanks for replying and yes Kelly's example answered exactly what I was looking to do. I have not had to use feature layers before and had those confused with feature services (I'm still on 9.3.1 and never thought to look into using a feature layer before).

As far as your sample, I don't have any specific questions but i have been using popups in most of my recent applications and any user samples that I can view and use for reference I find to be really helpful.

good luck with your issue and if you need anyone to review or test any functionality feel free to send me a link/email.
thanks,
chris
0 Kudos