Hi all,
I’m working with Survey123 data in an ArcGIS Dashboard and need help filtering a parent layer based on selections from a child layer.
In the survey I capture incidents and locations, while the repeats then capture species observations related to each incident.
I want to allow dashboard users to select a species (from the repeat/child layer) and then filter the parent layer to show only the incidents/locations where that species was recorded.
I created a category selector using the species field from the child layer. I attempted to use filter actions, but I’m struggling to get the parent layer to respond correctly to selections from the child layer. In Actions I can't connect the species child layer to anything which filters the parent layer correctly. Either the data doesn't show at all or nothing happens.
Parent to parent and parent to child filter works across the dashboard.
I clearly seem to be missing something really obvious. Do I need to change the Survey itself? Is there a way to do this using Arcade expressions?
How can I dynamically filter the parent layer based on related child records? Are there best practices for setting up this kind of related record filtering in Dashboards?
Any guidance or examples would be much appreciated!
Thanks,
Philine
I am not sure if this is exactly what you are trying to sort out. But widget actions for filtering based on selections for widgets like tables are pretty straightforward and can be configured through the Actions tab of the widget. For instance, in the following example I have configured a filter action from my child layer to the parent layer based on selections made on the child layer table.
One way you could do this.
In your form outside of the repeat, add a hidden calculation field to hold a comma delimited list of all the species listed in the repeat. Use the join function to populate the field: join(',', ${Species}).
Then in the dashboard make a new category selector, use the repeat table as the source and group values of the species names for the category field. Then on the selector tab, in the operator section choose 'contains'. Then in the Actions tab set the parent table to filter on that newly created comma separate list field you created in theform. So basically it will check if the list contains that species name.
You most likely could accomplish the species list in Arcade as well, by recreating your parent feature set with the list included.
Yes, I suspected I might need to make the changes directly in the survey.
Unfortunately, it’s often only after a survey is set up that users decide what they want to see on the dashboard. I was hoping there might be a way to query the content without having to go back and edit the survey itself.
Could you advise how I can recreate the species list in the parent layer?
Ah, I used Grouped Values instead of Features.
When I switch to Features I can match Global/ParentID and the filter now lists all species from each incident. Any pointers to an Arcade script so I can group all the species by name and not have each listed by incident? So instead of 3 separate Bird entries I just see one and that filters all relevant incidents/locations from the parent ID?
You could group the species like that, but I think you will run into the same issue as above. Once you group you still have to have a way to match back to the parent table.
Here is a sample arcade code for a new data expression to add a comma delimited list to your parent table from related items in the child table. For the example I just used two fields so you will have to be sure your new feature set includes includes all the fields you need/want from the source.
//get data from parent and child tables
var portal = Portal('https://www.arcgis.com');
var parentTable = FeatureSetByPortalItem(portal,'<FeatureID>',layerIndex, ['globalid', 'Location']);//additional fields you need here
var childTable = FeatureSetByPortalItem(portal,'<FeatureID>',layerIndex, ['species', 'parentglobalid']);
// Schema for new feature set
var fields = [
{ name: 'Location', type: 'esriFieldTypeString' },
{ name: 'Species_List', type: 'esriFieldTypeString' }
//add all fields from parent table you want
];
var features = [];
for (var p in parentTable) {
var parentID = p.globalid;
var related = Filter(childTable, 'parentglobalid = @parentID');
var species = [];
for (var r in related) {
if (!IsEmpty(r.species)) {
Push(species, r.species);
}
}
var newFeature = {
attributes: {
Location: p.Location,
Species_List: Concatenate(species, ', ')
//additional fields from parent
}
};
Push(features, newFeature);
}
return FeatureSet({
fields: fields,
geometryType: '', // No geometry
features: features
});
Once you have this new table, you can use the instruction above i.e. group the species in your category selector, set it to contains, and filter on the new species list field in the new table.