Edit attribute values

Attributes represent intelligent information about geographic features in a GIS. Although the information captured is important, collecting attribute values can be challenging. For example, attribute value errors can occur when an incorrect value is recorded within the attribute field or when a field is missing a value. Misspelled words and other typographical errors are common problems that can lead to inaccurate conclusions when performing a GIS analysis while solving a spatial problem. Attribute domains, subtypes, rules, and contingent values provide potential enhancements to reduce data entry error. Forms provide another tool that can be used to enhance the data collection process to:

  • ease data entry for application end users
  • limit the types of input by restricting and guiding data types (for example, character limits, value options, numeric vs. string values)
  • perform easier calculations from attribute to attribute using Arcade scripting calculated upon data entry

You can display these forms, also known as feature forms, to users of your ArcGIS Maps SDK for Swift application using a couple of approaches.

  1. The recommended approach is to use the open source toolkit component that uses the API described in this topic.
  2. For requirements that go beyond the capabilities of the toolkit component, you can work with the API directly as described in this topic to meet your specific obligations.

Build and access the feature form

Forms are defined in the web map JSON specification (also known as formInfo) and created using the map viewer in ArcGIS Online, ArcGIS Enterprise, or the Field Maps Designer. Before you can get started with the API, a form must be defined for a supported feature layer and saved with a web map that you have access to because the form configuration JSON, formInfo, is saved as part of the web map definition. See Display a web map for documentation on how to programmatically access a web map from a portal, if necessary. After programmatically retrieving the web map and obtaining the feature layers contained within, there are two ways you can access the feature form definition: FeatureLayer or ArcGISFeatureTable. Both classes contain a property allowing you to retrieve the feature form definition. A FeatureFormDefinition is the serialized JSON representation of the feature form as it was defined and saved in the web map for a feature layer. Essentially, the feature form definition represents metadata describing the details around how a form was defined.

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
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
        // Gets a feature layer from the `ArcGISFeature` to retrieve the feature form definition.
        let layer = feature.table?.layer as? FeatureLayer
        // Uses the feature layer to retrieve the feature form definition.
        guard let formDefinition = layer?.featureFormDefinition else { return }

A FeatureForm is created using the feature form definition and a new or existing feature. Using the metadata from the feature form definition and the field information from the feature, the feature form is exposed by the API. As a start, you can use the feature form, for instance, to retrieve the FeatureForm.elements defined in the form. FormElement can be used to help you interrogate the details around a specific element in order to construct a user interface for editing a feature's attributes. There are many methods you can use to obtain the ArcGISFeature, such as adding a new feature, querying for a feature, or identifying a feature, to name a few.

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
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
        // Uses the feature identified by the user and the feature form definition to construct a new feature form.
        let featureForm = FeatureForm(feature: feature, definition: formDefinition)

Evaluate expressions

ArcGIS Arcade can be used to add logic to a form allowing the behavior of form elements to be controlled. With Arcade expressions, form elements can be dynamically hidden, required, or enabled for editing depending on conditions set in the expression. In addition, it's possible to add calculation expressions that allow values to be calculated and populated in the form. The feature form can asynchronously evaluate all form expressions, FeatureForm.evaluateExpressions(), and upon completion return a set of FormExpressionEvaluationErrors providing diagnostic information about errors encountered while evaluating these expressions.

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
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
        // It is required to call evaluateExpressions() before displaying the feature form.
        // Performs the initial expression evaluation.
        let formExpressionEvaluationErrors = try await featureForm.evaluateExpressions()
        // Sets a flag to know that the initial evaluation has completed.
        initialEvaluation = false

Retrieve validation errors

Validation errors can be thought of in two distinct ways. The first use case allows you to retrieve validation errors for any individual FieldFormElement. This approach can be useful to provide your application user with feedback while editing a single form element.

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
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
        // Await validation errors for an individual field form element.
        let validationErrorTask = Task.detached {
            // Await validation errors for an individual field form element.
            for await errors in fieldFormElement.$validationErrors {
                // Return if our Task is cancelled.
                guard !Task.isCancelled else { return }
                // Use `errors` to notify the user with a description of the errors.
            }
        }

The second use case comes when the user of your application is ready to submit the edited attribute values with the intention of committing the edits to the database. In this scenario, it is ideal to retrieve validation errors for all the form elements in the feature form, although it is not a requirement. If desired, you can use FeatureForm.validationErrors to retrieve the errors. If errors are present, then a dictionary mapping from the field form element's field name (the key) to an array of errors is available to help you determine which fields may have one one or more errors associated with it. An empty dictionary implies that that all form element values are valid, thus the edits can be committed to the database in this scenario.

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
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
        // Retrieves the feature form validation errors for all form elements
        // and loop through the contents by field name.
        for (fieldName, errors) in featureForm.validationErrors {
            // It is possible to have more than a single error for a form element.
            errors.forEach { error in
                // Use the field name and the array of errors to
                // format a descriptive message for the user.
                print(error)
            }
        }

If any validation errors exist, then it becomes a matter of choice whether to display these errors or to wait till the user of the application edits form element values. The toolkit component discussed previously, upon displaying the feature form for the first time, does not display validation errors; however, the alternative approach can be taken and any validation errors can be displayed for the application end user to address.

Show any validation errors

In the case that you want to display validation errors that your user will need to address before they can submit the form for further action, the user interface experience is left entirely up to your preferences. It's important to note that the validation errors you learned how to retrieve earlier are likely not sufficient for helping your user resolve the problem. You will likely need additional logic in your application to interrogate why an error was thrown and what message you will display to your user. For example, if the FeatureFormError.exceedsNumericMaximum is retrieved, then your logic could interrogate what the maximum length is when displaying your error message to the user, perhaps even provide a character count as the user addresses the problem that disappears when the character count falls below the maximum length allowed. If necessary, the toolkit component is open source and can be reviewed for examples on how you might address each error type.

Update value for a form element

The user of your application can edit a form element value. When that value is changed, you'll need to update the value on the form element in the API. Calling FieldFormElement.updateValue() updates the value of a field in the feature associated with the FieldFormElement. At a minimum, the value passed in should be the correct data type for the field in the feature.

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
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
        // Updates a form element with the new value.
            .onChange(of: text) { text in
                // Call the update value method with the new value.
                formElement.updateValue(text)

                // Evaluates the form expressions after the form element value is updated.
                Task {
                    try await featureForm.evaluateExpressions()
                }
            }

After the value is updated, you should evaluate expressions in order to update any dependent properties. If you have code that is retrieving validation errors (either at the feature form level or individual field form elements - see retrieve validation errors for details), then your logic will be called if there is any change to the validation status. This process repeats itself for each form element that is editing by the application user.

Process validation errors

Earlier, it was illustrated how to retrieve validation errors. This section describes the process for dealing with validation errors when they exist. If no validation errors exist, then you can proceed with adding a new or updating an existing feature following the edit process captured here. When validation errors exist, you can choose to ignore them and proceed with the editing process or you can work through each validation error by displaying a useful message to your end user and following the process captured in the update value for a form element section since it will be the application user that needs to resolve whatever validation error is not being met.

For example, let's say a form definition contains a field form element used to capture a social security number (SSN). A SSN, for those that may not know, is a unique numerical identifier assigned to every U.S. citizens to track income and other government benefits. In this scenario, this feature attribute is required and all SSN's are precisely 9 digits long. During the design of the form, two constraints are placed on the field form element requiring that the value be present and exactly 9 characters long (minimum = maximum = 9). Initially, this form element can be empty with no error. However, when the form is displayed and the user starts to engage with the field form element, then the following logic can be used to gather the errors for this field form element.

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
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
        // Awaits validation errors for an individual field form element.
        let validationErrorTask = Task.detached {
            // Awaits validation errors for an individual field form element.
            for await errors in fieldFormElement.$validationErrors {
                // Return if our Task is cancelled.
                guard !Task.isCancelled else { return }
                // Use `errors` to notify the user with a description of the errors.
            }
        }

The following code shows one approach on how you might process the collection of potential errors possible in the scenario described.

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
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
        // In this example, we know the value is a string for this particular element/field type.
        let currentValue = fieldFormElement.value as? String

        if currentValue?.isEmpty ?? true {
            if errors.contains(where: { $0.localizedDescription == isRequiredError.localizedDescription })
                &&
                errors.contains(where: { $0.localizedDescription == characterConstraintError.localizedDescription }) {
                // Show no error if the field is empty, which is common
            }
        } else {
            // Show an appropriate error so the user can intuitively address the validation error.
        }

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