AGOL: custom app template with one-to-many relate lookup/table?

5061
6
02-09-2015 11:42 AM
WolfgangGrunberg
New Contributor II

I learned in this thread that AGOL's WebApp Builder and the hosted application templates do not support one-to-many tables ... yet. Imported File GeoDB relates do show up in the AGOL Web Map interface ("Show Related Records" link in attribute popup).

Could anyone give me some recommendations or any pointers on how I could implement one-to-many attribute table look-ups for point features in a custom AGOL app template?

Are there non-Esri AGOL app templates that do it already?

0 Kudos
6 Replies
KellyHutchins
Esri Frequent Contributor

Here's an example of how to do this using the ArcGIS API for JavaScript:

<!DOCTYPE html>
  <html>
  <head>
  <title>Display Related Records</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
  <link rel="stylesheet" href="https://community.esri.com//jsdev.arcgis.com/3.13/dgrid/css/dgrid.css">
  <link rel="stylesheet" href="https://community.esri.com//jsdev.arcgis.com/3.13/dgrid/css/skins/claro.css">
  <link rel="stylesheet" href="http://js.arcgis.com/3.12/esri/css/esri.css">
  <style>
    html,body,#mapDiv,.map.container{
      padding:0;
      margin:0;
      height:100%;
    }
    #tableContainer{
      position: absolute;
      z-index: 99;
      bottom:0;
      right:0;
      left:0;
      height: 15%;
    }
  </style>


  <script>var dojoConfig = { parseOnLoad: true };</script>
  <script src="http://js.arcgis.com/3.12"></script>
  <script>
    var map,grid = null,
        webmapId = "283117cc8d5c4028acc30a0609d58254";


        //Note the web map id has related records 
    
    require([
      "esri/map",
      "esri/arcgis/utils",
      "dgrid/OnDemandGrid",
      "dojo/store/Memory",
      "esri/tasks/RelationshipQuery",
      "esri/domUtils",
      "dojo/dom-construct",
      "dojo/query",
      "dojo/_base/array",
      "dojo/_base/window",
      "dijit/registry",
      "dojo/on",
      "dojo/domReady!"
      ], function (Map, arcgisUtils, Grid, Memory, RelationshipQuery, domUtils, domConstruct, query, array, win, registry, on) {
        arcgisUtils.createMap(webmapId, "mapDiv").then(function (response) {
        map = response.map;
        on(map.infoWindow, "hide", function(){
          //close the table if open 
          clearGrid();
        });
        //add a link to the popup that for getting related records 
        var link = domConstruct.create("a",{
          "class": "action", 
          "id": "relatedLink",
          "innerHTML": "Show Related Records", //text that appears in the popup for the link 
          "href": "javascript: void(0);"
        }, query(".actionList", window.map.infoWindow.domNode)[0]);




        on(link, "click", function(){
          //Get info from the selected feature 
          var feature = map.infoWindow.getSelectedFeature();
          var layer = feature.getLayer();
          var OIDField = layer.objectIdField;
          var oids = feature.attributes[OIDField];


          //Setup the relationship query 
          var relatedQuery = new RelationshipQuery();
          relatedQuery.outFields = ["*"];
          relatedQuery.relationshipId = 0;
          relatedQuery.objectIds = [oids];


          //Perform the query
          layer.queryRelatedFeatures(relatedQuery, function(relatedRecords){
            //get the related records for the input OID. In this case there
            //is just one object id. 
            clearGrid();
            var featureSet = relatedRecords[oids];
            if(featureSet && featureSet.features){
             createTable(featureSet);
            }else{
              console.log("No related records");
            }




          });


        });
    });


      function clearGrid(){
        //clear existing grid 
        if(grid){
            grid.set("store",new Memory({data:[]}));
            domUtils.hide(grid.domNode);
        }
      }
      function createTable(featureSet, info){
        var data = [];      
        array.forEach(featureSet.features, function(r){
          data.push(r.attributes);
        });
        //define the columns
        var relatedLayer = featureSet.features[0].getLayer();
        var columns = {};
        array.forEach(relatedLayer.fields, function(f){
          columns[f.name] = f.alias;
        });
        var memoryStore =  new Memory({data: data});


        grid = new Grid({
          columns: columns
        },"tableContainer");




        grid.set("store", memoryStore);
        domUtils.show(grid.domNode);










      }
    });
  </script>


  </head>


  <body class="claro">
    <div id="mapDiv"></div>
    <div id="tableContainer"></div>
  </body>
  </html>
WolfgangGrunberg
New Contributor II

Thank you Kelly for the sample code!

WolfgangGrunberg
New Contributor II

Thanks again!

but ... We have experimented with Kelly's sample code using our test Web Map (webmapId a84674b1d474471e8ea8fa550f7f220b) and need some help/clarification.

The information we want to display is contained in featureSet.features.attributes (an array; lines 114 -116 in Kelly's code) - attributes in the layer and the related table (see image below).  How do I pull that information out to create the columns correctly?

Currently the "Show Related Records" table columns are being set to featureSet.features[0].getLayer(), specifically the alias and name fields in the layer (see lines 118 - 123 ) which are then put into a node/grid (line 126, etc.) for display via Dojo (?). This only displays feature attributes (uploaded ones and those created by AGOL) - not any of the related attributes.

one-to-many_featureSet-features-attributes.jpg

0 Kudos
KellyHutchins
Esri Frequent Contributor

Is your web map public? If so can you send me the id?

0 Kudos
WolfgangGrunberg
New Contributor II

Hi Kelly,

Thank you for your support!

The web map is public and here is the webmapId again: a84674b1d474471e8ea8fa550f7f220b

Ciao, WG

0 Kudos
C_EHoward
Occasional Contributor III

Is there any plan to incorporate this functionality anywhere other than Web App Builder? It would be nice to have a web app template capable of showing related records that is also  more pleasing to the eye (and our customers) than WAB. Currently I have to use the web map viewer and I would really  rather not have the whole AGOL login and header part of my app window.

0 Kudos