CSVLayer event onclick

2793
9
Jump to solution
02-19-2016 11:32 AM
EricHolweg
New Contributor

I have a CSVLayer that I loaded into a web application.

The data that I want to display within the infowindow of that CSVLayer is too large to display nicely in the existing map window.

Therefore when I click on a point within that CSVLayer, I need to execute some code that re-centers the map such that the entire infowindow is displayed within the map.

The problem that I have is that I cannot figure out how to create a click event on just the CSVlayer.

Currently I have a click event triggered on the map as a whole.. which does the recentering for me, but this proved problematic if I end up clicking on any other part of the map. In those cases, there is no infowindow to open and the map will still be forced to re-center.

Below is my code for this application.

<script src="http://js.arcgis.com/3.15/"></script>
   <script>
   var map, kml, csv;
  require(["esri/map", "esri/layers/KMLLayer", "esri/layers/CSVLayer", "esri/renderers/SimpleRenderer", "esri/InfoTemplate", "esri/urlUtils", "esri/symbols/PictureMarkerSymbol", "esri/geometry/Point", "esri/SpatialReference", "esri/geometry/webMercatorUtils", "esri/geometry/screenUtils", "esri/geometry/ScreenPoint", "dojo/dom", "dojo/_base/array", "dojo/domReady!"], function(Map, KMLLayer, CSVLayer, SimpleRenderer, InfoTemplate, urlUtils, PictureMarkerSymbol, Point, SpatialReference, webMercatorUtils, screenUtils, ScreenPoint, dom, array) {
  map = new Map("map", {
  basemap : "hybrid",
  center : [-83.71, 36.05],
  zoom : 8
   });

  map.on("load", function() {
  map.infoWindow.set('anchor', 'bottom-right');
  map.infoWindow.resize(625, 425);
  map.on("mouse-move", showCoordinates);
  map.on("mouse-drag", showCoordinates);
   });

   var kmlUrl = "http://www.srh.noaa.gov/images/rtimages/mrx/kml/RiversLakes.kml";
  kml = new KMLLayer(kmlUrl);
  map.addLayer(kml);

  dojo.connect(kml, 'onLoad', function(lyr) {
   var layers = lyr.getLayers();
  dojo.forEach(layers, function(lyr) {
  lyr.setInfoTemplate(null);
   });
   });


  urlUtils.addProxyRule({
  proxyUrl : "/proxy/proxy.php",
  urlPrefix : "www.srh.noaa.gov"
   });

   var template = new InfoTemplate("${name}", "<iframe src=${fcstlink} class="fcst"></iframe>");

   var csvUrl = "http://www.srh.noaa.gov/images/rtimages/mrx/js_local/riverpoints.csv";
  csv = new CSVLayer(csvUrl, {
  copyright : "weather.gov",
  infoTemplate : template
   });
   var logo = new PictureMarkerSymbol("http://www.srh.noaa.gov/images/mrx/surf.png", 20, 20);
   var renderer = new SimpleRenderer(logo);
  csv.setRenderer(renderer);
  csv.attr('sites', 'sites');
  map.addLayer(csv);

  dojo.connect(map.infoWindow, "onHide", centerMap);
  map.on("click", mapClickAction);

   function showCoordinates(evt) {
   var mp = webMercatorUtils.webMercatorToGeographic(evt.mapPoint);
   var sp = screenUtils.toScreenGeometry(map.extent, 800, 550, evt.mapPoint);
  dom.byId("info").innerHTML = mp.x.toFixed(3) + ", " + mp.y.toFixed(3) + "<br>" + sp.x + " " + sp.y;
   }

   function centerMap(){
  map.graphics.clear();
  map.centerAt([-83.71, 36.05]);
   return;
   }

   function mapClickAction(evt) {
   var screenX = evt.screenPoint.x;
   var screenY = evt.screenPoint.y;

   var newScreenX = screenX + 225;
   var newScreenY = screenY + 250;

   var newScreenCenter = screenUtils.toMapPoint(map.extent, 800, 550, new ScreenPoint(newScreenX, newScreenY));

  map.centerAt(newScreenCenter);
   }
   });

   </script>

0 Kudos
1 Solution

Accepted Solutions
KenBuja
MVP Esteemed Contributor

Instead of using the map's click event, use the CSVLayer's click event

View solution in original post

9 Replies
KenBuja
MVP Esteemed Contributor

Instead of using the map's click event, use the CSVLayer's click event

EricHolweg
New Contributor

Ken...

Thanks for the reply. I was trying to access the CSVlayer click event but could not get it to work.

Stupid question but I get access to the map click event via

map.on("click", mapClickAction);

How do I get access to the CSVLayer object click event?

0 Kudos
KenBuja
MVP Esteemed Contributor

The syntax would be

csv.on("click", mapClickAction);

A couple other observations about your code. You're using dojo.connect in a few places. You should replace those with on

dojo.connect(kml, 'onLoad', function(lyr) {  

kml.on("load", function(lyr) {

and

dojo.connect(map.infoWindow, "onHide", centerMap);
map.infoWindow.on("hide", centerMap);

EricHolweg
New Contributor

Ken,

Thank you so much for the help. That was the solution. I appreciate your time.

I made the changes from

  1. dojo.connect(kml, 'onLoad', function(lyr) { 
  2.    var layers = lyr.getLayers(); 
  3.   dojo.forEach(layers, function(lyr) { 
  4.   lyr.setInfoTemplate(null); 
  5.    }); 
  6.    });

to

kml.on("load", function(lyr) {
                    var layers = lyr.getLayers();
                    dojo.forEach(layers, function(lyr) {
                        lyr.setInfoTemplate(null);
                    });
                });

and when I try to set the InfoTemplate to null so that it does not show up when a user clicks on the map...

It is now causing the entire kml shape to no longer display.

With the kml.on("load", function... the map looks like

With the dojo connect function the kml layer appears without the ability to click on that layer and have an info window display.

In the interest of coding this up properly with .on instead of dojo.connect... can anyone tell me what is going wrong?

I appreciate the help thus far.

0 Kudos
KenBuja
MVP Esteemed Contributor

I'm glad to help. Please remember to mark the original question as answered.

As for your new question,the "load" event function is returning a different object than the "onLoad" event function.

This is what is returned from the "load" event.

load.png

And this is what's returned from the "onLoad" event.

onload.png

You have to use the syntax "var layers = lyr.layer.getLayers();" in your "load" function to get the same object.

kml.on('load', function (lyr) {
    var layers = lyr.layer.getLayers();
    dojo.forEach(layers, function (lyr) {
        lyr.setInfoTemplate(null);
    });
});
EricHolweg
New Contributor

Ken.. thanks again.

I did run into a recurrence of the original problem. Now when I click on the csv points... I cannot get them to execute the click event that I had set up.

Was wondering if you could see what might be going wrong.

It is almost as if the csv layer is "beneath" the kml layer and therefore cannot have the csv.on("click", mapFcstAction) called.

The map.infowindow.on("hide", centerMap) call seems to work fine.

Kind of spinning my wheels right now with this.

Eric

map = new Map("map", {
                    basemap : "hybrid",
                    center : [-83.71, 36.05],
                    zoom : 8
                });

                map.on("load", function() {
                    map.infoWindow.set('anchor', 'bottom-right');
                    map.infoWindow.resize(625, 425);
                });
                map.infoWindow.on("hide", centerMap);

                urlUtils.addProxyRule({
                    proxyUrl : "/proxy/proxy.php",
                    urlPrefix : "www.srh.noaa.gov"
                });

                var template = new InfoTemplate("${name}", "<iframe src=${fcstlink} class="fcst"></iframe>");
                var csvUrl = "http://www.srh.noaa.gov/images/rtimages/mrx/js_local/riverpoints.csv";
                csv = new CSVLayer(csvUrl, {
                    copyright : "weather.gov",
                    infoTemplate : template
                });
                var logo = new PictureMarkerSymbol("http://www.srh.noaa.gov/images/mrx/surf.png", 20, 20);
                var renderer = new SimpleRenderer(logo);
                csv.setRenderer(renderer);
                map.addLayer(csv);
                csv.on("click", mapFcstAction);

                var kmlUrl = "http://www.srh.noaa.gov/images/rtimages/mrx/kml/RiversLakes.kml";
                kml = new KMLLayer(kmlUrl);
                map.addLayer(kml);

                kml.on('load', function(lyr) {
                    var layers = lyr.layer.getLayers();
                    array.forEach(layers, function(l) {
                        l.setInfoTemplate(null);
                    });
                });

                function centerMap() {
                    alert("CENTER");
                    map.graphics.clear();
                    map.centerAt([-83.71, 36.05]);
                }

                function mapFcstAction(evt) {
                    alert("FCST");
                    map.infoWindow.show(evt.screenPoint);
                    var screenX = evt.screenPoint.x;
                    var screenY = evt.screenPoint.y;
                    var newScreenX = screenX + 225;
                    var newScreenY = screenY + 250;
                    var newScreenCenter = screenUtils.toMapPoint(map.extent, 800, 550, new ScreenPoint(newScreenX, newScreenY));
                    map.centerAt(newScreenCenter);
                }
0 Kudos
KenBuja
MVP Esteemed Contributor

This is strange. I've tried adding in the CSVLayer after the KMLLayer, but the KMLLayer always appears on top. Even this code leaves the KMLLayer on top of the CSVLayer

kml.on("load", function() {
  map.addLayer(csv); 
})

I can't understand this, because according to the documentation, a two layers have different inheritance. The KMLLayer inherits directly from Layer

esri/layers/Layer

|_esri/layers/KMLLayer

while the CSVLayer inherits from GraphicsLayer

esri/layers/Layer
|_esri/layers/GraphicsLayer
|_esri/layers/FeatureLayer
   |_esri/layers/CSVLayer

Now a GraphicsLayer will always be on top of a Dynamic or Tiled layer, but I can't find any information about where a KMLLayer fits into this hierarchy.

I think you should start a new question to get some more knowledgeable people involved.

0 Kudos
EricHolweg
New Contributor

Thanks Ken... I followed up with another question this morning. This one really has me stumped... especially when it seemed to work fine using the old style dojo.connect.

0 Kudos
KenBuja
MVP Esteemed Contributor

You should move your other question to the ArcGIS API for JavaScript​ space to get more focused attention. I hadn't noticed that this discussion was in the more generic Developers​ space...or I would have suggested you move this one also.

0 Kudos