Pop-up Arcade Expression- Show List of Field Names if field Value matches expression

4881
17
Jump to solution
01-17-2020 08:57 AM
DaveAlmond
New Contributor III

Xander Bakker

I would like to create a popup that shows field names in the attribute table if the field value for the feature equals 1. 

Specifically, my Bus Stops table has a field for each bus route (A, B, C, D, etc. 22 in all) if the stop is served by a route, the field value is 1, if not, the field value is 0. I want the popup to show only the routes that serve the selected stop.  I know I need to iterate the route fields (but not all fields in the table) to evaluate whether the route field value is 1, and then add those field names (the route name) to a list and then return the list. I could do this in Python, but I am not as familiar with Arcade.  I tried checking some of the other posts on lists https://community.esri.com/people/mmckeanesriaustralia-com-au-esridist/blog/2019/10/07/creating-aggr...  but I couldn't glean what I needed since my Arcade is very basic. Thanks!

1 Solution

Accepted Solutions
XanderBakker
Esri Esteemed Contributor

Hi dalmond ,

I think you should be able to do something like this (see below). It will loop through the list of field names defined on line 1 (include all 22 here) and when the field has a value 1 it will add the route to the string to be returned at the end of the expression:

var route_flds = ['RouteA', 'RouteB', 'RouteC', 'RouteD'];
var routes = "Routes served at this stop:";

for (var i in route_flds) {
    if ($feature[route_flds[i]] == 1) {
        routes += TextFormatting.NewLine + " - " + route_flds[i];
    }
}

return routes;

View solution in original post

17 Replies
XanderBakker
Esri Esteemed Contributor

Hi dalmond ,

I think you should be able to do something like this (see below). It will loop through the list of field names defined on line 1 (include all 22 here) and when the field has a value 1 it will add the route to the string to be returned at the end of the expression:

var route_flds = ['RouteA', 'RouteB', 'RouteC', 'RouteD'];
var routes = "Routes served at this stop:";

for (var i in route_flds) {
    if ($feature[route_flds[i]] == 1) {
        routes += TextFormatting.NewLine + " - " + route_flds[i];
    }
}

return routes;
DaveAlmond
New Contributor III

Thank you, Xander. Works great! You help so many people here and it is really a great service how you keep us all moving forward. 🙂 

Dave

XanderBakker
Esri Esteemed Contributor

Hi dalmond ,

You are welcome! I'm glad it works.

0 Kudos
BenBaker1
Occasional Contributor

I am trying to accomplish a similar task, by only showing items that failed a previous inspection. 

I'm currently using these statements:

Exit and Passageways  (heading)

var field1 = $feature.Doors;IIf(field1 == 'fail', 'Doors: unlocked & unobstructed, operational: Fail',‘’);

var field2 = $feature.Corridors;IIf(field2 == 'fail', 'Corridors: unobstructed, properly maintained 36" min: Fail',‘’);

General Hazards (heading)

var field13 = $feature.HazRubbish;IIf(field13 == 'fail', 'Hazardous accumulation of rubbish: Fail',‘’);

var field14 = $feature.Stock;IIf(field14 == 'fail', 'Stock properly stored: Fail',‘’);

But I am thinking there's a way to loop through multiple fields and only show the heading if one or more of the questions evaluates to  'fail'. Is that possible? I tried the for loop below, but something's not right

0 Kudos
XanderBakker
Esri Esteemed Contributor

Hi bbaker_mhgis ,

To use the code that I shared earlier, you should change you lines 4 into:

var exit_flds = ["Doors", "Corridors"];

... this way on line 7 it will use $feature["Doors"] and $feature["Corridors"].

0 Kudos
BenBaker1
Occasional Contributor

Thank you Xander. That was what I was  missing. I did some more digging on this, because I was ending up with a lot of blank lines in my popup. I cleaned up my expression and then decided to go the HTML route discussed elsewhere to achieve what I'm wanting. I have the following expression to evaluate if any of the items in the list failed the last inspection (expression/expr0):

var exit_flds = ["Doors", "Corridors", "Stairs", "PanicHardware", "ExitSigns", "EmergencyLighting"];
for (var i in exit_flds){
   if ($feature[exit_flds] == 'fail'){
      return "inline";
   } else {

      return "none";
}

Then, I have expressions for each inspection item (6 expressions from exit_flds above):

if($feature.Doors == 'fail'){
   return "inline";

} else {
   return "none";
}

However, when I use the HTML below, the header (expression/expr0) does not always evaluate to "inline" when it should. For example, the popup on the left displays correctly, whereas the popup on the right has an item that failed, but is not displaying the header. 

I have successfully set up a series of else if statements that work, but shouldn't the list do the same thing?

HTML:

<br style="display:{expression/expr0}" /><span style="display:{expression/expr0}"><font color="”#000000”"><b><u>Exits and Passageways</u></b></font></span>

<br style="display:{expression/expr1}" /><span style="display:{expression/expr1}">Doors: unlocked &amp; unobstructed, operational: <font color="#ff0000"><b>Fail</b></font></span>

<br style="display:{expression/expr2}" /><span style="display:{expression/expr2}">Corridors: unobstructed, properly maintained 36” minimum: <font color="#ff0000"><b>Fail</b></font></span>

<br style="display:{expression/expr3}" /><span style="display:{expression/expr3}">Stairs: unobstructed, rails &amp; stairs maintained: <font color="#ff0000"><b>Fail</b></font></span>

<br style="display:{expression/expr4}" /><span style="display:{expression/expr4}">Panic Hardware: existing, operational: <font color="#ff0000"><b>Fail</b></font></span>

<br style="display:{expression/expr5}" /><span style="display:{expression/expr5}">Exit Signs: present, operational: <font color="#ff0000"><b>Fail</b></font></span>

<br style="display:{expression/expr12}" /><span style="display:{expression/expr12}">Emergency Lighting: present, operational: <font color="#ff0000"><b>Fail</b></font></span>

0 Kudos
XanderBakker
Esri Esteemed Contributor

Hi Ben Baker ,

I did not read your complete post, but there is something you will need to change in the first expression. When you use return inside a loop, it will exit the loop when it hits the return. So, in your case it will just use the first value.

Try something like this instead:

var exit_flds = ["Doors", "Corridors", "Stairs", "PanicHardware", "ExitSigns", "EmergencyLighting"];
var result = "none"
for (var i in exit_flds){
   if ($feature[exit_flds[i]] == 'fail'){
      return "inline";
}
return result;

It will return "none", unless any field value equals "fail".

0 Kudos
BenBaker1
Occasional Contributor

That was exactly what I needed. I've just started using Arcade, so those nuances are tricky. I'll have to set up expressions for each category and then each attribute, but the HTML is working well and reducing the blank spaces. Thank you!

0 Kudos
BenBaker1
Occasional Contributor

An unrelated note, so please advise if I should direct this elsewhere, but am I correct in my understanding that Arcade expressions don't pass through to the hosted view when a Join function is run in ArcGIS Online?

0 Kudos