This sample demonstrates how to edit related data using the Editor widget. By default, this widget will not automatically detect and enable editing for related data. A configured FormTemplate must be set on either the FeatureLayer or FeatureForm. If there is an associated Form
on the editable layer, the Editor will automatically recognize the configured form information within it and display it while editing.
Relationship editing is enabled by adding relationship elements to the FormTemplate in the Editor's layer
. Alternatively, this could have been set directly on the FeatureLayer.formTemplate.
In order for relationship elements to work, there must be an relationship class set on the editable layer. Creating the relationship class is handled outside of the SDK, in an application such as ArcGIS Pro.
Further considerations for editing related data can be found at Relationship element API reference.
In addition to working with related data, this sample also makes use of calculated expressions via Arcade expressions. An expression can be useful when wanting to control behavior of a field's visibility, requirement, editability, or the actual value itself. This sample demonstrates the use of valueExpressions, and also requiredExpressions, and editableExpressions.
How it works
This sample takes an existing webmap which contains a feature layer and two tables that participate in a relationship. The Parcels layer participates in a one-to-one relationship with the Permits table and a one-to-many relationship with the Owners table. The application creates a new FormTemplate with Field and Relationship elements. In order for the related records to display while editing, all the data that participates in the relationship should be added in the map. In addition, the form must be configured with the Relationship elements.
The following snippets show the steps needed using one of the expressions and associated field element.
The expressions are written as <script
tags at the top of the application.
<script type="text/plain" id="get-owner-count">
// Check the edit context
// If it is insert (create workflow), return and get out
if ($editcontext.editType == "INSERT") {
return;
} else {
// If not Insert/Create
// Get a FeatureSet of owners from the related owners table
var ownersFeatureSet = (FeatureSetByRelationshipName($feature, 'NZParcels_Owners', ['*'], false));
// Make sure ownersFeatureSet is not empty
if(!(IsEmpty(ownersFeatureSet))) {
// Count the amount of owners within the owners featureset
var countOwners;
countOwners = Count(ownersFeatureSet)
// Apply the count to the value in the owner_number field
return countOwners;
}
// If ownersFeatureSet is empty, return nothing.
return;
}
</script>
Create the ExpressionInfo and set its name to the script's id
.
const getOwnerCountExp = new ExpressionInfo({
expression: document.getElementById("get-owner-count").text,
name: "get-owner-count",
returnType: "number",
title: "Get owner count"
});
The expressionInfo is then set on the FieldElement.
const ownerCountParcelFE = new FieldElement({
description: "Queries the related owners table and counts the number of owners related to this parcel",
label: "Total no. of owners",
fieldName: "owner_number",
editableExpression: falseExp.name,
input: { // autocastable to TextBoxInput
type: "text-box"
},
valueExpression: getOwnerCountExp.name
});
Set the FieldElement into an array of the FormTemplate's elements and set the ExpressionInfo into an array of the FormTemplate's expressionInfos.
const parcelsFormTemplate = new FormTemplate({
title: "Parcel ID - {parcel_id}",
elements: [parcelIdFE, parcelTypeFE, calcParcelAreaFE, ownerCountParcelFE, relatedOwners, relatedPermits],
expressionInfos: [createParcelIdExp, calcParcelAreaExp, getOwnerCountExp, trueExp, falseExp]
});
Finally, set the FormTemplate on the parcels layer.
view.map.editableLayers.forEach((layer) => {
if (layer.title == "Parcels") {
parcelsLayer = layer;
parcelsLayer.formTemplate = parcelsFormTemplate;
}
});
Take note that fields containing a valueExpression cannot be modified directly within the form as they are dependent upon the returned value of the evaluated expression. It is by design that they should not be editable.
The following table lists the referenced Arcade expressions expression names used in this sample with a short description of its behavior.
Arcade expression name | Expression type | Behavior description |
---|---|---|
true-boolean | requiredExpression | A boolean value indicating whether the Ownership date field is required. |
false-boolean | editableExpression | A boolean value indicating whether the Parcel, Owner, and Permits' Parcel ID fields can be edited. In addition, it also sets the whether the Parcel's Total no. of owners and Parcel area in sq. meters fields. can be edited. |
create-parcel-id | valueExpression | Populates the Parcel layer's Parcel ID field with a randomly-generated ID value. |
calculate-parcel-area | valueExpression | Populates the Parcel layer's Area field in square meters. |
get-owner-count | valueExpression | Populates the Parcel layer's Total no. of owners field with the total number of owners related to the parcel layer. |
parcel-id-owner | valueExpression | Populates the Owners table's Parcel ID field with the parcel ID. |
parcel-id-permit | valueExpression | Populates the Permits table's Parcel ID field with the parcel ID. |
The expression must follow the Form Calculation Profile specification.