Select to view content in your preferred language

Removing empty fields from popup in Portal Map Viewer using Arcade Expression

804
7
02-13-2024 01:56 AM
CJCowardin
Emerging Contributor

Trying to configure a pop-up to remove all of the fields with no data since the list is very long.  I tried using IsEmpty but they are still there.  Any help is appreciated. 

This is a sample popup

CJCowardin_0-1707818197175.png

 

0 Kudos
7 Replies
ZachBodenner
MVP Regular Contributor

I have a solution that I've repurposed quite a few times. Here's an Arcade expression where the return is an HTML table that will include only attributes that have a value present. You'll have to switch out the attributes to match your own. 

 

// Use Arcade > Text template
// create one expression for all fields
// return as table showing only populated fields
// If field is null, do not add row to table
// if field has a value, add row to table
 
// Create variables for checked-for-field and what their labels should be. 
// Select the fields to look for
var fieldsArray = ['Condition','Install_Date','Location','Intersection_Type','Facility_Type','Ramp_Config','Managed_By','Comments'];
// Set the field aliases in the same order as the fields above
var labelsArray = ['Condition','Install Date','Location','Intersection Type','Facility Type','Ramp Configuration','Managed By','Comments'];
var arrayLength = Count( fieldsArray );

// Table Header
// Identify condition and set background color accordingly
var cond = $feature.Condition
var backgroundColor = When(cond=="1 (Non-existant)","#fc461d",cond=="2 (Poor)","#df750c",cond=="3 (Functional)","#f2cc0d",cond=="4 (ADA Compliant)","#37aac4","#cccccc") 
// Set table header
var returnString = `<h3 style="background-color:${backgroundColor};padding-left:2%">Ramp Info</h3><table style="width:100%;background-color:#f4f4f4;">`;

// Make sure the final table is searching for correct attributes
Expects( $feature, 'Condition','Install_Date','Location','Intersection_Type','Facility_Type','Ramp_Config','Managed_By','Comments')

/*loops through a number of times eual to the length of the array (that's the i<arrayLength part), incrementing by one each time (i++). If the attribute if the field array is not empty 
(!IsEmpty), then the value of the the variable returnString is equal the value in the fieldsArray equal to the index value of the array (fieldsArray[i]) plus the additional portion of the
return string enclosed in the curly brackets. If it is empty, then the value of returnString   
*/

for (var i = 0; i < arrayLength; i++ ) {
  if ( !IsEmpty( $feature[ fieldsArray[i] ] ) ){
    //returnString = returnString + "<tr><td>" + labelsArray[i] + "</td><td>" + $feature[ fieldsArray[i] ] + "</td></tr>";
    returnString = `${returnString}<tr><td style="border-bottom: 1px solid #cccccc;border-right: 1px solid #cccccc;width:50%;padding-left:2%"><b>${labelsArray[i]}</b></td><td style="border-bottom: 1px solid #cccccc;width:50%;padding-left:2%">${$feature[ fieldsArray[i] ]}</td></tr>`;
  }}
 
returnString = returnString + "</table>";

return { 
   type : 'text', 
   text : returnString 
}

 

Here's what the result looks like (note that I also used one of the attributes, Condition, to determine the background color of the header:

 

ZachBodenner_0-1707833902624.png

 

LAGIBOO
New Contributor

This was exactly what I have been looking for!  Couple questions I wonder if you can help me with?

 

1. In the header, instead of specifying the text like you have as "Ramp Info" can I have it pull an attribute field or two?  I would like to use $feature.Project_Title - $feature.Project_Status so it looks something like Generation - In Progress.

2. I noticed it is displaying a Date field as 2024-02-01T00:00:00-06:00 even though I have the field date format set to MM/DD/YYYY... is there any way I can get this to display just date and in the MM/DD/YYYY format (so 02/01/2024 in this case)?

 

Thank you!!

0 Kudos
ZachBodenner
MVP Regular Contributor

Yes to both! So my header variable is here:

`<h3 style="background-color:${backgroundColor};padding-left:2%">Ramp Info</h3><table style="width:100%;background-color:#f4f4f4;">`;

 

Just change the Ramp Info text to something that fits your needs

`<h3 style="background-color:${backgroundColor};padding-left:2%">${$feature.Project_Title} - ${$feature.Project_Status}</h3><table style="width:100%;background-color:#f4f4f4;">`;

 

As to dates, the display can be easily changed as well, but they would need to be pulled out of the loop return.

 

var date = Text($feature.datefield,'DD MMM, YYYY') //or whatever format
var dateReturn = `<tr><td style="border-bottom: 1px solid #cccccc;border-right: 1px solid #cccccc;width:50%;padding-left:2%"><b>Date: </b></td><td style="border-bottom: 1px solid #cccccc;width:50%;padding-left:2%">${date}</td></tr>`

for (var i = 0; i < arrayLength; i++ ) {
  if ( !IsEmpty( $feature[ fieldsArray[i] ] ) ){
    //returnString = returnString + "<tr><td>" + labelsArray[i] + "</td><td>" + $feature[ fieldsArray[i] ] + "</td></tr>";
    returnString = `${returnString}<tr><td style="border-bottom: 1px solid #cccccc;border-right: 1px solid #cccccc;width:50%;padding-left:2%"><b>${labelsArray[i]}</b></td><td style="border-bottom: 1px solid #cccccc;width:50%;padding-left:2%">${$feature[ fieldsArray[i] ]}</td></tr>`;
  }}

returnString = returnString + dateReturn + "</table>";

 

So what I did there was create a text variable for the date, plug it into a table row with two columns (same as the loop return table, and in the same style) and then place it after the loop, but before closing the table.

0 Kudos
CJCowardin
Emerging Contributor

I just need to create a new Arcade expression under my pop-up properties box, add the above and change to my fields?

0 Kudos
ZachBodenner
MVP Regular Contributor

That's right! You can think of the two variable fieldsArray and labelsArray as matched pairs. The fieldsArray values need to be the actual database field names, then you can alias them (like you would do from the field menu in map Viewer), just making sure that the label is in the same order as the field name.

 

Of course, you'll also have to adjust the HTML. This part of the code:

var returnString = `<h3 style="background-color:${backgroundColor};padding-left:2%">Ramp Info</h3><table style="width:100%;background-color:#f4f4f4;">`;

wont work for you because it's relying in my backgroundColor variable, which is based in the field "Condition." 

You cane remove this portion: 

var cond = $feature.Condition
var backgroundColor = When(cond=="1 (Non-existant)","#fc461d",cond=="2 (Poor)","#df750c",cond=="3 (Functional)","#f2cc0d",cond=="4 (ADA Compliant)","#37aac4","#cccccc") 

and then just remove everything after "h3" in that tag.

0 Kudos
CJCowardin
Emerging Contributor

I added this and just used 2 fields to test.  I don't see anything different in my popup.  It's still showing Afghan which is empty and that's what I don't want to show.

// Use Arcade > Text template
// create one expression for all fields
// return as table showing only populated fields
// If field is null, do not add row to table
// if field has a value, add row to table
 
// Create variables for checked-for-field and what their labels should be.
// Select the fields to look for
var fieldsArray = ['Afghan','Akan'];
// Set the field aliases in the same order as the fields above
var labelsArray = ['Afghan','Akan'];
var arrayLength = Count( fieldsArray );

// Table Header
// Identify condition and set background color accordingly

// Set table header
var returnString = `<h3>`;

// Make sure the final table is searching for correct attributes
Expects( $feature, 'Afghan','Akan')

/*loops through a number of times eual to the length of the array (that's the i<arrayLength part), incrementing by one each time (i++). If the attribute if the field array is not empty
(!IsEmpty), then the value of the the variable returnString is equal the value in the fieldsArray equal to the index value of the array (fieldsArray[i]) plus the additional portion of the
return string enclosed in the curly brackets. If it is empty, then the value of returnString  
*/

for (var i = 0; i < arrayLength; i++ ) {
  if ( !IsEmpty( $feature[ fieldsArray[i] ] ) ){
    //returnString = returnString + "<tr><td>" + labelsArray[i] + "</td><td>" + $feature[ fieldsArray[i] ] + "</td></tr>";
    returnString = `${returnString}<tr><td style="border-bottom: 1px solid #cccccc;border-right: 1px solid #cccccc;width:50%;padding-left:2%"><b>${labelsArray[i]}</b></td><td style="border-bottom: 1px solid #cccccc;width:50%;padding-left:2%">${$feature[ fieldsArray[i] ]}</td></tr>`;
  }}
 
returnString = returnString + "</table>";

return {
   type : 'text',
   text : returnString
0 Kudos
ZachBodenner
MVP Regular Contributor

I see a couple things which could be tripping you up. Your text string starts with an <h3> tag, but doesn't have a closing tag. Try adding text followed by a close tag just to see what happens:

var returnString = `<h3>This is my popup title</h3>

Next, are you using the Arcade popup element (as opposed to text popup element or an arcade expression)? This format of Arcade will only work using the Arcade popup element.

 

0 Kudos