Can I limit the contents of a featureTable to current map extent?

3611
5
Jump to solution
06-03-2016 01:32 PM
TracySchloss
Frequent Contributor

I have been using a dGrid for a long time and have set them to update on extent change to only list what's shown in the current map extent.

I don't see that I have that level of control using FeatureTable.  There's interaction from the table to the map, like Zoom to Selection, but nothing that goes the other way, map or layer to control the table.

I'd also have a definition expression tool I've added to limit the features on the map that way, and the table isn't honoring that either.

Am I missing something, or is that functionality just not available in a FeatureTable?  Too bad if it isn't since it means offering something that is faster (FeatureTable) at the expense of loss of functionality. 

0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Tracy,

  Here is a sample of how to filter the FeatureTable by the maps extent:

<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Using FeatureTable</title>
  <link rel="stylesheet" href="http://js.arcgis.com/3.16/dijit/themes/claro/claro.css">
  <link rel="stylesheet" href="http://js.arcgis.com/3.16/esri/css/esri.css">
  <script src="http://js.arcgis.com/3.16/"></script>

  <style>
    html, body, #map{
      width:100%;
      height:100%;
      margin:0;
      padding:0;
    }
  </style>

  <script>
    var map;

    require([
      "esri/layers/FeatureLayer",
      "esri/dijit/FeatureTable",
      "esri/geometry/webMercatorUtils",
      "esri/map",
      "dojo/dom-construct",
      "dojo/dom",
      "dojo/parser",
      "dojo/ready",
      "dojo/on",
      "dojo/_base/lang",
      "dijit/registry",
      "esri/tasks/query",
      "dijit/form/Button",
      "dijit/layout/ContentPane",
      "dijit/layout/BorderContainer",
      "dijit/form/TextBox"
    ], function (
      FeatureLayer, FeatureTable, webMercatorUtils, Map,
      domConstruct, dom, parser, ready, on,lang,
      registry, Query, Button, ContentPane, BorderContainer, TextBox
    ) {
      parser.parse();

      ready(function(){

        var myFeatureLayer;
        var map = new Map("map",{
          basemap: "streets"
        });

        map.on("load", loadTable);

        function loadTable(){

          // Create the feature layer
          myFeatureLayer = new FeatureLayer("https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Warren_College_Trees/FeatureServer...", {
            mode: FeatureLayer.MODE_ONDEMAND,
            visible: true,
            outFields: ["*"],
            id: "fLayer"
          });

          //set map extent
          on(myFeatureLayer, "load", function(evt){
            var extent = myFeatureLayer.fullExtent;
            if (webMercatorUtils.canProject(extent, map)) {
              map.setExtent( webMercatorUtils.project(extent, map) );
              on(map, 'extent-change', lang.hitch(this, function(params){
                var oidFld = myFeatureLayer.objectIdField;
                var query = new Query();
                query.geometry = params.extent;
                query.spatialRelationship = Query.SPATIAL_REL_CONTAINS;
                myFeatureLayer.queryIds(query, lang.hitch(this, function(objectIds) {
                  myFeatureTable.selectedRowIds = objectIds;
                  myFeatureTable._showSelectedRecords();
                }));
              }));
            }
          });

          map.addLayer(myFeatureLayer);

          myFeatureTable = new FeatureTable({
            "featureLayer" : myFeatureLayer,
            "outFields":  ["Collected","Crew","Status","Spp_Code", "Height", "Cmn_Name","Sci_Name","Street","Native"],
            "map" : map,
            "gridOptions": {}
          }, 'myTableNode');

          myFeatureTable.startup();
        }
      });
    });
  </script>
</head>

<body class="claro esri">
  <div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline'" style="width:100%; height:100%;">
    <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center', splitter:true" style="height:50%">
      <div id="map"></div>
    </div>
    <div id="bot" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'bottom', splitter:true" style="height:50%">
      <div id="myTableNode"></div>
    </div>
  </div>
</body>
</html>

And here is a thread where I provide a sample that allows for filtering based on user text:

Is it possible to filter the Feature Table?

View solution in original post

5 Replies
JoanneMcGraw
Occasional Contributor III

Tracy,

It seems to me that when you define the Query for your query task you can pass a geometry and tell it to return the features contained by that geometry. For example, you could use the Map object's current extents to limit the features returned from the feature layer.

Sorry, no details...just a suggestion of something that I have vague memories of from a couple of years ago. I just happened to notice your post because it was near my own.

Hope it helps and I'm not leading you in the wrong direction.

Cheers,

jtm

0 Kudos
TracySchloss
Frequent Contributor

You're describing exactly how I always populated my grid, but I'm not seeing that I can get that fine grained when I'm using a featureTable instead.  It's a lot more of a closed box in terms of determining what the store/memory is for it, and you don't set up any sort of query for it either.   It's more "Here's my featureLayer, how I want the table to display, and my div", and the object takes care getting its own store set up.  . 

The table offered in Web App Builder I believe does let you tie the table to the extent.  That functionality hasn't made it's way into the JS API featureTable object, as far as I can tell.  

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Tracy,

  Here is a sample of how to filter the FeatureTable by the maps extent:

<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Using FeatureTable</title>
  <link rel="stylesheet" href="http://js.arcgis.com/3.16/dijit/themes/claro/claro.css">
  <link rel="stylesheet" href="http://js.arcgis.com/3.16/esri/css/esri.css">
  <script src="http://js.arcgis.com/3.16/"></script>

  <style>
    html, body, #map{
      width:100%;
      height:100%;
      margin:0;
      padding:0;
    }
  </style>

  <script>
    var map;

    require([
      "esri/layers/FeatureLayer",
      "esri/dijit/FeatureTable",
      "esri/geometry/webMercatorUtils",
      "esri/map",
      "dojo/dom-construct",
      "dojo/dom",
      "dojo/parser",
      "dojo/ready",
      "dojo/on",
      "dojo/_base/lang",
      "dijit/registry",
      "esri/tasks/query",
      "dijit/form/Button",
      "dijit/layout/ContentPane",
      "dijit/layout/BorderContainer",
      "dijit/form/TextBox"
    ], function (
      FeatureLayer, FeatureTable, webMercatorUtils, Map,
      domConstruct, dom, parser, ready, on,lang,
      registry, Query, Button, ContentPane, BorderContainer, TextBox
    ) {
      parser.parse();

      ready(function(){

        var myFeatureLayer;
        var map = new Map("map",{
          basemap: "streets"
        });

        map.on("load", loadTable);

        function loadTable(){

          // Create the feature layer
          myFeatureLayer = new FeatureLayer("https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Warren_College_Trees/FeatureServer...", {
            mode: FeatureLayer.MODE_ONDEMAND,
            visible: true,
            outFields: ["*"],
            id: "fLayer"
          });

          //set map extent
          on(myFeatureLayer, "load", function(evt){
            var extent = myFeatureLayer.fullExtent;
            if (webMercatorUtils.canProject(extent, map)) {
              map.setExtent( webMercatorUtils.project(extent, map) );
              on(map, 'extent-change', lang.hitch(this, function(params){
                var oidFld = myFeatureLayer.objectIdField;
                var query = new Query();
                query.geometry = params.extent;
                query.spatialRelationship = Query.SPATIAL_REL_CONTAINS;
                myFeatureLayer.queryIds(query, lang.hitch(this, function(objectIds) {
                  myFeatureTable.selectedRowIds = objectIds;
                  myFeatureTable._showSelectedRecords();
                }));
              }));
            }
          });

          map.addLayer(myFeatureLayer);

          myFeatureTable = new FeatureTable({
            "featureLayer" : myFeatureLayer,
            "outFields":  ["Collected","Crew","Status","Spp_Code", "Height", "Cmn_Name","Sci_Name","Street","Native"],
            "map" : map,
            "gridOptions": {}
          }, 'myTableNode');

          myFeatureTable.startup();
        }
      });
    });
  </script>
</head>

<body class="claro esri">
  <div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline'" style="width:100%; height:100%;">
    <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center', splitter:true" style="height:50%">
      <div id="map"></div>
    </div>
    <div id="bot" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'bottom', splitter:true" style="height:50%">
      <div id="myTableNode"></div>
    </div>
  </div>
</body>
</html>

And here is a thread where I provide a sample that allows for filtering based on user text:

Is it possible to filter the Feature Table?

TracySchloss
Frequent Contributor

So far so good.  I added the code to my extent change handler and the table now contains only the current map extent features.   What is controlling the text in the grid header?  It states the number of records and the number selected.  Limiting the table, the values in the header still reflect the original total number of features. 

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Tracy,

  I noticed that too, but never had the time to track that one down.

0 Kudos