Editing related data with calculated expressions

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 FormTemplate 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 layerInfos.formTemplate. 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.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<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.

Use dark colors for code blocksCopy
1
2
3
4
5
6
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.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
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.

Use dark colors for code blocksCopy
1
2
3
4
5
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.

Use dark colors for code blocksCopy
1
2
3
4
5
6
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 nameExpression typeBehavior description
true-booleanrequiredExpressionA boolean value indicating whether the Ownership date field is required.
false-booleaneditableExpressionA 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-idvalueExpressionPopulates the Parcel layer's Parcel ID field with a randomly-generated ID value.
calculate-parcel-areavalueExpressionPopulates the Parcel layer's Area field in square meters.
get-owner-countvalueExpressionPopulates the Parcel layer's Total no. of owners field with the total number of owners related to the parcel layer.
parcel-id-ownervalueExpressionPopulates the Owners table's Parcel ID field with the parcel ID.
parcel-id-permitvalueExpressionPopulates the Permits table's Parcel ID field with the parcel ID.

The expression must follow the Form Calculation Profile specification.

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.