Skip to content

Contingent values

Contingent values are a data design feature that allow you to make the values in one field dependent upon the values in another field. In other words, contingent values are how you define a set of attribute values that are specifically valid in the context of other feature attribute values. For example, a power pole dataset might use contingent values to specify which values are appropriate for poles based on particular attributes. The voltage level for a pole determines what material values are valid; each material might have a set of appropriate heights from which to choose. Contingent values let you define all valid combinations of values for two or more attribute fields within a dataset.

Values in the dropdown are contingent values based on the previous entry.

What contingent values look like

You can author contingent values using ArcGIS Pro and save them in a mobile map or scene package, standalone geodatabase, web map, web scene, or feature service.

Contingent values are defined in one or more field groups. A field group is a named collection of attribute fields in your dataset that have contingent values. Each field in a field group must have an associated domain. Contingent values are based on the field's domain and represent a subset of the values the domain defines. See Introduction to attribute domains in the ArcGIS Pro documentation for more information about domains.

For each field group, contingent values define all combinations of appropriate values for the participating fields. The value you provide for each field depends on the type of domain associated with it (coded value or range). You can also provide special values to indicate that any value in the domain is considered valid or that a null value is valid (for fields that accept null values). Note that the any value also includes null.

The following image shows a field group defining a set of contingent values for power poles. The fields Voltage, Material, and Height use coded value domains for their values, while Diameter uses a range domain. Poles that have a value of Wood in the Material field can have any value for Height that's in the associated domain (or null) without violating the contingent value constraints.

Contingent values that define all valid combinations for voltage levels, material types, pole height, and diameter.

Access contingent values in your app

Classes and helper methods are provided for reading contingent value definitions for a dataset and for determining contingent value violations for a specific feature, allowing your app to incorporate contingent values into editing workflows. You might use drop down lists, for example, to provide the appropriate list of values based on other attributes that have been specified. Your app can also validate against contingent values to find violations before saving edits for a feature.

Contingent values can be read from an ArcGISFeatureTable. Here are some of the classes used to represent contingent values:

  • FieldGroup—Defines all possible contingent values for a set of fields. The contingent values definition contains a collection of field groups.

  • Contingency—Defines a set of contingent values for a field group.

  • ContingentValue—A base class that defines a possible value for a field participating in a field group. A contingent value can be one of the following:

In addition to these classes, the API provides the following helper methods on ArcGISFeatureTable. In many cases, these helper methods are all you need to provide contingent value support when editing the table.

Edit with contingent values

Contingent values do not enforce data integrity or attribute rules for the data. However, you can design your app to guide the user through an edit workflow where contingent values provide appropriate choices and validation checks before edits are saved. For example, you could enforce ordered steps in your editing workflow to ensure that the current set of values you display for the editor are based on the previous inputs.

Values in the dropdown are contingent values based on the previous entry.

Get contingent values

Contingent values are derived from values in an attribute domain for the dataset. Since domains can either be a list of coded values or a range of acceptable numeric values, the same is true for contingent values. Each set of contingent values is defined from a subset of the domain. If your domain for pole diameter defines a range of 6 to 18 inches, for example, any contingent values must be within this range, such as 7 to 10 inches. Likewise, coded value domains define a set of acceptable values, and the contingent values must contain a subset of those items.

To get the contingent values for a field, use the ArcGISFeatureTable.contingentValues(with:forFieldNamed:)helper method and pass the current feature and the field name. The helper method looks at the current values defined for other attributes of the feature to return a set of the appropriate contingent values for the specified field.

You can get all contingent coded values for the specified field based on the other attribute values for the provided 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 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231  // Get all contingent values defined for a specified field name.  // The attribute values of the feature determine which contingent values are returned.  let contingentValuesResult = featureTable.contingentValues(with: feature, forFieldNamed: "Material")  // Get contingent values for a specified field group.  guard let contingentValues = contingentValuesResult?.contingentValuesByFieldGroup["voltage_material"] else {  return }  // You can use code like this to get contingent values for all field groups if this field participates in more than one.  // let allContingentValues = contingentValuesResult?.contingentValuesAllGroups  // Stores a list of values from the contingent values field group.  let availableValues = contingentValues.compactMap { $0 as? ContingentCodedValue }.map { $0.codedValue } 

If the contingent values are from a range domain, you can return the minimum and maximum values for the valid range.

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 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231  if let contingentRangeValue = contingentValue as? ContingentRangeValue {  guard let minValue = contingentRangeValue.minValue as? Int else { return }  guard let maxValue = contingentRangeValue.maxValue as? Int else { return }  range = minValue...maxValue  // ...   } 

If an ContingentAnyValue is defined for the field, you can provide all values from the field's domain as valid edit choices.

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 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231  // Checks for ContingentAnyValue (which means any value in the domain is valid).  if contingentValue is ContingentAnyValue,  let domain = featureTable.field(named: fieldName)?.domain as? CodedValueDomain {  // Adds all values from the field's domain.  availableValues = domain.codedValues  } 

Validate edits against contingent values

To see if a feature's attribute values conform to the defined contingent values, call the ArcGISFeatureTable.validateContingencyConstraints(for:) helper method and pass a feature. The method returns a collection of ContingencyConstraintViolation that you can use to enforce edit restrictions or provide warnings to the user.

Each contingency constraint violation indicates if it is a warning or an error, and which field group contains the violated contingent value. A violation is considered an error if the field group is marked as restrictive, meaning that edits to any participating fields must conform to previously defined contingent values. If a field group is not marked restrictive, the violation is considered a warning.

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 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231  let contingentValueViolations = featureTable.validateContingencyConstraints(for: feature)   // If there are no violations, allow user to save the feature.  if contingentValueViolations.isEmpty {  saveFeatureButton.isEnabled = true  }   // Loops through contingency violations and show messages for errors and warnings.  // Includes the name of the field group that has the violation.  contingentValueViolations.forEach { violation in  // Gets the violation type and field group name  let violationType = violation.kind == .error ? "Error" : "Warning"  let message = "Contingency value violation for field group \(violation.fieldGroup.name)"  // Prints the validation message.  print(violationType)  print(message)  } 

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