Ce document vous expliquera comment masquer un champ dans une fenêtre contextuelle en utilisant Arcade. Vous pouvez utiliser cela pour masquer un champ qui contient une valeur particulière, ou si le champ est vide/NULL.<\/P>
1. Créez une expression d'attribut pour le champ que vous souhaitez masquer en cliquant sur le bouton à 3 points à côté de la couche dans la carte Web > Configurer la fenêtre contextuelle<\/STRONG><\/P><\/span><\/P>2. Faites défiler vers le bas jusqu'à Expressions d'attribut<\/STRONG> et cliquez sur Ajouter<\/STRONG>:<\/P><\/span><\/P> <\/P>3. Spécifiez une instruction IIF<\/A> pour le champ que vous souhaitez masquer. Pour la trueValue<\/STRONG>, spécifiez None<\/STRONG>. Pour la falseValue<\/STRONG>, spécifiez inline<\/STRONG>. Voici un exemple:<\/P>IIF($feature["Meter_Meter_Flow"] == -999 || IsEmpty($feature["Meter_Meter_Flow"]), "None", "inline")<\/code><\/pre>L'expression Arcade ci-dessus masquera le champ Meter_Meter_Flow<\/STRONG> si la valeur est -999,<\/STRONG> ou si la valeur est vide.<\/P>4. Sous Contenu de la fenêtre contextuelle<\/STRONG>, changez l'Affichage<\/STRONG> en Affichage d'attribut personnalisé<\/STRONG><\/P><\/span><\/P> <\/P>5. Cliquez sur CONFIGURER<\/STRONG><\/P>6. Dans la boîte de dialogue Affichage d'attribut personnalisé, ajoutez tous les champs que vous souhaitez afficher dans la fenêtre contextuelle<\/P><\/span><\/P>7. Pour masquer un champ, vous devrez passer en mode Afficher la source HTML. <\/STRONG>Cela vous permettra d'entrer du code HTML.<\/P><\/span><\/P>8. Spécifiez le HTML suivant pour masquer le champ:<\/P><span style=\"display:{expression\/_expr0}\"><b>Débit du compteur :<\b> {Meter_Meter_Flow}<br \/><\span><\/code><\/pre>L'expression\/_expr0 <\/
IIF($feature["Meter_Meter_Flow"] == -999 || IsEmpty($feature["Meter_Meter_Flow"]), "None", "inline")<\/code><\/pre>L'expression Arcade ci-dessus masquera le champ Meter_Meter_Flow<\/STRONG> si la valeur est -999,<\/STRONG> ou si la valeur est vide.<\/P>4. Sous Contenu de la fenêtre contextuelle<\/STRONG>, changez l'Affichage<\/STRONG> en Affichage d'attribut personnalisé<\/STRONG><\/P><\/span><\/P> <\/P>5. Cliquez sur CONFIGURER<\/STRONG><\/P>6. Dans la boîte de dialogue Affichage d'attribut personnalisé, ajoutez tous les champs que vous souhaitez afficher dans la fenêtre contextuelle<\/P><\/span><\/P>7. Pour masquer un champ, vous devrez passer en mode Afficher la source HTML. <\/STRONG>Cela vous permettra d'entrer du code HTML.<\/P><\/span><\/P>8. Spécifiez le HTML suivant pour masquer le champ:<\/P><span style=\"display:{expression\/_expr0}\"><b>Débit du compteur :<\b> {Meter_Meter_Flow}<br \/><\span><\/code><\/pre>L'expression\/_expr0 <\/
<span style=\"display:{expression\/_expr0}\"><b>Débit du compteur :<\b> {Meter_Meter_Flow}<br \/><\span><\/code><\/pre>L'expression\/_expr0 <\/
Thank you for your time. It's greatly appreciated! I'll test this out.
I can confirm, the script published by Xander (I can't tag you for some reason) still works with AGOL Map Viewer in 2025. I got Copilot to modify it so you can pick the fields you want to include rather than exclude, and display them by order. If you're reading this Xander, thank you! This is one of very few examples online.
Function HasDomain(f, fldname) { return Domain(f, fldname) != Null; } Function GetAlias(f, fldname) { var esquema = Schema(f); var flds = esquema["fields"]; for (var i in flds) { var fldinfo = flds[i]; if (fldinfo["name"] == fldname) { return fldinfo["alias"]; } } return fldname; } Function GetFieldNames(f, keepflds) { var fldlst = []; var esquema = Schema(f); var flds = esquema["fields"]; for (var i in flds) { var fldinfo = flds[i]; if (Includes(keepflds, fldinfo["name"])) { Push(fldlst, fldinfo["name"]); } } Console(fldlst); return fldlst; } var fs = FeatureSetByName($map, "YourFeatureSetName"); var oid = $feature.objectid; var sql = "OBJECTID = @oid"; var f = First(Filter(fs, sql)); var keepflds = ['Field1', 'Field2', 'Field3']; // Specify the fields in the desired order var flds = GetFieldNames(f, keepflds); var info = []; var atts = {}; for (var i in keepflds) { var fldname = keepflds[i]; if (!IsEmpty(f[fldname])) { var alias = GetAlias(f, fldname); Push(info, {'fieldName': alias}); if (HasDomain(f, fldname)) { atts[alias] = DomainName(f, fldname); } else { atts[alias] = f[fldname]; } } } return { type: 'fields', fieldInfos: info, attributes: atts }
I'm testing this solution in Portal v11.1 and AGOL. I've followed JakeSkinner's instructions on how to hide a field in a pop up. For Step 3, here's my expression {expression/expr0} hiding the Contact field if it is blank:
IIF(IsEmpty($feature.contact), "None", "inline")
For Steps 7 and 8, the HTML code in the Custom Attribute Display looks like this
<b>Site:</b> {site}<br /><b>Address:</b> {address}<br /><span style="display:{expression/expr0}"><b>Contact:</b> {contact}<br /></span>
Nothing works. Other resources that I followed with similar workflows that do not work either
Conditional Field Display with #Arcade in #Pop #Ups | #ArcGISOnline | #GIS - YouTube
Conditional Field display with Arcade in Pop Ups - Page 2 - Esri Community
I'm not sure if this is a JS3 vs JS4 issue? Any assistance in solving this issue is greatly appreciated!
hi @XanderBakker
The Arcade Element works for the main layer. But if i have a related table?
I have a related table with the same issue, in the related table i want to show only fields with data and hide empty or null... (the related table have 150 fields)
Atentamente,
I saw this return in arcade expression
return { type: 'fields', title: 'Detalles de la actividad', description : '(con Arcade)', fieldInfos: info, attributes : atts }
If that Arcade expression is {expression/expr0}, I was wondering, how do you grab either fieldInfos OR attributes value in the html code? for example
<p> my Field Info: {expression/expr0} </p> <p> my Attribute: {expression/expr0} </p>
This will result as [object Object]
Please advice. Thank you.
@JustinConnerWR I would imagine if you replaced the -999 with zero in the this:
IIF($feature["Meter_Meter_Flow"] == -999 || IsEmpty($feature["Meter_Meter_Flow"]), "None", "inline")
so it would look like this:
IIF($feature["Meter_Meter_Flow"] == 0 || IsEmpty($feature["Meter_Meter_Flow"]), "None", "inline")
Haven't tested it, but would give it a try and see if that works.
@XanderBakker
Using the expression above. How would you go about applying logic to also hide fields with a 0 (zero) value?
This is very helpful. Thank you @Vanilla2020 . I'm getting the error when trying to access your featureset or mine:
Execution Error: Failed to open Layer: Feature layer must be created with either a url or a source
Any thoughts on why this is happening?
@NatalieRobbins Are you using Portal or AGO?
I noticed that when in Portal, the "source" html button is missing, but if you are in AGO it is there as @JakeSkinner has shown in their post.
Curios to hear from Esri if there is some other way to handle HTML in pop-ups or if this was simply not added yet to the pop-up configuration in Portal.
There is discussion of this here
-Vanesa
@NatalieRobbins in the new Map Viewer, select Add Content in the Pop-up pane, and then select Text:
You can then format your text with supported HTML using the Source icon:
Is there a way to configure this type of schema in the new Map Viewer? I don't see an option for custom HTML pop-ups in there but the arcade abilities seem more robust. Is this functionality now baked in?
@AdrianaCalderon you then have to go into the pop-up's html and configure the html so it knows what to show/not to show in the pop-up. I think one of the link
I think this might have the info https://community.esri.com/t5/arcgis-online-blog/conditional-field-display-with-arcade-in-pop-ups/ba-p/891549#comment-66670
or this thread https://community.esri.com/t5/arcgis-online-questions/can-i-eliminate-empty-values-using-arcade-in-my/td-p/351344
Hello, I have tried using the expression:
IIF(isEmpty($feature.Organizati, "None", "inline"), as an attribute expression in my popup configuration but it is not working.
I am using Map Viewer and I want to hide those fields that have no data when the popup is displayed.
Do I need to add an attribute expression? or an Arcade expression as content? What is the difference between these?
Thank you
Thank you very much for all your reply. I will try this out!
Hi @Vanilla2020 ,
Have a look at the "GetFieldNamesOnPrivacy" function below:
Function HasDomain(f, fldname) { return Domain(f, fldname) != Null; } Function GetAlias(f, fldname) { var esquema = Schema(f); var flds = esquema["fields"]; for (var i in flds) { var fldinfo = flds[i]; if (fldinfo["name"]==fldname) { return fldinfo["alias"]; } } return fldname; } Function GetFieldNamesOnPrivacy(f) { // privacy_level with values from 0 to 5) // I want to display, say field_A, field_B, field_C, field_D // for locations with privacy level larger than 2, // while only field_A and field_B var fldlst = []; var level = f["privacy_level"]; if (level > 2) { fldlst = ["field_A", "field_B"]; } else { fldlst = ["field_A", "field_B", "field_C", "field_D"]; } return fldlst; } var fs = FeatureSetByName($datastore, "_8_de_formulario"); var oid = $feature.objectid; var sql = "OBJECTID = @oid"; var f = First(Filter(fs, sql)); // var excludeflds = ['globalid', 'objectid', 'prueba', "x_coord","y_coord","EditDate","Editor"]; var flds = GetFieldNamesOnPrivacy(f); var info = []; var atts = {}; for (var i in flds) { var fldname = flds[i]; if (!IsEmpty(f[fldname])) { var alias = GetAlias(f, fldname); Push (info, {'fieldName': alias}) if (HasDomain(f, fldname)) { atts[alias] = DomainName(f, fldname); } else { atts[alias] = f[fldname]; } } } return { type: 'fields', title: 'Detalles de la actividad', description : '(con Arcade)', fieldInfos: info, attributes : atts }
@Vanilla2020
you could use something like this article talks about. I realize this article is for relative time, but you can use the idea to create your if then statement.
https://community.esri.com/t5/commercial-blog/arcade-calculating-relative-time-for-popups-and/ba-p/884360
Hi @XanderBakker I have a question related to this topic: How could I display a list of different fields in the pop-up based on the values in a certain field? For example, I would like to configure a pop-up for hundreds of business locations. Due to data sharing agreement with the business owners, some of the fields can be shown on the pop-up for some business, but cannot for others. I have a field (e.g., privacy_level with values from 0 to 5) to indicate that. So I want to display, say field_A, field_B, field_C, field_D for locations with privacy level larger than 2, while only field_A and field_B for locations with privacy level smaller than or equal to 2. How could I use Arcade to accomplish that?
Thank you!
Hi @VanessaSimps ,
The comment above your comment explains just how to do that using the new Map Viewer and Arcade elements.
Let me know if you have any questions on how to do this.
This is super useful, however, is there a way to have the line break not show up if your 'hidden' value isn't at the bottom of the popup list?
This is what it looks like if I have values for all the fields
Here is when I don't have a Valve ALTID value:
I am not loving the big gap that is created here. I could move the values to the bottom of my list, but the end user wanted the list in this order.
Thanks!
Vanessa
Hi @erica_poisson ,
Yes, you can when you use the new Map Viewer. In this case, you will not add an expression (virtual field) to the pop-up, but you will add an Arcade Element and configure something like:
Function HasDomain(f, fldname) { return Domain(f, fldname) != Null; } Function GetAlias(f, fldname) { var esquema = Schema(f); var flds = esquema["fields"]; for (var i in flds) { var fldinfo = flds[i]; if (fldinfo["name"]==fldname) { return fldinfo["alias"]; } } return fldname; } Function GetFieldNames(f, excludeflds) { var fldlst = []; var esquema = Schema(f); var flds = esquema["fields"]; for (var i in flds) { var fldinfo = flds[i]; // Console(fldinfo["name"]); // Console(Includes(excludeflds, fldinfo["name"])); if (!Includes(excludeflds, fldinfo["name"])) { Push(fldlst, fldinfo["name"]); } } Console(fldlst) return fldlst; } var fs = FeatureSetByName($datastore, "_8_de_formulario"); var oid = $feature.objectid; var sql = "OBJECTID = @oid"; var f = First(Filter(fs, sql)); var excludeflds = ['globalid', 'objectid', 'prueba', "x_coord","y_coord","EditDate","Editor"]; var flds = GetFieldNames(f, excludeflds); var info = []; var atts = {}; for (var i in flds) { var fldname = flds[i]; if (!IsEmpty(f[fldname])) { var alias = GetAlias(f, fldname); Push (info, {'fieldName': alias}) if (HasDomain(f, fldname)) { atts[alias] = DomainName(f, fldname); } else { atts[alias] = f[fldname]; } } } return { type: 'fields', title: 'Detalles de la actividad', description : '(con Arcade)', fieldInfos: info, attributes : atts }
In this case, I have a feature service that stores the results of a Survey with a lot of conditional questions. In order to avoid the empty (non-relevant) fields being showed in the pop-up, you can use this to only show those that have information.
On line 33 you define the layer that you want to connect to and on line 37 I define a list of fields that I don't want to show.
Hi @JakeSkinner -
This is great. Is there any way to do this en-masse for many fields within one expression? Right now I am getting ready to write this expression & HTML code ~90 times for all of the fields I need to deal with.
Les membres connectés peuvent publier, suivre les mises à jour, et plus encore. Nouveau ici ? Inscrivez-vous gratuitement.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.