The choices rendered in dynamic choice input values are generated via an Arcade expression and reflect what is returned.
How it works
The web map contains a Drill jobs feature layer and a standalone table containing Drill rigs. The form’s field element is configured with various inputs, with dynamic choice input as one of them. This input is configured with a choiceExpression. This is an Arcade expression that returns a dictionary with an array of choices objects. Each object has a name and code property.
The Depth, Diameter, or Rough terrain field values are used by an Arcade expression that filters a standalone table to include only rig names that meet the current job requirements. It returns those matches as the choices for the Assigned drilling rig name field.
Add the Map and Editor components. The map contains the editable layer and table.
<arcgis-map item-id="193f575f144b47faa3c2b287368c114d"> <arcgis-zoom slot="top-left"></arcgis-zoom> <arcgis-editor slot="top-right"></arcgis-editor> </arcgis-map>After the map is ready, find and load the Drill jobs feature layer and define any expressionInfos used by the form.
const drillLayer = viewElement.map.allLayers.find((layer) => layer.title === "Drill jobs");
// Wait for the layer to load before accessing it await drillLayer.load();
// Set the expressions for editing the layer's field and its dynamic choices const trueExpression = new ExpressionInfo({ expression: "true", name: "system/true", });
const dynamicChoiceExpression = new ExpressionInfo({ name: "dynamic-tree-choices", expression: getChoiceExpression(), });Configure the form with a form template. The assignedDrillingRigName field uses the dynamic-choice input type and references the expression by name.
const formTemplate = new FormTemplate({ elements: [ new FieldElement({ // Field element for the start date fieldName: "startDate", label: "Start date", input: { // Input configuration for the start date field type: "datetime-picker", includeTime: false, }, editableExpression: trueExpression.name, }), new FieldElement({ fieldName: "depth", label: "Depth (ft.)", input: { type: "text-box", }, }), new FieldElement({ fieldName: "diameter", label: "Diameter (in.)", input: { type: "text-box", }, }), new FieldElement({ fieldName: "offRoadRequired", label: "Rough terrain", input: { type: "combo-box", showNoValueOption: false, }, }), new FieldElement({ fieldName: "assignedDrillingRigName", label: "Assigned drilling rig name", input: { // Input configuration for the assigned drilling rig name field type: "dynamic-choice", choiceExpression: dynamicChoiceExpression.name, // Reference to the dynamic choice expression for the assigned drilling rig name field }, }), ], // Set the expression infos for the form template expressionInfos: [trueExpression, dynamicChoiceExpression], });
// Assign the form template to the layer drillLayer.formTemplate = formTemplate;The choiceExpression reads the current form values, filters the Drill rigs table by its maximum depth and diameter, and checks off-road capability when rough terrain is required. Each matching rig is returned as a choice with a descriptive label and the rig name as its stored value.
function getChoiceExpression() { return ` var depth = 0; var diameter = 0; var offRoadRequired = 0;
if (TypeOf($feature.depth) == "Number") { depth = $feature.depth; }
if (TypeOf($feature.diameter) == "Number") { diameter = $feature.diameter; }
if (TypeOf($feature.offRoadRequired) == "Number") { offRoadRequired = $feature.offRoadRequired; }
var where = \`maxDepth >= \${depth} AND maxDiameter >= \${diameter}\`;
if (offRoadRequired == 1) { where = where + " AND offRoadCapable=1" }
var rigsLayer = FeatureSetById($map, "1a13105b1ec-layer-9"); var matches = Filter(rigsLayer, where);
var choices = []; for (var rig of matches) { var name = \`\${rig.name} (\${rig.maxDepth}, \${rig.maxDiameter}\`;
if (rig.offRoadCapable == 1) { name = name + ", off-road capable"; } name = name + ")";
Push(choices, Dictionary({ name: name, code: rig.name}) ); } return { choices: choices } `; }