Hi everyone,
I am currently working on a project using Forms in Field Maps/Map Viewer and am a little stuck. In the Form, I have added Arcade expressions in it where if the user selects a certain Defect Type only certain fields will show up for editing. However after they submit the form, the pop-up shows every other field in the layer. Is it possible to write an arcade expression (in Map Viewer pop-up) that reads the Defect Type(11 in total) field and depending on the answer, only shows certain fields (field does not have to be filled in but if it was applicable to the defect in the form I want it to show up)? For example, If Defect Type equals Unevenness, only show the fields Area(sqft), Height/Depth(in) & Sunken or Raised in the pop-up? If Defect Type = Missing Section, only show the fields Area(sqft) & Height /Depth(in) in the pop-up.
Thanks in advance!
Here's one way to do it. This uses an Arcade element to return a truncated field list. It first gets the list of fields and loops through them. As it loops through the fields, the if statements sends a different set of fields for each Defect Type to the fieldTest function, which will populate the field list with the field names and their values. Note that if the Defect Type field uses a Domain, you'll have to use the DomainName function to use the descriptive name.
var fields = Schema($feature).fields;
var attributes = {};
var fieldInfos = [];
function fieldTest(fieldList, fieldName) {
if (Includes(fieldList, fieldName)) {
attributes[fieldName] = $feature[fieldName];
Push(fieldInfos, { fieldName: fieldName });
}
}
var code = $feature["Defect Type"]; // or DomainName($feature, "Defect Type)
for (var i in fields) {
if (code == "Unevenness") fieldTest(["Area", "Height", "Sunken"], fields[i].name);
else if (code == "Missing") fieldTest(["Area", "Height"], fields[i].name);
//else if for each of other defect conditions
}
return {
type: "fields",
fieldInfos: fieldInfos,
attributes: attributes
};
That works great! Thank you so much! I really appreciate this I am newer to Arcade.
If I wanted to clean it up - have a custom order (for the fields), and also have the field names show up as their edited alias names how would I make that modification?
var fields = Schema($feature).fields;
var attributes = {};
var fieldInfos = [];
function fieldTest(fieldList, fieldName) {
if (Includes(fieldList, fieldName)) {
attributes[fieldName] = $feature[fieldName];
Push(fieldInfos, { fieldName: fieldName });
}
}
var code = DomainName($feature,"DefectType");
for (var i in fields) {
if (code == 3) fieldTest(["SystemID","DefectType","Comment","CriticalArea","Area_sqft", "Height / Depth (in)", "D03_Unevenness","SynTurfSystemID","SynTurfInsSystemID","CreationDate","Creator","EditDate","Editor"], fields[i].name);
else if (code == 4) fieldTest(["SystemID","DefectType","Comment","CriticalArea","Height_Depth_in","Width_in","Length_ft","SynTurfSystemID","SynTurfInsSystemID","CreationDate","Creator","EditDate","Editor"], fields[i].name);
else if (code == 5) fieldTest(["SystemID","DefectType","Comment","CriticalArea","Area_sqft", "Height / Depth (in)","Length_in","SynTurfSystemID","SynTurfInsSystemID","CreationDate","Creator","EditDate","Editor"], fields[i].name);
else if (code == 6) fieldTest(["SystemID","DefectType","Comment","CriticalArea","Area_sqft", "Height / Depth (in)","SynTurfSystemID","SynTurfInsSystemID","CreationDate","Creator","EditDate","Editor"], fields[i].name);
else if (code == 7) fieldTest(["SystemID","DefectType","Comment","CriticalArea","Area_sqft", "Length_ft","SynTurfSystemID","SynTurfInsSystemID","CreationDate","Creator","EditDate","Editor"], fields[i].name);
else if (code == 😎 fieldTest(["SystemID","DefectType","Comment","CriticalArea","Area_sqft", "D08_BurnMark","SynTurfSystemID","SynTurfInsSystemID","CreationDate","Creator","EditDate","Editor"], fields[i].name);
else if (code == 9) fieldTest(["SystemID","DefectType","Comment","CriticalArea","Area_sqft", "Height / Depth (in)","Length_ft","SynTurfSystemID","SynTurfInsSystemID","CreationDate","Creator","EditDate","Editor"], fields[i].name);
else if (code == 10) fieldTest(["SystemID","DefectType","Comment","CriticalArea","D10_11_PoolingWeeds","SynTurfSystemID","SynTurfInsSystemID","CreationDate","Creator","EditDate","Editor"], fields[i].name);
else if (code == 11) fieldTest(["SystemID","DefectType","Comment","CriticalArea","D10_11_PoolingWeeds","SynTurfSystemID","SynTurfInsSystemID","CreationDate","Creator","EditDate","Editor"], fields[i].name);
else if (code == 12) fieldTest(["SystemID","DefectType","Comment","CriticalArea","Area_sqft", "D12_Vand_Deface","SynTurfSystemID","SynTurfInsSystemID","CreationDate","Creator","EditDate","Editor"], fields[i].name);
else if (code == 12) fieldTest(["SystemID","DefectType","Comment","CriticalArea","SynTurfSystemID","SynTurfInsSystemID","CreationDate","Creator","EditDate","Editor"], fields[i].name);
//else if for each of other defect conditions
}
return {
type: "fields",
fieldInfos: fieldInfos,
attributes: attributes
};
Glad to help. Don't forget to click the Accept as Solution button on the post that answers your question.
If you want the fields in the order that they are in the original popup, then you have to get the schema for the FeatureSet using the FeatureSetByPortalItem function. This appears to be the only way to get them in their original order. If you want them in another custom order, that will take a little more coding. Replace line 1 with this
var fields = Schema(FeatureSetByPortalItem(Portal('your portal url'), 'your item number')).fields;
To get the alias, change the if statements to include the aliases and use "alias" instead of "name" at the end of the line
if (code == 3) fieldTest(["Defect ID", "Defect Type", "Comment", "Critical Area","Area (sqft)", "Height / Depth (in)"], fields[i].alias);
Okay I'll give that a shot! I just noticed though, while I am seeing the Arcade expression has no problem being executed on the Map Viewer, in Field Maps application it's not showing up at all and there's no error message. Does something need to be added to the code so that it shows up in both places?
That appears to be working properly when I view the map I'm testing this on in Field Maps. I did notice that your line 21 was missing the code and closing parenthesis. I don't know if that was the issue.
I realized that I didn't quite have the alias part right. You'll have to make this update to the fieldTest function. This also returns the fields with domains and the date fields formatted.
function fieldTest(fieldList, fieldName, fieldAlias, fieldType) {
if (Includes(fieldList, fieldAlias)) {
if (fieldType == 'esriFieldTypeDate') attributes[fieldalias] = Text($feature[fieldName], 'dddd, MMMM D, Y');
else attributes[fieldalias] = DomainName($feature, fieldName);
Push(fieldInfos, { fieldName: fieldAlias });
}
}
The if statements would look like this
if (code == 3) fieldTest(["Defect ID", "Defect Type", "Comment", "Critical Area","Area (sqft)", "Height / Depth (in)"], fields[i].name, fields[i].Alias, fields[i].type);
Note: during my testing, the app started crashing when opening the popup, so I have to figure out what is happening