Edit features using feature forms

View inMAUIWPFWinUIView on GitHub

Display and edit feature attributes using feature forms.

Image of Edit features using feature forms sample

Use case

Feature forms help enhance the accuracy, efficiency, and user experience of attribute editing in your application. Forms can be authored as part of the web map using Field Maps Designer or using Map Viewer. This allows a simplified user experience to edit feature attribute data on the web map.

How to use the sample

Tap a feature on the map to open a sheet displaying the feature form. Select form elements in the list and perform edits to update the field values. Tap the submit icon to commit the changes on the web map.

How it works

  1. Add a Map to the MapView using Portal URL and item ID.
  2. When the map is tapped, perform an identify operation to check if the tapped location is an ArcGISFeature.
  3. Create a FeatureForm object using the identified ArcGISFeature.
  • Note: If the feature's FeatureLayer, ArcGISFeatureTable, or the SubtypeSublayer has an authored FeatureFormDefinition, then this definition will be used to create the FeatureForm. If such a definition is not found, a default definition is generated.
  1. Use the FeatureForm toolkit component to display the feature form configuration by providing the created featureForm object.
  2. Optionally, you can add a ValidationErrorVisibility option to the FeatureForm toolkit component that determines the visibility of validation errors.
  3. Once edits are added to the form fields, check if the validation errors list are empty using featureForm.ValidationErrors to verify that there are no errors.
  4. To commit edits on the service geodatabase:
    1. Call FinishEditingAsync() to save edits to the database.
    2. Retrieve the backing service feature table's geodatabase using serviceFeatureTable?.ServiceGeodatabase.
    3. Verify the service geodatabase can commit changes back to the service using serviceGeodatabase.ServiceInfo?.CanUseServiceGeodatabaseApplyEdits
    4. If apply edits are allowed, call ApplyEditsAsync() to apply local edits to the online service.
    5. If edits are not allowed on the ServiceGeodatabase, then apply edits to the ServiceFeatureTable using ApplyEditsAsync()

Relevant API

  • ArcGISFeature
  • FeatureForm
  • FeatureLayer
  • FieldFormElement
  • GroupFormElement
  • ServiceFeatureTable
  • ServiceGeodatabase

About the data

This sample uses a feature forms enabled Feature Form Places web map, which contains fictional places in San Diego of various hotels, restaurants, and shopping centers, with relevant reviews and ratings.

Additional information

Follow the tutorial to create your own form using the Map Viewer. This sample uses the FeatureForm and GeoViewCompose Toolkit modules to be able to implement a Composable MapView which displays a Composable FeatureForm UI.

This sample uses the feature forms toolkit component. For information about setting up the toolkit, as well as code for the underlying component, visit the toolkit repository.

Tags

edits, feature, featureforms, form, toolkit

Sample Code

EditFeaturesUsingFeatureForms.xaml.csEditFeaturesUsingFeatureForms.xaml.csEditFeaturesUsingFeatureForms.xaml
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Copyright 2021 Esri.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
// You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
// language governing permissions and limitations under the License.

using Esri.ArcGISRuntime.Data;
using Esri.ArcGISRuntime.Mapping;
using Esri.ArcGISRuntime.Mapping.FeatureForms;
using Esri.ArcGISRuntime.Portal;
using Microsoft.UI.Xaml;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace ArcGIS.WinUI.Viewer.Samples.EditFeaturesUsingFeatureForms
{
    [ArcGIS.Samples.Shared.Attributes.Sample(
        name: "Edit features using feature forms",
        category: "Data",
        description: "Display and edit feature attributes using feature forms.",
        instructions: "Tap a feature on the map to open a sheet displaying the feature form. Select form elements in the list and perform edits to update the field values. Tap the submit icon to commit the changes on the web map.",
        tags: new[] { "edits", "feature", "featureforms", "form", "toolkit" })]
    public partial class EditFeaturesUsingFeatureForms
    {
        private FeatureForm _featureForm;

        public EditFeaturesUsingFeatureForms()
        {
            InitializeComponent();
            _ = Initialize();
        }

        private async Task Initialize()
        {
            // NOTE: to be a writable geodatabase, this geodatabase must be generated from a service with a GeodatabaseSyncTask. See the "Generate geodatabase" sample.
            try
            {
                // Create the ArcGIS Online portal.
                var portal = await ArcGISPortal.CreateAsync();

                // Get the Naperville water web map item using its ID.
                var webmapItem = await PortalItem.CreateAsync(portal, "516e4d6aeb4c495c87c41e11274c767f");

                // Create a map from the web map item.
                var onlineMap = new Map(webmapItem);

                // Display the map in the MapView.
                MyMapView.Map = onlineMap;
            }
            catch (Exception ex)
            {
                await new MessageDialog2(ex.Message, "Error").ShowAsync();
            }
        }

        private async void MyMapView_GeoViewTapped(object sender, Esri.ArcGISRuntime.UI.Controls.GeoViewInputEventArgs e)
        {
            try
            {
                // Perform identify operation to get the feature.
                var identifyResult = await MyMapView.IdentifyLayersAsync(e.Position, 12, false);
                var feature = identifyResult.SelectMany(result => result.GeoElements).OfType<ArcGISFeature>().FirstOrDefault();

                if (feature != null)
                {
                    // Create a feature form.
                    _featureForm = new FeatureForm(feature);
                    // Assign the feature form to the FeatureFormView.
                    FeatureFormViewPanel.FeatureForm = _featureForm;

                    // Show the feature form.
                    FeatureFormPanel.Visibility = Visibility.Visible;
                }
            }
            catch (Exception ex)
            {
                await new MessageDialog2(ex.Message, "Error").ShowAsync();
            }
        }

        private async void SaveButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // Check if there are validation errors.
                if (_featureForm.ValidationErrors.Any())
                {
                    var errors = _featureForm.ValidationErrors;
                    var errorMessages = errors.SelectMany(kvp => kvp.Value.Select(ex => $"{kvp.Key}: {ex.Message}"));
                    string errorMessage = string.Join("\n", errorMessages);
                    throw new Exception($"Validation errors exist.\n{errorMessage}");
                }

                // Finish editing.
                await _featureForm.FinishEditingAsync();

                // Get the service feature table.
                var serviceFeatureTable = (ServiceFeatureTable)_featureForm.Feature.FeatureTable;

                // Get the service geodatabase.
                var serviceGeodatabase = serviceFeatureTable.ServiceGeodatabase;

                // Check if the service geodatabase can apply edits.
                if (serviceGeodatabase.ServiceInfo?.CanUseServiceGeodatabaseApplyEdits == true)
                {
                    // Apply edits to the service geodatabase.
                    await serviceGeodatabase.ApplyEditsAsync();
                }
                else
                {
                    await serviceFeatureTable.ApplyEditsAsync();
                }

                // Hide the feature form.
                FeatureFormPanel.Visibility = Visibility.Collapsed;
            }
            catch (Exception ex)
            {
                await new MessageDialog2(ex.Message, "Error").ShowAsync();
            }
        }

        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            // Cancel editing.
            _featureForm.DiscardEdits();

            // Hide the feature form.
            FeatureFormPanel.Visibility = Visibility.Collapsed;
        }
    }
}

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