Select to view content in your preferred language

RelationshipQuery using 4.10

1070
7
Jump to solution
02-20-2019 11:21 AM
ToddFagin
Frequent Contributor

Quick background. I currently have a feature layer that represents insect traps (this is a mock dataset with just two points for now). Occasionally, field technicians will go and inspect the traps and record the findings in a related table (we will ultimately use Collector for this). I am also developing an associated webapp. I would like to use JSAPI 4.10 to enable a user to click on a feature and the related table (showing the field inspections) open.

This is actually something I previously did on another project using 3.15 in conjunction with bootstrap. When I update this old code with the new feature layer, it still works in 3.15. However, since I plan to integrate this into a larger app utilizing the newer version of the API, I would like to update it to 4.10. Thus far, I have failed miserably in this regard. Additionally, there may be a far more elegant and straightforward solution than I am trying to use, but I cannot find any examples (which I need since I follow the mantra of "code by cannibalization" since I really don't know what I am doing--ha)!!! For instance, here is a real simply web map I made in ArcGIS Online that has a popup with the option to show related records that, when clicked, the related table opens. I oh so want to believe there is a straight forward way to do this with the JSAPI.

Below are two examples that I have. The first uses 3.15 and works. The second 4.10 and doesn't work. As I said, though, if there are better solutions out there, I would gladly explore those.

Example 1: This works (but I don't have an option to close the table, which is another issue, but not the one I am addressing now)

<!DOCTYPE html>  
<html>  
 
<head>  
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">  
  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">  
  <title>Related Table</title>  
  <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">  
  <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.2.4/bootstrap-table.min.css">  
  <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>  
  <!-- cool bootstrap plugin for working with tables  
    //http://wenzhixin.net.cn/p/bootstrap-table/docs/index.html  
  -->  
  <script src="http://rawgit.com/wenzhixin/bootstrap-table/master/dist/bootstrap-table.min.js"></script>  
  <link rel="stylesheet" href="http://js.arcgis.com/3.15/dijit/themes/claro/claro.css">  
  <link rel="stylesheet" href="http://js.arcgis.com/3.15/esri/css/esri.css">  
  <style>  
    html,  
    body {  
      height: 100%;  
      width: 100%;  
      margin: 0;  
      padding: 0;  
    }  
 
    #map {  
      width: 100%;  
      height: 100%;  
      margin: 0;  
      padding: 0;  
    }  
 
    .claro .dijitTooltipContainer {  
      background-image: none;  
      border: 1px solid #444444;  
      background-color: #444444;  
      color: #FFFFFF;  
    }  
 
    .claro .dijitTooltipConnector {  
      background-image: none;  
    }  
 
    #info-pane {  
      position: absolute;  
      top: 10px;  
      right: 10px;  
      z-index: 1000;  
      padding: 1em;  
      background: white;  
    }  
 
    .fixed-table-container {  
      position: absolute;  
      bottom: 10px;  
      left: 10px;  
      z-index: 1000;  
      padding: 1em;  
      background: white;  
    }  
 
    .fixed-table-body {  
      max-height: 400px;  
      max-width: 600px;  
    }  
 
    #hidden {  
      display: none;  
    }  
  </style>  
  <script src="http://js.arcgis.com/3.15/"></script>  
  <script>  
    require([  
      "dojo/dom-construct",  
      "dojo/parser",  
      "esri/Color",  
      "esri/config",  
      "esri/dijit/Popup",  
      "esri/dijit/PopupTemplate",  
      "esri/layers/ArcGISTiledMapServiceLayer",  
      "esri/layers/FeatureLayer",  
      "esri/map",  
      "esri/tasks/query",  
      "esri/tasks/QueryTask",  
      "esri/tasks/RelationshipQuery",  
      "esri/symbols/SimpleFillSymbol",  
      "esri/symbols/SimpleLineSymbol",  
      "esri/tasks/GeometryService",  
      "dojo/on",  
      "dojo/domReady!"  
      ], function (  
      domConstruct,  
      parser,  
      Color,  
      esriConfig,  
      Popup,  
      PopupTemplate,  
      ArcGISTiledMapServiceLayer,  
      FeatureLayer,  
      Map,  
      Query,  
      QueryTask,  
      RelationshipQuery,  
      SimpleFillSymbol,  
      SimpleLineSymbol,  
      GeometryService,  
      on  
    ) {  
      parser.parse();  
      currentBasemap = []  
 
      map = new Map("map", {  
        center: [-98.435731, 35.222876],  
        zoom: 7,  
        slider: false,  
        logo: false  
      });  
 
      relief = new ArcGISTiledMapServiceLayer("http://services.arcgisonline.com/arcgis/rest/services/World_Physical_Map/MapServer")    
      currentBasemap.push(relief);    
 
      var traps = new FeatureLayer("https://services.arcgis.com/3xOwF6p0r7IHIjfn/arcgis/rest/services/OBWEO_Collector_Test/FeatureServer/0", {    
        mode: FeatureLayer.MODE_ONDEMAND,    
      });  
      map.addLayers([relief, traps]);  
      traps.on("click", queryRelated);  
 
      //Here's the code with which I am having issue  
 
      function queryRelated(evt) {  
        var content  
        var feature = evt.graphic;  
        var relatedOWBEOQuery = new RelationshipQuery();  
        relatedOWBEOQuery.outFields = ["*"];  
        relatedOWBEOQuery.relationshipId = 0;  
        relatedOWBEOQuery.objectIds = [feature.attributes[traps.objectIdField]];  
        traps.queryRelatedFeatures(relatedOWBEOQuery, function (relatedRecords) {  
          var fset = relatedRecords[feature.attributes[traps.objectIdField]];  
          if (fset.features.length > 0) {  
            var results = [];  
            for (i = 0; i < fset.features.length; i++) {  
              results.push(fset.features.attributes);  
            }  
            $('#my-table').removeClass('hidden');  
            //you can only call refresh() when loading from a url  
            $('#my-table').bootstrapTable('destroy');  
            $('#my-table').bootstrapTable({  
              data: results,  
              cache: false,  
              striped: true,  
              clickToSelect: true,  
              columns: [{    
                  field: 'TRAPID',    
                  title: 'Trap ID',    
                  sortable: true,    
                  order: 'asc'    
              }, {    
                  field: 'Trapper',    
                  title: 'Trapper No.',    
                  sortable: true,    
              }, {    
                  field: 'Date',    
                  title: 'Date',    
                  sortable: true    
              }, {    
                  field: 'WeevilsCaught',    
                  title: 'Weevils Caught',    
                  sortable: true    
              }, {    
                  field: 'Condition',    
                  title: 'Trap Condition',    
                  sortable: true    
              }, {    
                  field: 'Comment',    
                  title: 'Comment',    
                  sortable: true    
              }
              , {    
                  field: 'Status',    
                  title: 'Status',    
                  sortable: true    
              }]  
            });  
          }  
        });  
      }  
    });  
  </script>  
</head>  
 
<body class="claro">  
  <div id="my-table" class="hidden">  
  </div>  
  <div id="map"></div>   
</body>  
 
</html>

Example 2: My crude and failed attempt to migrate to 4.10

<!DOCTYPE html>
<html dir="ltr">

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" />
  <title>Related Table</title>
 
  <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">  
  <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.2.4/bootstrap-table.min.css">  
  <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>  
 
  <script src="http://rawgit.com/wenzhixin/bootstrap-table/master/dist/bootstrap-table.min.js"></script>

  <link rel="stylesheet" href="https://js.arcgis.com/4.10/esri/css/main.css">
  <script src="https://js.arcgis.com/4.10/"></script>

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

  <script>
    require([
      "esri/Map",
      "esri/views/MapView",
      "esri/layers/FeatureLayer",
      "esri/tasks/support/Query",
      "esri/tasks/QueryTask",
      "esri/tasks/support/RelationshipQuery"
    ], function(Map, MapView, FeatureLayer, Query, QueryTask, RelationshipQuery) {

      // setup the map
      var map = new Map({
        basemap: "streets"
      });
      var view = new MapView({
        container: "mapDiv",
        map: map,
        center: [-98.338, 35.636],
        zoom: 7
      });
      
      
      const pointRenderer = {
          type: "simple", // autocasts as new SimpleRenderer()
          symbol: {
            type: "simple-marker", // autocasts as new SimpleMarkerSymbol()
            size: 8,
            color: [0, 0, 0],
            outline: null
          }
        };

      var traps = new FeatureLayer({
        url: "https://services.arcgis.com/3xOwF6p0r7IHIjfn/arcgis/rest/services/OBWEO_Collector_Test/FeatureServer/0",
        renderer: pointRenderer,
        outFields: ["*"]
      });
      map.add(traps);
      traps.on("click", queryRelated);
      
      function queryRelated(evt) {  
        var content  
        var feature = evt.graphic;  
        var relatedOWBEOQuery = new RelationshipQuery();  
        relatedOWBEOQuery.outFields = ["*"];  
        relatedOWBEOQuery.relationshipId = 0;  
        relatedOWBEOQuery.objectIds = [feature.attributes[traps.objectIdField]];  
        traps.queryRelatedFeatures(relatedOWBEOQuery, function (relatedRecords) {  
          var fset = relatedRecords[feature.attributes[traps.objectIdField]];  
          if (fset.features.length > 0) {  
            var results = [];  
            for (i = 0; i < fset.features.length; i++) {  
              results.push(fset.features.attributes);  
            }  
            $('#my-table').removeClass('hidden');  
            //you can only call refresh() when loading from a url  
            $('#my-table').bootstrapTable('destroy');  
            $('#my-table').bootstrapTable({  
              data: results,  
              cache: false,  
              striped: true,  
              clickToSelect: true,  
              columns: [{    
                  field: 'TRAPID',    
                  title: 'Trap ID',    
                  sortable: true,    
                  order: 'asc'    
              }, {    
                  field: 'Trapper',    
                  title: 'Trapper No.',    
                  sortable: true,    
              }, {    
                  field: 'Date',    
                  title: 'Date',    
                  sortable: true    
              }, {    
                  field: 'WeevilsCaught',    
                  title: 'Weevils Caught',    
                  sortable: true    
              }, {    
                  field: 'Condition',    
                  title: 'Trap Condition',    
                  sortable: true    
              }, {    
                  field: 'Comment',    
                  title: 'Comment',    
                  sortable: true    
              }
              , {    
                  field: 'Status',    
                  title: 'Status',    
                  sortable: true    
              }]  
            });  
          }  
        });  
      }
      
      
    });
  </script>

</head>

<body>
  <div id="mapDiv"></div>
</body>

</html>

Thanks in advance. I appreciate any help on this.

Todd

0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Todd,

  You weren't to far off. Mainly your issue was understanding that layer do not have a click event in 4.x:

<!DOCTYPE html>
<html dir="ltr">

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" />
  <title>Related Table</title>

  <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
  <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.2.4/bootstrap-table.min.css">
  <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>

  <script src="http://rawgit.com/wenzhixin/bootstrap-table/master/dist/bootstrap-table.min.js"></script>

  <link rel="stylesheet" href="https://js.arcgis.com/4.10/esri/css/main.css">
  <script src="https://js.arcgis.com/4.10/"></script>

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

    .claro .dijitTooltipContainer {
      background-image: none;
      border: 1px solid #444444;
      background-color: #444444;
      color: #FFFFFF;
    }

    .claro .dijitTooltipConnector {
      background-image: none;
    }

    #info-pane {
      position: absolute;
      top: 10px;
      right: 10px;
      z-index: 1000;
      padding: 1em;
      background: white;
    }

    .fixed-table-container {
      position: absolute;
      bottom: 20px;
      left: 10px;
      z-index: 1000;
      padding: 1em;
      background: white;
    }

    .fixed-table-body {
      max-height: 400px;
      max-width: 600px;
    }

    #hidden {
      display: none;
    }
  </style>

  <script>
    require([
      "esri/Map",
      "esri/views/MapView",
      "esri/layers/FeatureLayer",
      "esri/tasks/support/Query",
      "esri/tasks/QueryTask",
      "esri/tasks/support/RelationshipQuery"
    ], function(Map, MapView, FeatureLayer, Query, QueryTask, RelationshipQuery) {

      // setup the map
      var map = new Map({
        basemap: "streets"
      });
      var view = new MapView({
        container: "mapDiv",
        map: map,
        center: [-98.338, 35.636],
        zoom: 7
      });


      const pointRenderer = {
        type: "simple", // autocasts as new SimpleRenderer()
        symbol: {
          type: "simple-marker", // autocasts as new SimpleMarkerSymbol()
          size: 8,
          color: [0, 0, 0],
          outline: null
        }
      };

      var traps = new FeatureLayer({
        url: "https://services.arcgis.com/3xOwF6p0r7IHIjfn/arcgis/rest/services/OBWEO_Collector_Test/FeatureServer/0",
        renderer: pointRenderer,
        outFields: ["*"]
      });
      map.add(traps);
      traps.on("click", queryRelated);

      view.on("click", function(evt) {
        view.hitTest(evt).then(function(response) {
          if (response.results.length) {
            var graphic = response.results.filter(function(result) {
              // check if the graphic belongs to the layer of interest
              return result.graphic.layer === traps;
            })[0].graphic;
            if (graphic) {
              queryRelated(graphic);
            }
          }
        })
      });

      function queryRelated(gra) {
        var content
        var feature = gra;
        var relatedOWBEOQuery = new RelationshipQuery();
        relatedOWBEOQuery.outFields = ["*"];
        relatedOWBEOQuery.relationshipId = 0;
        relatedOWBEOQuery.objectIds = [feature.attributes[traps.objectIdField]];
        traps.queryRelatedFeatures(relatedOWBEOQuery).then(function(relatedRecords) {
          var fset = relatedRecords[feature.attributes[traps.objectIdField]];
          if (fset.features.length > 0) {
            var results = [];
            for (i = 0; i < fset.features.length; i++) {
              results.push(fset.features[i].attributes);
            }
            $('#my-table').removeClass('hidden');
            //you can only call refresh() when loading from a url
            $('#my-table').bootstrapTable('destroy');
            $('#my-table').bootstrapTable({
              data: results,
              cache: false,
              striped: true,
              clickToSelect: true,
              columns: [{
                field: 'TRAPID',
                title: 'Trap ID',
                sortable: true,
                order: 'asc'
              }, {
                field: 'Trapper',
                title: 'Trapper No.',
                sortable: true,
              }, {
                field: 'Date',
                title: 'Date',
                sortable: true
              }, {
                field: 'WeevilsCaught',
                title: 'Weevils Caught',
                sortable: true
              }, {
                field: 'Condition',
                title: 'Trap Condition',
                sortable: true
              }, {
                field: 'Comment',
                title: 'Comment',
                sortable: true
              }, {
                field: 'Status',
                title: 'Status',
                sortable: true
              }]
            });
          }
        });
      }
    });
  </script>

</head>

<body>
  <div id="my-table" class="hidden">
  </div>
  <div id="mapDiv"></div>
</body>

</html>

View solution in original post

7 Replies
RobertScheitlin__GISP
MVP Emeritus

Todd,

  You weren't to far off. Mainly your issue was understanding that layer do not have a click event in 4.x:

<!DOCTYPE html>
<html dir="ltr">

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" />
  <title>Related Table</title>

  <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
  <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.2.4/bootstrap-table.min.css">
  <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>

  <script src="http://rawgit.com/wenzhixin/bootstrap-table/master/dist/bootstrap-table.min.js"></script>

  <link rel="stylesheet" href="https://js.arcgis.com/4.10/esri/css/main.css">
  <script src="https://js.arcgis.com/4.10/"></script>

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

    .claro .dijitTooltipContainer {
      background-image: none;
      border: 1px solid #444444;
      background-color: #444444;
      color: #FFFFFF;
    }

    .claro .dijitTooltipConnector {
      background-image: none;
    }

    #info-pane {
      position: absolute;
      top: 10px;
      right: 10px;
      z-index: 1000;
      padding: 1em;
      background: white;
    }

    .fixed-table-container {
      position: absolute;
      bottom: 20px;
      left: 10px;
      z-index: 1000;
      padding: 1em;
      background: white;
    }

    .fixed-table-body {
      max-height: 400px;
      max-width: 600px;
    }

    #hidden {
      display: none;
    }
  </style>

  <script>
    require([
      "esri/Map",
      "esri/views/MapView",
      "esri/layers/FeatureLayer",
      "esri/tasks/support/Query",
      "esri/tasks/QueryTask",
      "esri/tasks/support/RelationshipQuery"
    ], function(Map, MapView, FeatureLayer, Query, QueryTask, RelationshipQuery) {

      // setup the map
      var map = new Map({
        basemap: "streets"
      });
      var view = new MapView({
        container: "mapDiv",
        map: map,
        center: [-98.338, 35.636],
        zoom: 7
      });


      const pointRenderer = {
        type: "simple", // autocasts as new SimpleRenderer()
        symbol: {
          type: "simple-marker", // autocasts as new SimpleMarkerSymbol()
          size: 8,
          color: [0, 0, 0],
          outline: null
        }
      };

      var traps = new FeatureLayer({
        url: "https://services.arcgis.com/3xOwF6p0r7IHIjfn/arcgis/rest/services/OBWEO_Collector_Test/FeatureServer/0",
        renderer: pointRenderer,
        outFields: ["*"]
      });
      map.add(traps);
      traps.on("click", queryRelated);

      view.on("click", function(evt) {
        view.hitTest(evt).then(function(response) {
          if (response.results.length) {
            var graphic = response.results.filter(function(result) {
              // check if the graphic belongs to the layer of interest
              return result.graphic.layer === traps;
            })[0].graphic;
            if (graphic) {
              queryRelated(graphic);
            }
          }
        })
      });

      function queryRelated(gra) {
        var content
        var feature = gra;
        var relatedOWBEOQuery = new RelationshipQuery();
        relatedOWBEOQuery.outFields = ["*"];
        relatedOWBEOQuery.relationshipId = 0;
        relatedOWBEOQuery.objectIds = [feature.attributes[traps.objectIdField]];
        traps.queryRelatedFeatures(relatedOWBEOQuery).then(function(relatedRecords) {
          var fset = relatedRecords[feature.attributes[traps.objectIdField]];
          if (fset.features.length > 0) {
            var results = [];
            for (i = 0; i < fset.features.length; i++) {
              results.push(fset.features[i].attributes);
            }
            $('#my-table').removeClass('hidden');
            //you can only call refresh() when loading from a url
            $('#my-table').bootstrapTable('destroy');
            $('#my-table').bootstrapTable({
              data: results,
              cache: false,
              striped: true,
              clickToSelect: true,
              columns: [{
                field: 'TRAPID',
                title: 'Trap ID',
                sortable: true,
                order: 'asc'
              }, {
                field: 'Trapper',
                title: 'Trapper No.',
                sortable: true,
              }, {
                field: 'Date',
                title: 'Date',
                sortable: true
              }, {
                field: 'WeevilsCaught',
                title: 'Weevils Caught',
                sortable: true
              }, {
                field: 'Condition',
                title: 'Trap Condition',
                sortable: true
              }, {
                field: 'Comment',
                title: 'Comment',
                sortable: true
              }, {
                field: 'Status',
                title: 'Status',
                sortable: true
              }]
            });
          }
        });
      }
    });
  </script>

</head>

<body>
  <div id="my-table" class="hidden">
  </div>
  <div id="mapDiv"></div>
</body>

</html>
ToddFagin
Frequent Contributor

Thank you for the reply and assistance.

Immediately after posting, I had to head  out of the office for a conference. It will likely be a day or two before I get to dig into this. Nonetheless, in the meantime, I wanted to express my gratitude.

Take care,

Todd

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

OK, just don't forget to mark this question as answered by clicking on the "Mark Correct" link on the reply that answered your question when you get back to this.

ToddFagin
Frequent Contributor

Done.

As an aside, and I will dig deeper later, when I found this Bootstrap solution three or four years ago, I recall it was a necessary workaround because the then current API didn't handle what I wanted to do (I could be wrong there).

If possible, I would like to stay primarily (or solely) within the 4.10 API (this is just because of my limited skills and knowledge in these regards--It makes my life somewhat easier). Is there any solution you would recommend beyond this hack. I am just wanting a pointer here--everything I do comes from modifying other examples I have found elsewhere. There are  likely many examples I am overlooking.

As always, much appreciated.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Todd,

   Here it is without bootstrap or jQuery:

<!DOCTYPE html>
<html dir="ltr">

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" />
  <title>Related Table</title>

  <link rel="stylesheet" href="https://js.arcgis.com/4.10/esri/css/main.css">
  <script src="https://js.arcgis.com/4.10/"></script>

  <style>
    html,
    body,
    #viewDiv {
      height: 100%;
      width: 100%;
      margin: 0;
      padding: 0;
      overflow: hidden;
    }

    .dgrid-header,
    .dgrid-header-row {
      background-color: #eee;
      color: #57585A;
    }

    .dgrid-row-even {
      background-color: #F7F8F8;
    }

    .dgrid-row-odd {
      background-color: #EFEFEF;
    }

    .dgrid-row {
      border: none
    }

    .dgrid {
      height: 10em;
      width: 600px;
    }

    #gridDisplay {
      position: absolute;
      background-color: white;
      border-color: grey;
      font-family: "Avenir Next W00", "Helvetica Neue", Helvetica, Arial, sans-serif;
      font-size: 14px;
      display: none;
      bottom: 20px;
      left: 10px;
      z-index: 1000;
      padding: 1em;
      max-height: 400px;
      max-width: 600px;
      overflow-x: auto;
    }
  </style>

  <script>
    require([
      "esri/Map",
      "esri/views/MapView",
      "esri/layers/FeatureLayer",
      "esri/tasks/support/Query",
      "esri/tasks/QueryTask",
      "esri/tasks/support/RelationshipQuery",
      "dojo/_base/declare",
      "dgrid/OnDemandGrid",
      "dgrid/extensions/ColumnResizer",
      "dojo/store/Memory",
      "dstore/legacy/StoreAdapter",
      "dojo/dom-class",
      "dojo/date/locale"
    ], function(Map, MapView, FeatureLayer, Query, QueryTask, RelationshipQuery, declare,
      OnDemandGrid, ColumnResizer, Memory, StoreAdapter, domClass, locale) {

      let grid;
      let gridFields = ["TRAPID", "Trapper", "Date",
        "WeevilsCaught", "Condition" ,"Comment" ,"Status"
      ];

      const gridDis = document.getElementById("gridDisplay");

      const dataStore = new StoreAdapter({
        objectStore: new Memory({
          idProperty: "TRAPID"
        })
      });

      // setup the map
      var map = new Map({
        basemap: "streets"
      });
      var view = new MapView({
        container: "viewDiv",
        map: map,
        center: [-98.338, 35.636],
        zoom: 7
      });

      const pointRenderer = {
        type: "simple", // autocasts as new SimpleRenderer()
        symbol: {
          type: "simple-marker", // autocasts as new SimpleMarkerSymbol()
          size: 8,
          color: [0, 0, 0],
          outline: null
        }
      };

      var traps = new FeatureLayer({
        url: "https://services.arcgis.com/3xOwF6p0r7IHIjfn/arcgis/rest/services/OBWEO_Collector_Test/FeatureServer/0",
        renderer: pointRenderer,
        outFields: ["*"]
      });
      map.add(traps);

      view.on("click", function(evt) {
        view.hitTest(evt).then(function(response) {
          if (response.results.length) {
            var graphic = response.results.filter(function(result) {
              // check if the graphic belongs to the layer of interest
              return result.graphic.layer === traps;
            })[0].graphic;
            if (graphic) {
              queryRelated(graphic);
            }
          }
        })
      });

      function createGrid(columns) {
        grid = new (declare([ OnDemandGrid, ColumnResizer ]))({
          columns: columns
        }, "grid");
      }

      function formatTimestamp(value) {
        var inputDate = new Date(value);
        return locale.format(inputDate, {
          selector: 'date',
          datePattern: 'MM/dd/yyyy'
        });
      }

      function doClear() {
        if(grid){
          dataStore.objectStore.data = {};
          grid.set("collection", dataStore);
        }
        // gridDis.style.display = 'none';
      }

      function queryRelated(gra) {
        doClear();
        var feature = gra;
        var relatedOWBEOQuery = new RelationshipQuery();
        relatedOWBEOQuery.outFields = ["*"];
        relatedOWBEOQuery.relationshipId = 0;
        relatedOWBEOQuery.objectIds = [feature.attributes[traps.objectIdField]];
        traps.queryRelatedFeatures(relatedOWBEOQuery).then(function(relatedRecords) {
          var fset = relatedRecords[feature.attributes[traps.objectIdField]];
          if (fset.features.length > 0) {
            gridDis.style.display = 'block';
            var results = [];
            for (i = 0; i < fset.features.length; i++) {
              results.push(fset.features[i].attributes);
            }
            var columns =  [{
                field: 'TRAPID',
                label: 'Trap ID',
                sortable: true
              }, {
                field: 'Trapper',
                label: 'Trapper No.',
                sortable: true
              }, {
                field: 'Date',
                label: 'Date',
                sortable: true,
                formatter: formatTimestamp
              }, {
                field: 'WeevilsCaught',
                label: 'Weevils Caught',
                sortable: true
              }, {
                field: 'Condition',
                label: 'Trap Condition',
                sortable: true
              }, {
                field: 'Comment',
                label: 'Comment',
                sortable: true
              }, {
                field: 'Status',
                label: 'Status',
                sortable: true
              }];
            createGrid(columns);

            // get the attributes to display in the grid
            var data = fset.features.map(function(feature, i) {
              return Object.keys(feature.attributes)
                .filter(function(key) {
                  // get fields that exist in the grid
                  return (gridFields.indexOf(key) !== -1);
                })
                // need to create key value pairs from the feature
                // attributes so that info can be displayed in the grid
                .reduce((obj, key) => {
                  obj[key] = feature.attributes[key];
                  return obj;
                }, {});
            });

            // set the datastore for the grid using the
            // attributes we got for the query results
            dataStore.objectStore.data = data;
            grid.set("collection", dataStore);
          }
        });
      }
    });
  </script>

</head>

<body>
  <div id="viewDiv">
    <div id="gridDisplay">
      <div id="grid"></div>
    </div>
  </div>
</body>

</html>
ToddFagin
Frequent Contributor

This is fantastic. Thank you for taking the time to do this. I am now looking into dgrid trying to learn more about it.

ToddFagin
Frequent Contributor

Once again, this is great.

I made a small addition for anyone else who may stumble across this thread.

For some reason (the best I can tell, at least) dgrid doesn't have a way to close the data grid once opened. The easy fix for me was to add a button with a tiny bit of JS to the gridDisplay div:

<div id="gridDisplay">
       <button class="button" onclick="document.getElementById('gridDisplay').style.display='none'" >x</button>
      <div id="grid"></div>
    </div>

I don't know if this is the most elegant solution, but it works.

Thanks again for your assistance.