So what I want to do, is to be able to select a line feature (trails) and have related lines, based on attributes, selected too.
What I am thinking is in a data grid. I have been playing with ways to do this.
I have tried Query related records | ArcGIS API for JavaScript
I have tried Datagrid look up. Neither way seems to work the way I am wanting.
Ultimately I want to join this with the Elevations Profile web-app. I can do this part (I hope), if I can figure how to select related features.
Our data has multiple trails that split off of each other.
Solved! Go to Solution.
Rickey,
Here's some sample code that shows how to display related records. In this example click on a point then use the 'Show Related Records' link to display a table showing related record info.
If your resulting app (based on the Elevation template) is going to be public I'd love to see what you come up with.
<!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>
Rickey,
Here's some sample code that shows how to display related records. In this example click on a point then use the 'Show Related Records' link to display a table showing related record info.
If your resulting app (based on the Elevation template) is going to be public I'd love to see what you come up with.
<!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>
Thank you! That helped a lot!
I was wondering if there was a way to zoom to a record in the table? Or is the table the related table and one cannot zoom?
How can I remove some fields so they do not display in the table?
On another note, is it possible to have the relate table relate off of 3 different fields?
Yes you can zoom if the related data is a layer. In the example above its just tabular data so there is no feature geometry. To zoom you'll just get the geometry of the feature and set the map extent. There are several threads with more info on zooming to features and a good blog post here with more details.
You can remove fields by setting the outFields for the relatedQuery to include just the fields you are interested in so here we just get back info from two fields:
relatedQuery.outFields = ["YAPIID", "OPERATIONNUMBER"];
Then you'll want to update the code that generates the table columns to just display those two fields:
var columns = {
"YAPIID": "ID",
"OPERATIONNUMBER": "Op Number"
}
As far as having the relate table relate off of three different fields I'm not sure. Since the relationship is set up in ArcGIS Server you may want to post your question about creating the relationship to the ArcGIS Server place.
I replaced the relatedQuery and var columns like you suggested. The relatedQuery part worked but the table now shows every row and only populates the two fields.
Looks like the columns may not be specified correctly? Can you post that portion of your code?
I copied your suggestions into the code you provided above and it did not work.
//Setup the relationship query
var relatedQuery = new RelationshipQuery();
relatedQuery.outFields = ["ROUTE_1 ","ROUTE_2 ","NAME ","GROUP_","LENGTH"];
relatedQuery.relationshipId = 0;
relatedQuery.objectIds = [oids];
And
//define the columns
var relatedLayer = featureSet.features[0].getLayer();
var columns = {
"ROUTE_1": "Route 1",
"ROUTE_2": "Route 2 ",
"NAME ": "Name",
"GROUP_": "Group",
"LENGTH ": "Length (ft)"
};
array.forEach(relatedLayer.fields, function(f){
columns[f.name] = f.alias;
});
You need to remove this portion of code that creates a new column for each field in the layer.
array.forEach(relatedLayer.fields, function(f){
columns[f.name] = f.alias;
});
That was it,
Thank you!
My project is not done yet but you can go to the elevation link in my question to see my progress.
(if it is not working it is because I am still in development and I am changing the script)
I did find an issue with the related records code. For some reason the first time the map loads, the area where the related records table shows does not act properly. When I try to move the map, it highlights the map and will not let it move.
In the example you provided the bottom 15% (the side of the table) of the map cannot be navigated like normal.
Is there a way to change the z value or change the height to 0 until the table is displayed?
I also changed my services so that the related layer is a line layer. When I select the table it does not move to selected location.
"Yes you can zoom if the related data is a layer. In the example above its just tabular data so there is no feature geometry. To zoom you'll just get the geometry of the feature and set the map extent."
Any suggestions?
Thank you