Custom Widget 1.1 Feature Layer getSelectedFeatures zero count

4787
11
Jump to solution
06-08-2015 12:57 PM
JasonHaught
New Contributor II

I have recently been working on porting our custom widget from version 1.0 to version 1.1.

The same code  was working in 1.0 but no longer seems to respect selected features in 1.1.*

//Gets the specific graphicsLayer requested
var layer = this.map.getLayer(this.map.graphicsLayerIds);

//Verify the layer is a feature layer from base type graphics layer
 if (layer.type && layer.type === "Feature Layer")
 {
          var features = layer.getSelectedFeatures();
            //The map shows features selected within a popup, but this code always returns a zero count in 1.1
            var count  = features.length;
}

Did something change between versions in this code logic?

Why would the features.length be zero, but the feature layer popup show features?

The Feature Service being used was from an ArcGIS Server version 10.1 SP1.  I switched to using featue services in 10.2 and the issue still remains.

Any insight would be appreciated,

Jason

*On a related note, I noticed the previous WebMap we used in 1.0 would not work at all since the JS API did not recognize the map.graphicsLayerIds.length. The graphicsLayerIds.length was returning a count of zero. After some fiddling around, I discovered the WebMap now required that feature layers be added one by one to the WebMap. You cannot simply just point to the main feature service as previously worked in 1.0. I don't know if this was a change in the AGOL WebMap, the Esri JS API, ArcGIS Server version for Feature services, or some combination of the sort.

0 Kudos
1 Solution

Accepted Solutions
JasonHaught
New Contributor II

I don't know what changed between versions, but as best I can tell a feature click on the map used to select the feature(s) now it just identifies!

The solution requires that your widget calls selectFeatures (for each feature layer you care about). I see no other way as I could not find select tools or built-in click events that do this.

The breakdown for selection:

1) Add a Select tool such as "esri/toolbars/draw" and hook a click event from a UI element to call .activate(Draw.EXTENT);

2)  Wire up the DrawEnd event and for each feature layer call selectFeatures with your desired options (e.g. FeatureLayer.SELECTION_ADD)

3) Wire up features to the event "selection-complete"

4) In the "selection-complete" handle event you can add graphics to the map in order to show what is selected.

5) Add a clear button so you can call map.graphics.clear() and for each feature layer call clearSelection().

View solution in original post

0 Kudos
11 Replies
JunshanLiu
Occasional Contributor III

It seems that there are some changes in JS API, I am not sure why this function doesn't work, maybe you can get a clue from API reference: FeatureLayer | API Reference | ArcGIS API for JavaScript

In selection mode, features are retrieved from the server only when they are selected. Features are available on the client only while they are selected. To work with selected features:

  1. Call the selectFeatures method.
  2. Listen for the onSelectionComplete event.
  3. Once onSelectionComplete fires, retrieve the selected features using the getSelectedFeatures method.

BTW, in v1.0, we use 3.12 API, in v1.1, we use 3.13 API.

0 Kudos
JasonHaught
New Contributor II

The key here is that my Widget is not controlling the selection of features.

Instead, it assumes the user selected features through some other mechanism, such as a click.

From there, once the widget is opened (onOpen event), it calls the code I posted above to check for selected features.

So perhaps I should instead hook the onSelectionComplete events for all feature layers during the widget startup event. When onOpen is called, the widget should already know what features are selected.

I will see if this is possible even though I am not calling the selectFeatures method.

0 Kudos
KellyHutchins
Esri Frequent Contributor

Jason Haught

If you want the selected features then the approach Junshan Liu​ suggests is correct. Here's a snippet showing this.

        var layer = map.getLayer("csv_9076_0");
        layer.on("selection-complete", function(){
          var features = layer.getSelectedFeatures();
          console.log(features);
          console.log(map.infoWindow.features);
        });
JasonHaught
New Contributor II

Yep , exactly, that is what I was suggesting I would do next.

After testing popup click selections, and attribute table selections, the hooked event never fires in my widget code?

Here is the code in widget startup that hooks but with no errors but never fires.

Maybe I should have my own select tool in the widget.

          var len = this.map.graphicsLayerIds.length;
          var hasFeatLayers = false;
          if (len == 0)
          {
              console.log('Missing map.graphicsLayerIds *************');
          }
          else
          {
              for (i = 0; i < len; i++)
              {
                  var layer = this.map.getLayer(this.map.graphicsLayerIds);
                  if (layer.type === "Feature Layer" && layer.url)
                  {
                      //Check the version of the feature layer to make sure we can query it
                      var flVersion = layer.version;
                      
                      //break;
                      if (flVersion < 10.1)
                      {
                          console.log('******Unsupported Feature layer: "' + layer.name + '" version: "' + flVersion + '" will be ignored.************');
                      }
                      else
                      {
                          console.log('Feature layer: "' + layer.name + '" url: "' + layer.url + '" version: "' + flVersion + '".');
                          hasFeatLayers = true;
                          //layer.on("selection-complete", this._HandleFeatureSelectionEvent);
                          layer.on("selection-complete", function(){  
                                   //var features = layer.getSelectedFeatures();  
                                   console.log("! selection-complete FIRED !");
                                   //console.log(map.infoWindow.features);  
                              });  
                          featureLayers.push(layer);
                      }
                      
                  }
              }
          }
0 Kudos
KellyHutchins
Esri Frequent Contributor

If you set a breakpoint in your code is layer defined?  Are there any errors?

0 Kudos
JasonHaught
New Contributor II

There are no errors and the layer can be seen in my "Locals" during a breakpoint as a layer object.

HookSelectFeatures.png

I added my own select tool.  When I do that, the event does fire!  I was hoping to avoid having my own select tool, but I can go that route if need be.

SelectFires.png

0 Kudos
JunshanLiu
Occasional Contributor III

Attribute table doesn't always use selectFeature(). it uses query if the layer has a URL, uses selectFeature if it

's a feature collection, so this event may not be triggered.

0 Kudos
JasonHaught
New Contributor II

Good to know.

So what about a click select of a feature(s) that brings a popup in the UI?

0 Kudos
JasonHaught
New Contributor II

I don't know what changed between versions, but as best I can tell a feature click on the map used to select the feature(s) now it just identifies!

The solution requires that your widget calls selectFeatures (for each feature layer you care about). I see no other way as I could not find select tools or built-in click events that do this.

The breakdown for selection:

1) Add a Select tool such as "esri/toolbars/draw" and hook a click event from a UI element to call .activate(Draw.EXTENT);

2)  Wire up the DrawEnd event and for each feature layer call selectFeatures with your desired options (e.g. FeatureLayer.SELECTION_ADD)

3) Wire up features to the event "selection-complete"

4) In the "selection-complete" handle event you can add graphics to the map in order to show what is selected.

5) Add a clear button so you can call map.graphics.clear() and for each feature layer call clearSelection().

0 Kudos