The composable FeatureForm in the ArcGIS Maps SDK for Kotlin Toolkit provides a ready-to-use form for editing attributes and attachments of one feature at a time. The toolkit component provides the following functionality:

  • Displays the feature form UI in your app.
  • Handles interactions between the user and the feature form.
  • Displays validation errors below field form elements that are visible in the form.
  • Evaluates Arcade expressions defined in the expressionInfos array in the feature form definition. The expressions provide values for properties in the formElements array.

Since the toolkit is open source, the component can be extended to meet any special UI requirements your app might have.

A typical composable feature form from the toolkit looks something like the following.

Animated feature form editing workflow in the toolkit.

Using the toolkit component allows you to focus on intuitive editing workflows for your user, rather than the low-level details of creating an editing UI, handling user interaction, and validating input. Implementing an editing workflow using feature forms may follow a pattern like this:

  1. Create an instance of the FeatureForm from the ArcGIS Maps SDK for Kotlin API.
  2. Call the FeatureForm composable from the ArcGIS Maps SDK for Kotlin toolkit.
  3. Process errors before submitting edits.
  4. Save or discard edits.
  5. Persist edits.

Create a FeatureForm instance

Before using the toolkit component, you must create an instance of the FeatureForm class with the feature to be edited. The FeatureForm class is defined in the ArcGIS Maps SDK for Kotlin API.

You can now create an instance of FeatureForm by passing in the feature.

// Create a FeatureForm instance using a feature.
val featureForm = FeatureForm(feature)

For ways to obtain a feature, see the Create a feature form instance section on the Overview page.

Call FeatureForm composable in toolkit

You display a feature form in your app by calling the FeatureForm composable, passing in an instance of FeatureFormState. The FeatureFormState constructor takes the FeatureForm instance you created above. The toolkit’s feature form can be displayed in an Android BottomSheet or other view appropriate to your app design.

FeatureForm(
featureFormState = FeatureFormState(
featureForm = featureForm,
coroutineScope = scope
),
modifier = Modifier
.fillMaxSize(),
validationErrorVisibility = ValidationErrorVisibility.Automatic,
onBarcodeButtonClick = { fieldFormElement -> /*Code that handles a barcode that has been acquired through a barcode scanner */ },
)

The validationErrorVisibility parameter determines how errors are displayed in your feature form. The parameter must be passed when you call the composable. See Visibility of validation errors on the form.

The onBarcodeButtonClick parameter is a lambda that is invoked when a barcode or QR scanner attached to the user’s device scans a barcode or QR code and returns the corresponding series of numbers and/or letters.

Visibility of validation errors on the form

The toolkit’s feature form has built-in functionality to display input errors directly on the form. Each error displays adjacent to the element and describes which constraint has been violated. For example, if the user inputs a string that exceeds the maximum length as defined by the form definition author, a validation error such as the following is displayed:

Example of an error on a feature form.

The validation errors on the form can be displayed in one of two ways:

  • Interactively - Upon initial display of the feature form, no errors are visible. An error for a field form element can display only when the user brings focus to the element. If the element was saved with an error (for example, a required field was left empty), then tapping on the element will immediately display the error. Otherwise, an error displays after the user enters a value that violates constraints.

  • All at once - Upon initial display of the feature form, all errors are visible.

You control the visibility of errors on the form by the constant you pass when calling the composable FeatureForm from the toolkit. The available constants are Automatic and Visible in the toolkit’s ValidationErrorVisibility sealed class. The Automatic constant displays validation errors interactively; this is the default. The Visible constant displays all validation errors at once.

Save and discard buttons

The toolkit’s FeatureForm component automatically displays a save button and a discard button.

Work with attachments

If a feature belongs to a layer that supports attachments, the toolkit’s feature form provides a UI for viewing, adding, and deleting attachments.

When a form contains attachment elements configured in ArcGIS Field Maps Designer or Map Viewer, the toolkit displays the attachment UI according to that design. If no attachment elements are configured, the toolkit component displays a default attachment UI. Attachment elements are defined by the web map specification’s formAttachmentElement and formAttachmentInput objects.

The form author configures attachment elements in the web map; your app displays them using the toolkit’s feature form. You do not need to build a separate attachment editing UI.

Attachment filenames and collection options

Configured attachment elements let the form author control whether filenames are displayed and whether users can rename attachments. Filenames can also be calculated from Arcade expressions defined by the form author. See the Form Attachment Filename Calculation profile.

The toolkit’s attachment menus respect the configured attachment types and collection methods. Depending on the attachment element’s configuration and device capabilities, users can take a photo, record a video, select existing media, or choose a file from the device. The form can offer more than one of these options.

Associate attachments with form elements

A keyword can be assigned to an attachment form element to associate attachments with that element. The attachment association rule, defined by AttachmentsFormElement.attachmentKeywordAssociation, determines which attachments are associated with the element:

  • All attachments on the feature, including those with matching keywords, different keywords, or no keyword.
  • Only attachments whose keyword exactly matches the element’s keyword.
  • Attachments with the element’s keyword or no keyword. Attachments with other keywords are excluded.

When the form author defines an attachment form element, a keyword is automatically assigned to the element. By default, the keyword is the element’s display name. Attachments added through the form element are automatically assigned that keyword.

Attachment constraints and validation

Attachment form elements support the following configured limits:

  • The minimum and maximum number of attachments.
  • The allowed attachment types.
  • The maximum duration of audio and video attachments for AudioFormInput and VideoFormInput.
  • The maximum file size of document attachments for DocumentFormInput.
  • The maximum length, in pixels, of an image attachment’s longest edge for ImageFormInput.

When an attachment is added through an attachment form element, the API checks its type, duration, and file size against the applicable configured limits and rejects it if those limits are violated. Adding an attachment is also rejected if it would exceed the maximum attachment count. Images that exceed the configured pixel dimensions are resized before being added.

The toolkit displays attachment-count validation errors on the attachment element and reports errors encountered when adding attachments. The video capture UI also honors the configured maximum duration while recording a video. Your app can also check attachment and field validation errors before submitting edits.

Include attachment keywords in offline data

Including attachment keywords in offline data allows the form to associate attachments with the appropriate attachment form elements.

When generating an offline geodatabase:

  1. Check SyncCapabilities.supportsAttachmentKeywords to confirm that the feature service supports syncing attachment keywords.
  2. Set GenerateGeodatabaseParameters.syncAttachmentKeywords to true to include the keywords.
  3. To make existing attached files available offline as well, set GenerateGeodatabaseParameters.returnAttachments to true. This setting controls attachment downloads separately from keyword inclusion.

When generating an on-demand offline map, use GenerateOfflineMapParameterOverrides to configure these settings for each geodatabase.

For preplanned offline map areas, attachment keywords must be included when the geodatabases are prepared. The app cannot enable keyword inclusion when downloading the area.

For general offline data guidance, see Work with offline data.

Process form errors before submitting edits

When users are ready to submit their feature form edits, the toolkit component will check for validation errors. If there are no such errors, the edits can be saved to the local geodatabase. If there are errors, the toolkit component will display the errors and require the user to fix them all.

Alternatively, if your workflow requires a more lenient approach, you can take over the responsibility of saving edits and checking which validation errors you want to enforce and which you can ignore.

Inspecting validation errors: form elements

Use FeatureForm.elementValidationErrors to retrieve validation errors for attachment form elements and for field form elements that are both visible and editable.

Errors for hidden or noneditable fields are not included, even if those fields contain invalid values. To check those fields too, see Process all validation errors.

The returned dictionary maps each form element with errors (the key) to a collection of its errors (the value). An empty dictionary indicates that the visible, editable field form elements are valid and that the attachment form elements are valid. It does not indicate whether hidden or noneditable fields are valid.

A field form element has a validation error when its value does not meet the constraints of its input type or when a required value is missing. Whether a value is required is indicated by FieldFormElement.isRequired. The form author can configure field element visibility using visibilityExpression and editability using editableExpression in the feature form definition.

Inspecting validation errors: attachment form elements

To inspect validation errors for an individual attachment form element, use AttachmentsFormElement.validationErrors. For example, the element reports a validation error if it contains fewer attachments than required.

Adding an attachment can fail before the attachment becomes part of the element. These errors are reported by AttachmentsFormElement.addAttachment(), rather than by inspecting the element’s validation errors. For example, adding an audio or video attachment fails if it exceeds its configured maximum duration.

For the steps to save edits locally and then persist them to the feature service, see Save or discard edits and Persist edits.

Validation error types

Validation errors identify constraints that a field or attachment form element does not satisfy, such as a missing required field value or an attachment count outside the configured limits.

For lists of validation errors, see the following API reference pages:

Process all validation errors

FeatureForm.elementValidationErrors includes validation errors for attachment form elements. For field form elements, however, it includes errors only when the element is both visible and editable. If your app also needs errors for hidden or noneditable fields, inspect the validation errors for each field form element individually.

Start by accessing FeatureForm.elements to get a collection of all the form elements in the feature form. Then iterate over the collection, filtering for FieldFormElement. For each field form element, call FieldFormElement.validationErrors, which will evaluate the element’s Arcade expressions and any other relevant expressions and validate the field’s value.

Save or discard edits

When a user is finished making edits in the form, they can either save their edits to the local geodatabase or discard them.

User chooses to save edits

Toolkit default behavior

  • The end user taps the save button in the toolkit component.
  • The toolkit component defaults to checking validation errors (on visible and editable elements), and notifies the user if there are errors that need to be fixed before saving can proceed.
  • If there are no validation errors, the toolkit component calls FeatureForm.elementValidationErrors to check for any remaining errors and then calls FeatureForm.finishEditing(), which ends the editing session and saves the edits to the local geodatabase.

Your app code handles saving edits

Alternatively, you can take over the save responsibility. If you do so, you can check for validation errors by inspecting the FeatureForm.elementValidationErrors errors or by inspecting validation errors for all elements (if you need to check validation on non-editable or non-visible elements as well). In this approach, you can decide which errors you want to enforce, and which you want to ignore before calling FeatureForm.finishEditing().

Finishing editing saves all form-element edits to the local database. You do not need to add or update the feature separately. Applying those edits to the feature service is a separate step.

User chooses to discard edits

If the user decides that the edits in the form should not be saved to the local geodatabase, they tap the discard button in the toolkit component. If edits exist, the user will be notified that edits exist to confirm discarding them.

Alternatively, you can programmatically discard edits by calling FeatureForm.discardEdits().

Persist edits

When feature form edits are saved to the local geodatabase, they are preserved on the user’s device. These edits are not stored with the associated feature service until they are explicitly persisted.

To persist all edits from your service geodatabase to its associated service feature.

  1. Get the ServiceFeatureTable from the Feature that was edited.
  2. Get the ServiceGeodatabase from the table.
  3. Get the service info with ServiceGeodatabase.serviceInfo and then use ArcGISFeatureServiceInfo.canUseServiceGeodatabaseApplyEdits to check that you can commit edits back to the feature service.
  4. Call ServiceGeodatabase.applyEdits() to commit the edits.

For more information, see the Persist edits topic in the Basic editing workflow section of this guide.

As part of your app design, you can decide when and how users save edits in the local database and ultimately persist them with the feature service. For example, your app could persist edits to the service each time an edit is made and saved locally, or you could wait until the user has completed all local edits (or a set of them) before persisting them to the service. Likewise, you can either let the user decide when edits are persisted (with a UI control, for example) or you can persist edits for them automatically.