Does an OnRowClickHandler Event work with Feature Layers?

1000
9
02-06-2012 07:52 AM
EmilyLaMunyon
Occasional Contributor
Hi,
I have a Feature Layer that display results in a dojo datagrid. I would like to have the ability to click on the row and zoom to the related feature. I have this functionality working for dynamic layers, but when I try to use the same code for Feature Layers it does not work. Is there a difference in how dynamic layers and feature layers are zoomed to? Thanks for any info!!


function onDrawEnd(extent){
      navToolbar.deactivate();
      //id = "control";
      //select features within the draw extent
      var query = new esri.tasks.Query();
      query.geometry = extent;
      featureLayer.selectFeatures(query,esri.layers.FeatureLayer.SELECTION_NEW,function(features,selectionMethod){
        //add selected features to the grid
        if (document.getElementById("contSel").checked){
          showPointNameGrid();
       
        } else if(document.getElementById("survSel").checked){
         showSurveysNameGrid();
         

        }
        var items = dojo.map(features,function(feature){
          return feature.attributes;
        });
      if(document.getElementById("contSel").checked){
      searchType="selControl2";
        var data = {identifier:"POINT_NAME", items:items};
        var store = new dojo.data.ItemFileReadStore({data:data});
        var grid = dijit.byId('grid4'); 
        grid.setStore(store);
         

       featureLayer.selectFeatures.clear;
       
      } else if (document.getElementById("survSel").checked){
        var data = {identifier:"OBJECTID", items:items};
        var store = new dojo.data.ItemFileReadStore({data:data});
        var grid = dijit.byId('grid5'); 
        grid.setStore(store);
       featureLayer.selectFeatures.clear;
      }  
      });

   
      function toggleSelect (el) 
  {
   navToolbar.deactivate();
   alert(el.checked);
   if (el.checked)
   {
    switch (el.id)
    {
    case 'survSel': 
        searchType="selSurveys2";
     document.getElementById('contSel').checked = false;
      featureLayerUrl = "http://slcarcgisdev1/SLCOGIS/rest/services/public/SurveyorFS/FeatureServer/2";
         featureLayer = new esri.layers.FeatureLayer(featureLayerUrl,{
           mode:esri.layers.FeatureLayer.MODE_ONDEMAND,
           outFields:["OBJECTID"]
           });
         featureLayer.setSelectionSymbol(new esri.symbol.SimpleFillSymbol().setColor(new dojo.Color([255,255,0,0.5]))); 
   map.addLayer(featureLayer);
     break;    
    
    case 'contSel': 
         searchType="selControl2";
     document.getElementById('survSel').checked = false;
     featureLayerUrl = "http://slcarcgisdev1/SLCOGIS/rest/services/public/SurveyorFS/FeatureServer/0";
         featureLayer = new esri.layers.FeatureLayer(featureLayerUrl,{
           mode:esri.layers.FeatureLayer.MODE_ONDEMAND,
           outFields:["*"]
         });
         featureLayer.setSelectionSymbol(new esri.symbol.SimpleMarkerSymbol().setSize(8).setColor(new dojo.Color([160,214,238])));
   map.addLayer(featureLayer);
     break;
   }
   } else
   {
       switch (el.id)
    {
    case 'survSel': 
     document.getElementById('contSel').checked = true;
     break;
    case 'contSel': 
     document.getElementById('survSel').checked = true;
     break;
   }
   }
 }


//Zoom to Feature when row is clicked
  function onRowClickHandler(evt){ 
 }  if (searchType == "selControl2") { 
   var clickedTaxLotId = grid4.getItem(evt.rowIndex).POINT_NAME; 
   var selectedTaxLot; 
   dojo.forEach(map.graphics.graphics,function(graphic){ 
     if((graphic.attributes) && graphic.attributes.POINT_NAME === clickedTaxLotId){ 
    selectedTaxLot = graphic; 
    //added this part to build infotemplate
     map.infoWindow.setTitle(graphic.getTitle()); 
     map.infoWindow.setContent(graphic.getContent());
      //
    return; 
     } 
        }); 
  
   if ( selectedTaxLot.geometry.declaredClass == 'esri.geometry.Point' ) {
      map.centerAndZoom(selectedTaxLot.geometry, 11)
   var sp = map.toScreen(selectedTaxLot.geometry);
   map.infoWindow.show(selectedTaxLot.geometry, map.getInfoWindowAnchor(sp));
   } else {
   //alert("Polygon");
   var taxLotExtent = selectedTaxLot.geometry.getExtent(); 
   var screenpoint = map.toScreen(selectedTaxLot.geometry.getExtent().getCenter());
   var mappoint = map.toMap(screenpoint);
   map.centerAndZoom(selectedTaxLot.geometry,15);
   
   map.infoWindow.show(taxLotExtent.getCenter(), map.getInfoWindowAnchor(screenpoint));
   }
 
 }
     
      }



0 Kudos
9 Replies
StephenLead
Regular Contributor III
Hi Emily,

Yes, you can use a data grid with a feature layer. See the section which starts:

var clickedTaxLotId = grid4.getItem(evt.rowIndex).POINT_NAME; 
var selectedTaxLot; 
dojo.forEach(map.graphics.graphics,function(graphic){ 
  if((graphic.attributes) && graphic.attributes.POINT_NAME === clickedTaxLotId){ 


This specifies that each graphic in the map is iterated across - if the graphic's name matches the text value which was clicked in the data grid, the map will zoom to that graphic.

You could do the same thing with the feature layer. Another option could be to reverse the logic and run a Query, where the Where clause was based on the value that you clicked in the grid, and you would zoom to the extent of the result.

Good luck,
Steve
0 Kudos
EmilyLaMunyon
Occasional Contributor
I am still struggling with getting my OnRow Function to zoom to a feature layer.The error in Firebug says that selectedTaxLot is undefined on this line of code:
if ( selectedTaxLot.geometry.declaredClass == 'esri.geometry.Point' ) { .

This same OnRow function works with a graphics layer, just not a my Feature Layer so far.

Am I referring to the featureLayer correctly? Any help would be greatly appreciate..I amm really stuck on this one:confused:

  dojo.connect(map, 'onLoad', function(theMap) {
     //initialize the toolbar
          toolBar = new esri.toolbars.Draw(map);
          dojo.connect(toolBar, "onDrawEnd",onDrawEnd);          
          toolBar.deactivate();
       
      //resize the map when the browser resizes
      dojo.connect(dijit.byId('map'), 'resize', map,map.resize);
       navToolbar.deactivate();
     featureLayerUrl = "http://slcarcgisdev1/SLCOGIS/rest/services/public/SurveyorFS/MapServer/2";
      
      featureLayer = new esri.layers.FeatureLayer(featureLayerUrl,{
          mode:esri.layers.FeatureLayer.MODE_ONDEMAND,
          outFields:["*"]
        });
       featureLayer.setSelectionSymbol(new esri.symbol.SimpleFillSymbol().setColor(new dojo.Color([255,255,0,0.5]))); 
  map.addLayer(featureLayer); 
        
  }); 
       
  //Zoom to Feature from row click
       function onRowClickHandler(evt){ 
       if (searchType == "selControl2") { 
 var clickedTaxLotId = grid5.getItem(evt.rowIndex).doc_id; 
 var selectedTaxLot; 
 var highlightSymbol = new esri.symbol.SimpleMarkerSymbol().setColor(new dojo.Color([25,50,225,0.3])); 
 dojo.forEach(map.graphics.graphics,function(featureLayer){ 
 if((featureLayer.attributes) && featureLayer.attributes.doc.id === clickedTaxLotId){ 
 selectedTaxLot = featureLayer; 
 featureLayer.setSymbol(highlightSymbol);
 return; 
     } 
        }); 
  
 if ( selectedTaxLot.geometry.declaredClass == 'esri.geometry.Point' ) {
 map.centerAndZoom(taxLotExtent, 11)
 var sp = map.toScreen(selectedTaxLot.geometry);
 } else {
  
 var taxLotExtent = selectedTaxLot.geometry.getExtent(); 
 var screenpoint = map.toScreen(selectedTaxLot.geometry.getExtent().getCenter());
 var mappoint = map.toMap(screenpoint);
 map.setExtent(taxLotExtent,true);
 map.infoWindow.show(taxLotExtent.getCenter(), map.getInfoWindowAnchor(screenpoint));
 }
     } 

 
0 Kudos
StephenLead
Regular Contributor III
Hi Emily,

dojo.forEach(map.graphics.graphics,function(featureLayer){ 
  if((featureLayer.attributes) && featureLayer.attributes.doc.id === clickedTaxLotId){ 
    selectedTaxLot = featureLayer; 


I think you should be working with features, not a feature layer, in the highlighted sections.

Can you provide a link to your site?

Cheers,
Steve
0 Kudos
EmilyLaMunyon
Occasional Contributor
Hi Steve,

Thanks again for your reply. Unfortunately, our server is in a test environment and is only available internally. I will try to change the code to features instead of featureLayer and see what happends.

Thanks 😄
0 Kudos
EmilyLaMunyon
Occasional Contributor
Me again..

I tried this, and Firebug is still giving me an error saying selectedTaxLot is undefined on this line if (selectedTaxLot.geometry.declaredClass == 'esri.geometry.Point'):

var clickedTaxLotId = grid4.getItem(evt.rowIndex).POINT_NAME; 
   var selectedTaxLot; 
    var highlightSymbol = new esri.symbol.SimpleMarkerSymbol().setColor(new dojo.Color([25,50,225,0.3])); 
   dojo.forEach(map.graphics.graphics,function(features){ 
     if((graphic.attributes) && graphic.attributes.POINT_NAME === clickedTaxLotId){ 
    selectedTaxLot = features; 
    featureLayer.setSymbol(highlightSymbol);
    return; 
     } 
        }); 
  
   if ( selectedTaxLot.geometry.declaredClass == 'esri.geometry.Point' ) {
   map.centerAndZoom(taxLotExtent, 11)
   var sp = map.toScreen(selectedTaxLot.geometry);
  
   } else {
  
   var taxLotExtent = selectedTaxLot.geometry.getExtent(); 
   var screenpoint = map.toScreen(selectedTaxLot.geometry.getExtent().getCenter());
   var mappoint = map.toMap(screenpoint);
   map.setExtent(taxLotExtent,true);
   map.infoWindow.show(taxLotExtent.getCenter(), map.getInfoWindowAnchor(screenpoint));
   }
  


0 Kudos
StephenLead
Regular Contributor III
selectedTaxLot is undefined on this line if (selectedTaxLot.geometry.declaredClass == 'esri.geometry.Point'):

var clickedTaxLotId = grid4.getItem(evt.rowIndex).POINT_NAME; 
            var selectedTaxLot; 
             var highlightSymbol = new esri.symbol.SimpleMarkerSymbol().setColor(new dojo.Color([25,50,225,0.3])); 
            dojo.forEach(map.graphics.graphics,function(features){ 
              if((graphic.attributes) && graphic.attributes.POINT_NAME === clickedTaxLotId){ 
                selectedTaxLot = features; 
 


features should be an array, not a single feature, therefore the last line above won't work.

Try putting a Firebug breakpoint on the line if((graphic.attributes)... and see the value of features. You probably want to use features[0].

Cheers,
Steve
0 Kudos
EmilyLaMunyon
Occasional Contributor
Thanks again Steve!

I am still not having any luck.

When I add an alert(features[0]); to my code, I get an error saying it is undefined. If I add alert(featureLayer); I get an alert reading object:Object.

I am not sure what this means.
0 Kudos
TracySchloss
Frequent Contributor
When I've done this, I start with a featureLayer that is defined with the mode esri.layers.FeatureLayer.SELECTION.  I've even set an additional featurelayer up specifically for this purpose, calling it selectFeatureLayer if I also need to have it available ON_DEMAND.

Also in my selectFeatures function, I am getting to a single features with

var feature = features[0]


Here is the function I have for my clickHandler.  Not the same as yours, but maybe you will spot something:
 function onRowClickHandler(evt){ 
        map.graphics.clear();
        map.infoWindow.hide();
        var OID = grid.getItem(evt.rowIndex).OBJECTID; 
        var query = new esri.tasks.Query();
        query.objectIds = [OID];
        parcelFeatureLayer.selectFeatures(query,esri.layers.FeatureLayer.SELECTION_NEW, function (features) {
           var parcelExtent = esri.graphicsExtent(features);
           parcelExtent.expand(2);
           map.setExtent(parcelExtent); 
                var feature = features[0];               
                var centerPt = parcelExtent.getCenter();
                feature.setInfoTemplate(parcelInfoTemplate);              
                map.infoWindow.setTitle(feature.attributes.PID);
                map.infoWindow.setContent(feature.getContent());//from the infoTemplate defined in the original featureLayer definition
                 var labelPt = new esri.geometry.Point(centerPt, spatialReference);
                map.infoWindow.show(labelPt);
        });
   
        
      } 
0 Kudos
DianaBenedict
Occasional Contributor III
I noticed that you are using


var query = new esri.tasks.Query();
query.objectIds = [OID];


Have you not experienced issues with setting up a query with only query.objectIds.  I posted last week a disucssion that indicated that the Javascript API (3.3) seems to not perform well when using query.objectIds.  When I changed my query to

query.where = "OBJECTID = " + OID;

I ran the query using the where clause instead and the performance was way faster and I consistently was able to get my feature(s) of interest. 

Also, I just to confirm (as others have) that the returned value is an array of Graphics. So in order to get your 1 record of interest you would need to do the following (myReturnFeatures[0].geometry) to get back your geometry that was selected.

I have also found that you can simply how you get the extent geometry of any selection that returns an array of graphics by using the following:

var zoomExtent = esri.graphicsExtent(graphicsArray);
//esri.graphicsExtent will return null if the extent height and width are 0
if (!zoomExtent) {
    var geomArray = esri.getGeometries(graphicsArray);
    var deferred = bufferGeometry("http://myserver/arcgis/rest/services/Utilities/Geometry/GeometryServer",
                            geomArray, [0.1], map.spatialReference, map.spatialReference);
    deferred.then(function (results) {
      map.setExtent(results[0].getExtent());
    }, function (error) {
      alert("Error during buffer Geom: " + error.message);
    });
  } else {
    if (expandFactor) {
      map.setExtent(extent.expand(expandFactor));
    } else {
      map.setExtent(extent);
    }
  }


Note that the bufferGeometry is a sample test function that I wrote that buffers a geometry point. This method is only called if the returned extent is null --> which implies that we are dealing with a single point that has no extent.
0 Kudos