Conditional Field display with Arcade in Pop Ups

77383
118
07-18-2017 11:53 AM
KellyGerrow
Esri Frequent Contributor
42 118 77.4K

The June 2017 Release of ArcGIS Online enabled the capability to write custom Arcade expressions for use in Pop Ups!! A common request was to be able to format pop ups to display attribute values and labels when values are present and not have them appear when the values are blank. Although there are plans to incorporate this functionality directly into the pop up in the future, it is currently possible to use Arcade and Custom Attribute Displays to accomplish this.

I'm going to use an existing example of my Heron Watch Data and display the description when one is present. I will hide the field value and field label when it isn't present. View the Heron location in Singapore to see a feature with no description, or add features using this GeoForm App with no description.  

Check out the steps below to accomplish this and then share your real examples!

Step 1: Create an Arcade Expression that tests for values using IsEmpty. This will be used to determine if the label for the attribute needs to be displayed or not. 

Sample code:

    IIF(isEmpty($feature.description), "", "Description")

If the feature is empty, a blank value will be returned. If there is a value, the label "Description" will be returned in the expression.

2. Configure a table using Custom Attribute Display in the pop ups that is configured to use the expression as the label.

        Custom Attribute

    - Enable the option to view Source HTML:

    

- Create a table using the HTML  sample below. The text in curly brackets refer to attribute values in the feature layer. The plain text between the first table elements specifies the label for each attribute.

<table cellpadding="0px" cellspacing="3px">
     <tbody>
           <tr valign="top">
               <td><b>Observed Time (UTC)</b></td>
               <td><span>{viewed}</span> 
               </td>
            </tr>
            <tr valign="top">
               <td><b> Observed Time (Local) </b></td>
               <td>{textviewed}</td>
            </tr>
            <tr valign="top">
              <td><b>Species</b></td>
              <td>{type_of_heron}</td>
            </tr>
           <tr valign="top">
               <td><b>{expression/expr0}</b></td>
               <td>{description}</td>
           </tr>
      </tbody>
</table>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

- Note that {expression/expr0} is the value of the Arcade expression created in Step 1 that is used for the attribute label and the description value is used for the value. If no value is present in the description there will also be no value for the label.

- Unselect the HTML Source option and your formatted pop up configuration should look similar to this screen shot:

3. Save your Web Map and make an app to show off your Pop Ups

Description Values Present:

Description Values not Present

If you don't want to use a table to display your attributes, consider integrating this workflow with free text and calculated Arcade Expressions as outlined in this blog by Bernie Szukalski:

https://blogs.esri.com/esri/arcgis/2015/12/28/custom-attribute-display-pop-ups/ 

118 Comments
AdrianWelsh
MVP Honored Contributor

CCatania-esristaff‌, is there a way to add a "Helpful" button to blog posts (similar to what you see on Documents in the GeoNet)? I think that would add much value to the GeoNet content and can allow me to give credit to various blogs that are very helpful, like this one!

ChrisCatania
Esri Community Team

Thanks, Adrian. I'll pass on this feedback and keep you updated. 

AdrianWelsh
MVP Honored Contributor

Chris, I turned it into an ArcGIS Idea

https://community.esri.com/ideas/13705 

I hope it's clear (I may have put too many words in there).

AnninaHirschi_Wyss1
Occasional Contributor III

Hi Kelly Gerrow

Thanks for this! Amazing what you can do with Arcade... I have just a question:

  • Is there a way to write a script for "hiding" several attributes at once or do I have to write an expression for each of them? Or if not, is there a way to "upload" expressions? Would be useful if there are many attributes to hide conditionally.

Thanks a lot for your help,

Annina

KellyGerrow
Esri Frequent Contributor

Hi a.hirschi-wyssesri-rw-esridist‌,

Currently, each hidden attribute will need to have an individual expression. This can be time consuming if many fields require this (we are working on a better solution).

-Kelly

AnninaHirschi_Wyss1
Occasional Contributor III

That's what I was afraid of... For the moment, I keep a txt file with the expressions and a html file for the pop up for editing, and then copy it to AGOL. A bit tedious, but feasible, while waiting for your improvements! 🙂

BPriyaK
New Contributor III

Hello Kelly,
Great article !
I'm using arcade expressions in a webmap for voting precints and voting stations .

There is a relationship between these two feature classes and show the voting station when you click inside the boundary of a precint.

I'm working on arcade expressions to show a message if there is no voting station information and your blog article is exaclty what I was looking for.

However I'm curious to know if there is way to reference related table fields in the expression.
In the configure attributes drop down you would find related records something like {relationships/0/NAME}.
Is there a way to reference these from the globals in the scripting window.

Any help will be appreciated
Thanks

JaredPilbeam1
Occasional Contributor

Hi Kelly,

This is a great post. It basically does what I wanted to achieve in my pop-ups.

I have a bunch of points on my web map that are tourist attractions. Some have websites available, some do not. But, they're all in the same attribute table. I have a "URL" field, and when relevant there's a url to the website. This is where your post came in handy.

The only thing is that my attribute field is dealing with a link (visible in the background here). Would you have an idea how to configure it so the link is live? It's currently showing up as text.

Lake_Worth_BeachAdmin
Occasional Contributor III

I have a layer with a "Completed" field with 4 unique values. - design phase - future year - under construction - completed

in my pop-up configs I have "Status: {Completed}"

How can I use Arcade to change the color of the status value text based on its value?

eg. completed = green under construction = orange, design phase black future years light grey

RowenaTansley
New Contributor

Hi Bhanu, did you figure out your question with ArcAde and related tables? I am trying to do something similar. Thanks!

KellyGerrow
Esri Frequent Contributor

Hi Bhanu Vedula‌ and Rowena Tansley

Currently it isn't possible to include related tables with Arcade. It is something that we are researching currently. COuld you log an idea on https://community.esri.com/community/arcgis-ideas?sr=search&searchId=231afc25-6cbc-4569-8a05-a2abe12...‌ so we can track this request and the workflows that you would like to accomplish with them.

KellyGerrow
Esri Frequent Contributor

Hey Joe,

You can do this using similar logic. Here is an example I made classifying Earthquake magnitudes by colour. (It's not a stellar cartographic example, but you should be able to find the different classifications.)

App: https://webapps.maps.arcgis.com/apps/Minimalist/index.html?appid=5789741c078f4464a4657ae77e81fc28 

Web Map:https://www.arcgis.com/home/webmap/viewer.html?webmap=7cf2c86a661f45d29c29a568164bbaa1 

I made 6 expressions for each classification, similar to which returns the value of moderate if the magnitude is greater than 5 and less than 6 and returns nothing if the expression doesn't apply: 

IIf($feature.mag >= 5.0 && $feature.mag < 6, "Moderate", "")

When configuring the pop up, include all of the expressions in different colours. The correct expression will display for the mag value.

For your specific example try creating expressions for each status then colour code each response in the pop up.:

IIf($feature.completed == "under construction",  "under construction", "") 

Logical Functions | ArcGIS for Developers 

-Kelly

RowenaTansley1
New Contributor III

posted idea here, please upvote! https://community.esri.com/ideas/14016 

JaredPilbeam2
MVP Regular Contributor

At the moment, using the conditional field display on a field with a hyperlink will not work. It has been logged as a defect:

BUG-000108413 : When using a custom attribute display pop-up with a hyperlink field, null values in the hyperlink field result in a link to a blank page.

I've been trying to set up a conditional field display for a pop up using a field with a hyperlink. Using the HTML sample above, I simply changed out your fields for mine. Then I set up the Arcade expression to show the link in the pop up when it's available. The expression does what it is supposed to, but when there is a link to display it is not linked:

Lake_Worth_BeachAdmin
Occasional Contributor III

I am doing the same, IIF(field == '1', 'URL goes here','')

and I am adding this expression to my hyperlink in the pop-up configs but it directs to a blank page for everything. 

XanderBakker
Esri Esteemed Contributor

As an alternative you could use inline styles and use just one expression to define the color of the text:

HTML:

<p style="color:{expression/expr0};"><font size="6">{expression/expr1}</font></p>

Expression to define the style "{expression/expr0}":

var days = Round(DateDiff(Now(), $feature.FechaHora, "days"),0);

// classify the range of values (7 - 17)
var result = "";
if (days < 9) {
    result = "#08830E";
} else if (days < 11) {
    result = "#84E212";
} else if (days < 13) {
    result = "#FFFF00";
} else if (days < 15) {
    result = "#F7A000";
} else {
    result = "#B00900";
}

return result;

The other expression is just to calculate the days open "{expression/expr1}", but could simply point to a field: 

var days = DateDiff(Now(), $feature.FechaHora, "days");
return days;

The result will be like this:

 

  

JaredPilbeam2
MVP Regular Contributor

Here's a link to Esri Support's bug list if you want to keep track (sign-in required): https://my.esri.com/#/support/bugs 

by Anonymous User
Not applicable

Kelly Gerrow‌ , Annina Hirschi Wyss‌ and Team Esri great posts!!  Thank you for examples. For me, I learn the best seeing examples, to understand how things work; these quite nice.  Controlling HTML via attribute data is great. It will be key to allow more HTML rendering however, as well. https://community.esri.com/thread/202841-create-html-for-popup-with-arcade 

The main reason I want this is to hide Hyperlink field(s), if the hyperlink is blank. For example the Invasive Species layer (at bottom) in this viewer I am developing. It will be good to see Arcade support this and even better when it can conditionally hide fields i.e. hyperlinks via the standard popup configuration interface.

Lake_Worth_BeachAdmin
Occasional Contributor III

Hi Kevin,

I believe your request can be done in the pop ups.

1. Are your hyperlinks a field within the feature?

if so use the following expression to only display the hyperlink field if it is not blank:

IIF(IsEmpty($feature.Hyperlink),'','$feature.Hyperlink')

---> if the field if blank show '' if its not blank show the feature "Hyperlink" just replace the hyperlink text for the name of the field containing your links.

AnninaHirschi_Wyss1
Occasional Contributor III

Hi Kevin,

In my case I had to do it like this (I don't know exactly why, but there might be blanks in the data), and I wanted to hide the "label" as well.

Expression:

//Hide the URL Label if field is empty {expression/expr0}
var url = $feature.Link
IIF(url == " ","","Contact");

Pop up (custom attribute display):

<body>

<table>

<tr>

<td style="color: #888888; padding-right: 5px;">{expression/expr0}</td>
<td><a href="{Link}" target"_blank"="">{Link}</a></td>

</tr>

</table>

</body>

This works if your url is at the end of the pop up. If its in the middle, you will have to add the expression Joe has written and replace the second {Link} (not the one inside the <a href="") with that expression. Otherwise you'll have an empty row in the middle your pop up.

HTH,

Annina

Lake_Worth_BeachAdmin
Occasional Contributor III

Minor update, remove the single quotes from the last $feature.Hyperlink. the expression should look like below:

IIF(IsEmpty($feature.Hyperlink),'',$feature.Hyperlink)

JosephKerski
Esri Notable Contributor

Extremely wonderful - thank you !  I added my Florida heron picture to the map 🙂 

My own contribution here is simple (% of 20-somethings in cities) but this is usually what I have time to demonstrate in longer workshops:

https://community.esri.com/community/education/blog/2017/01/06/using-custom-expressions-in-arcgis-on...

Thank you!

--Joseph Kerski 

SueJohnston
New Contributor III

Hi Kelly, 
Is this still the case, that each hidden attribute will need to have an individual expression?  I believe I'm attempting to do something similar to Annina, loop through a set of fields and only show those that contain a value.

Great article, very helpful!
Thanks!
Sue

KellyGerrow
Esri Frequent Contributor

Hi Sue,

Currently each attribute still needs an individual expression.

Thanks,

-Kelly

by Anonymous User
Not applicable

Awesome stuff everyone. Arcade is sweet, I will be getting to the project for the links Annina soon and let you know how ti goes!  General question - is there any way to simply tell it to display all fields?  In other words to basically replicate the popup as if it were the default out-of-the-box popup. Kind of like the {"*"} infotemplate trick.  Reason I ask, is most often I just need to add one link to a popup. or make a field clickable. I don't want to have to manually re-create all the html for all the other fields and then get it spaced nicely like how the popup does out of the box for its own css/dom. Plus that way if Arcade could programmatically grab all fields, and spit them into the popup template, that would mean if fields changed or were added etc it would catch that automatically. So I could put a custom link by choosing "Custom Attribute Display" and then have the Arcade handle putting all the rest of the normal fields in, just as they would be for a regular popup. And it would maintain itself. 

XanderBakker
Esri Esteemed Contributor

Hi Kevin MacLeod , 

Arcade does not have an {"*"} option. The way to add an additional field is using Arcade. The expression can be used to create the URL/link and this will appear as an additional field that will be displayed in the pop-up by default. Although you can create an expression to create HTML with Arcade, this will not be interpreted as HTML and you will end up with simple text showing the HTML tags, which will not be what you want.

by Anonymous User
Not applicable

Xander thank you and yes indeed - it does an excellent job with all the great examples everyone has posted here.

My other thought now, is I have to manually create HTML for all the other fields in a popup (which could be up to a dozen or more) whereas if you just let it automatically create the fields by using the "A List of Field Attributes" it generates the HTML automatically. To have to re-create the HTML over and over takes time. add custom popup html in ADDITION to existing fields Hence this idea.

And, if you add a field in the attribute table (e.g in SDE), you have to remember to go back in and add it as manual HTML coding, if you have the custom HTML popup.  It would be nice to have a hybrid popup part automatic and part custom HTML, you see? In the interim.. what Esri could do is at least let us Copy and Paste out the HTML the popup auto-generates of HTML. So at least we could just say "A List of Field Attributes" and then Copy and Paste out the HTML vs doing it by hand. So at first, copy and paste, then in the longterm the hybrid approach, as feature enhancements.  Also if Arcade could generate HTML and manipulate the DOM that would open the door to data actually driving the visual look of a popup.  For example popups with "tree" in the point as an attribute would be green background or something. You can see how open ended that could be. That would be a distant future thing, I don't know how much I'd use that. But I'd definitely like to cut down on the time of doing popups. Especially since web maps still corrupt any time you change an mxd by adding a layer.  For now, I have my popup HTMLs in a Word document. You can see how this process could be more sophisticated!  

SueJohnston
New Contributor III

Hi Annina,

I'm trying to do this very thing, provide a link where the value is not null.

It works, except when the link opens it adds %5C where my slashes \ are (tested in both IE and Chrome).

If I add my link as an image, it works no problem, but then i can't filter out the null values.

Am i missing something?

Any insight would be appreciated!  or maybe Kelly Gerrow knows?
Thanks!
Sue

XanderBakker
Esri Esteemed Contributor

A URL normally used the forwards slash "/" instead of the backwards slash "\". How do you construct the URL?

SueJohnston
New Contributor III

Our hyperlink field uses the backslash.  So my url is my website.com/{hyperlink}

And my hyperlink is \project\drawing.tif

SueJohnston
New Contributor III

I changed  the backward slash to a forward slash and I'm still getting the same result, where %5C replaces the slash.

XanderBakker
Esri Esteemed Contributor

If I look at this using an Arcade expression, I can replace the backward slash (note that in this example I had to write the backslash character twice since it is an escape character and after replacing the backslash(es) for the forward slash and concatenate the url with the hyperlink link this:  

It will return a valid hyperlink:

SueJohnston
New Contributor III

Sorry, I'm not sure how to apply this using a hyperlink field, where all hyperlink paths are stored?

XanderBakker
Esri Esteemed Contributor

In my example I am setting two variable "url" and "hyperlink" using harcoded values, but if your fields are called "url" and "hyperlink" your first two lines would look like this:

var url = $feature.url;
var hyperlink = $feature.hyperlink;

or

var url = $feature["url"];
var hyperlink = $feature["hyperlink"];

This will read out the values stored in the attributes.

SueJohnston
New Contributor III

how does the replace work in this scenario?

I can get the the file path to show up now, using the 2 vars and the return result, but the link doesn't go to that directory.

XanderBakker
Esri Esteemed Contributor

Can you show the code you are using and the result you obtain at this moment? 

SueJohnston
New Contributor III

Xander Bakker‌ 

I got it to work.  I had my link set wrong, I hadn't added the expression to link itself.

now i'm going to try to incorporate IIF(isEmpty($feature.HYPERLINK),"","Link to Drawing")

thanks so much for your help (and patience  )!!! 

HlynurIngólfsson
New Contributor III

Hey there y'all and thanks for a good thread.

I have a pop-up with a bunch of hyperlinks and have gotten so far that they are hidden if they are empty (with the hyperlinking working fine), they however leave a blank lines in between where they are missing.. My pop-up code is something like this:
<br /><a href="{RAMMEBETINGELSER}" target="_blank">{expression/expr6}</a>
<br /><a href="{PHOTO_ALBUM}" target="_blank">{expression/expr7}</a>
<br /><a href="{VANN_NETT}" target="_blank">{expression/expr8}</a>
<br /><a href="{OTHER_DOCUMENT}" target="_blank">{expression/expr9}</a>

Where each arcade-expression (and there is one specific one for each hyperlink) is:

if (IsEmpty($feature.SAP)){
return ""
} else {
return "SAP"
}

if (IsEmpty($feature.SAP)){
return ""
} else {
return $feature.SAP
}

Anyone can be of help how i might solve this, to get rid of these blank spaces`in my pop-ups where there are empty hyperlinks? 

XanderBakker
Esri Esteemed Contributor

There is a way to do this and that is using the style="display:none" as attribute of both the line break and the anchor. Have a look at this simple example in html:

<br style="display:{expression/expr0}" /><a href="http://www.esri.com" target="_blank" style="display:{expression/expr0}">Website Esri Inc</a>  {expression/expr0}
<br style="display:{expression/expr1}" /><a href="http://www.esri.co" target="_blank" style="display:{expression/expr1}">Website Esri Colombia</a>  {expression/expr1}
<br style="display:{expression/expr2}" /><a href="http://www.esri.nl" target="_blank" style="display:{expression/expr2}">Website Esri NL</a>  {expression/expr2}

In this case I will use two different settings for the style attribute:

  • "display:none" will hide the element
  • "display:inline" will show the element

Each line has an expression that is used twice (OK an additional time at the end of the line to show the effect). The content of the expression could be something like this:

if (IsEmpty($feature.YourAttribute)){
    return "none";
} else {
    return "inline";
}

In case your attribute is empty it will return none and avoid the element to show. You should do this not only to your hyperlink (anchor a), but also to your break to avoid ending up with an empty blank line. 

To show you the effect, see the example below. The first popup contains a value for all three fields (hence the value "inline" at the end of the lines):

This example only has a single value (1 out of three), which is why there is two times the text "none":

As you can see there is no empty line being produced here.

deleted-user-pZlUMHhkW23Q
New Contributor III

I find Arcade scripting to be kind of broken at the moment in it's current form with ArcGIS online for popups. Only plain text can be returned by an Arcade script and even working within those limitations it does not work as one would expect. 

What I was trying to do was have one arcade script that dynamically builds out all the HTML markup (using only the approved HTML tags supported by ESRI ), Inline CSS styles (Regular CSS is not supported, another limitation imposed by the popup window) and build the logic within the Arcade script for handling empty fields, or hiding fields with certain fields etc.

I got this all working, but since the output of an Arcade script is only interpret as plain text, even if it has HTML markup in it, it won't render as HTML.

To add further insult to injury if I want just a plain text but dynamically create popup, newlines are not recognized so you'll just get a wall of text.

This means if you want to get a custom popup with CSS and Arcade logic in there you'd:

- Build out of all the HTML markup for each field and paste into the custom popup window under the view HTML source button.

- Use a CSS inliner tool to get the CSS in there

- Write out  each of the Arcade expressions individually, per field then write in your expressions into each spot needed in the HTML markup

- and repeat for every feature

This obviously is way to much overhead to do something so simple in ArcGIS online.

If Arcade expressions with HTML markup in them were rendered as HTML, or at minimum, if plain text return from Arcade would preserve newlines, we could do cool things with popups. But its currently so hamstrung by all the limitations placed on it to the point where it's only really useful on a per field basis.

AndresCastillo
MVP Regular Contributor

Kelly Gerrow

Xander Bakker

Kevin MacLeod

Or anyone else:
How to disable/hide a url on a webpage if nothing is found on the host web server?
We need a way to hide a pop up hyperlink if no file is found in the IIS directory to be served out by the web server.
Here is the context to my question:
We have a user defined unique identifier string field.
Every record has an ID.
In a web server, we are storing and serving out videos/pdfs with the ID as the file name.
For example,
In the popup for a feature, the ID field value is ID123.
Configuring a custom attribute display, I create a link, and set the url to:
http://domain/GIS_CCTV/{ID}.mp4
Set the link text to:
Click Here for Video
I do a similar configuration for the pdf files.
In the web server, we do not have .mp4s and pdf's for every one of our ID's,
such as ID123.mp4 and/or ID123.pdf
So, when the user clicks the 'Click Here for Video/PDF' link, they are taken to a 404 error page because the file is not available in the web server.
I started trying to do this with Arcade attribute expressions, because Arcade can show or hide an attribute field, based on whether or not there is an attribute value in the specific feature record.
My ID's will always have attribute values, so Arcade would always show the ID field.
My intent is not to hide the ID field anyways.
The issue with using Arcade for my scenario is that I do not have a Hyperlink field in my schema for Arcade to hide.
Furthermore, can Arcade/any other method hide the URL if there is no file available in the web server?
Lake_Worth_BeachAdmin
Occasional Contributor III

Andres,

Arcade will not be able to query your remote web server to determine if the response is 404 or not. 

Javascript could do this but you will not be able to get this working with an ESRI hosted web app.

A workaround could be to create a new field "has_files" with yes or no values (not sure what the environment looks like but field calculator should be able to do this pretty quickly) 

Then create arcade expression to read the new field:

IIF($has_files == 'yes', Click Here: www.linktowebserver/{id}.mp4, 'This feature does not have any files')

You can also combine this with some HTML tags for a cleaner display.

Combining Arcade and HTML for a Real-life Pop-up Display 

AndresCastillo
MVP Regular Contributor

Thank you Joe,

The issue I have with adding the new field to indicate whether or not the feature has files is that the directory is consistently changing.

People outside of our GIS group may upload new files into the directory on a daily basis.

This means that the values in my field would be outdated.

For example, ID234 might not have a file corresponding to it today, but might have a ID234.pdf in the web server tomorrow.

I don't mind using WAB Developer Edition to make my goal possible.

I would just like some help with it.

JacqueHamilton
New Contributor III

I have something simple (I think) but I still can't get this to work.  All I want to do is display a "No Data" if the feature field is blank. In this case my "field_base". I would like my "Field Base Test (attribute expressions) to say 'No Data". This is what I'm working with: 

IIF(IsEmpty($feature["field_base"]), "no data",$feature["field_base"])

Still...the 'no data" is not displaying in the Field Base Test when 'field_base' is empty.

I'm just starting to explore Arcade.  Any help would be great!

XanderBakker
Esri Esteemed Contributor

Is the field really Empty (Null) or is it an empty string?

JacqueHamilton
New Contributor III

It is an empty string. (Null) is not present.

XanderBakker
Esri Esteemed Contributor

In that case you will probably have to use something like this:

IIF($feature["field_base"] == "", "no data", $feature["field_base"])

IsEmpty is to test for Null values

JacqueHamilton
New Contributor III

I don't get any errors but the "no data" still does not show up.  Thank you so much for helping. The dataset is public so you can view it here https://umn.maps.arcgis.com/home/webmap/viewer.html?webmap=8070f19643f849629264021625c64146 

XanderBakker
Esri Esteemed Contributor

I noticed that there were elements that had a single space.

You could use this to get the no data:

IIF(Trim($feature["field_base"]) == "","no data",$feature["field_base"])

JacqueHamilton
New Contributor III

Perfect!  IT WORKS!!  Thank you so much!

About the Author
I love interactive maps and apps on the internet! The maps and apps that customers create and share on the web, make my job awesome. I'm a Product Manager with the ArcGIS Online team in Redlands, California. I am a proud graduate from Carleton University and the COGS in Canada, with research focus' in Health Geography. Originally from Bedford, NS, Canada but have spent a lot of time in Haliburton and Ottawa, Ontario. I have a passion for the outdoors and dogs.