# Arcgis Editing

> Edit features with the Editor component/widget, configure forms, manage subtypes, handle attachments, and work with branch versioning. Use when adding, updating, or deleting features, building edit forms, managing feature attachments, or working with versioned edits.

- **Type:** Skill
- **Install:** `agentstack add skill-saschabrunnerch-arcgis-maps-sdk-js-ai-context-arcgis-editing`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [SaschaBrunnerCH](https://agentstack.voostack.com/s/saschabrunnerch)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [SaschaBrunnerCH](https://github.com/SaschaBrunnerCH)
- **Source:** https://github.com/SaschaBrunnerCH/arcgis-maps-sdk-js-ai-context/tree/master/skills/arcgis-editing

## Install

```sh
agentstack add skill-saschabrunnerch-arcgis-maps-sdk-js-ai-context-arcgis-editing
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# ArcGIS Editing

Use this skill for editing features including Editor configuration, form templates, subtypes, attachments, versioning, and programmatic edits.

## Import Patterns

### Direct ESM Imports

```javascript
import Editor from "@arcgis/core/widgets/Editor.js";
import FeatureForm from "@arcgis/core/widgets/FeatureForm.js";
import FormTemplate from "@arcgis/core/form/FormTemplate.js";
```

### Dynamic Imports (CDN)

```javascript
const Editor = await $arcgis.import("@arcgis/core/widgets/Editor.js");
const FeatureForm = await $arcgis.import("@arcgis/core/widgets/FeatureForm.js");
const FormTemplate = await $arcgis.import("@arcgis/core/form/FormTemplate.js");
```

> **Note:** The examples in this skill use Direct ESM imports. For CDN usage, replace `import X from "path"` with `const X = await $arcgis.import("path")`.

## Editor Component

The simplest way to add editing is the `` component.

### Basic Usage

```html

  

```

### Key Properties

| Property                       | Type            | Default | Description                     |
| ------------------------------ | --------------- | ------- | ------------------------------- |
| `heading-level`                | number          |         | Heading level for accessibility |
| `hide-create-features-section` | boolean         | false   | Hide the create features panel  |
| `hide-edit-features-section`   | boolean         | false   | Hide the edit features panel    |
| `hide-labels-toggle`           | boolean         | false   | Hide the labels toggle          |
| `hide-merge-button`            | boolean         | false   | Hide the merge features button  |
| `hide-settings-menu`           | boolean         | false   | Hide the settings menu          |
| `hide-sketch`                  | boolean         | false   | Hide the sketch tools           |
| `hide-split-button`            | boolean         | false   | Hide the split feature button   |
| `hide-tooltips-toggle`         | boolean         | false   | Hide the tooltips toggle        |
| `hide-undo-redo-buttons`       | boolean         | false   | Hide undo/redo buttons          |
| `hide-zoom-to-button`          | boolean         | false   | Hide the zoom-to button         |
| `label`                        | string          |         | Component label                 |
| `layer-infos`                  | LayerInfo[]     |         | Layer editing configuration     |
| `snapping-options`             | SnappingOptions |         | Snapping configuration          |
| `sync-view-selection`          | boolean         | false   | Sync selection with view        |

### Key Events

| Event                  | Description                                    |
| ---------------------- | ---------------------------------------------- |
| `arcgisSketchCreate`   | Fires during feature creation sketch           |
| `arcgisSketchUpdate`   | Fires during feature update sketch             |
| `arcgisPropertyChange` | Fires when `activeWorkflow` or `state` changes |
| `arcgisReady`          | Fires when the component is ready              |

### Key Methods

| Method                                                | Description                        |
| ----------------------------------------------------- | ---------------------------------- |
| `cancelWorkflow()`                                    | Cancel the active editing workflow |
| `deleteFeatureFromWorkflow()`                         | Delete the feature being edited    |
| `startCreateFeaturesWorkflowAtFeatureTypeSelection()` | Start creating features            |
| `startUpdateWorkflowAtFeatureEdit(feature)`           | Start editing a specific feature   |
| `startUpdateWorkflowAtFeatureSelection()`             | Start feature selection for update |

### Editor Component with Configuration

```html

  

  const FeatureLayer = await $arcgis.import(
    "@arcgis/core/layers/FeatureLayer.js",
  );

  const mapElement = document.querySelector("arcgis-map");
  const view = await mapElement.view;
  await view.when();

  const layer = new FeatureLayer({
    url: "https://services.arcgis.com/.../FeatureServer/0",
  });
  mapElement.map.add(layer);

  const editor = document.querySelector("arcgis-editor");
  editor.layerInfos = [
    {
      layer: layer,
      formTemplate: {
        title: "Edit Feature",
        elements: [
          { type: "field", fieldName: "name", label: "Name" },
          { type: "field", fieldName: "category", label: "Category" },
        ],
      },
      addEnabled: true,
      updateEnabled: true,
      deleteEnabled: false,
    },
  ];

```

## Editor Widget (Core API)

### Configurable Editor

```javascript
import Editor from "@arcgis/core/widgets/Editor.js";

const editor = new Editor({
  view: view,
  layerInfos: [
    {
      layer: featureLayer,
      formTemplate: {
        title: "Feature Details",
        description: "Enter feature information",
        elements: [
          {
            type: "field",
            fieldName: "name",
            label: "Name",
            description: "Enter the feature name",
          },
          {
            type: "field",
            fieldName: "category",
            label: "Category",
          },
        ],
      },
      addEnabled: true,
      updateEnabled: true,
      deleteEnabled: false,
    },
  ],
});

view.ui.add(editor, "top-right");
```

### LayerInfo Configuration

| Property                     | Type         | Default  | Description                     |
| ---------------------------- | ------------ | -------- | ------------------------------- |
| `layer`                      | FeatureLayer | required | The layer to edit               |
| `formTemplate`               | FormTemplate |          | Form configuration              |
| `enabled`                    | boolean      | true     | Enable editing on layer         |
| `addEnabled`                 | boolean      | true     | Allow creating features         |
| `updateEnabled`              | boolean      | true     | Allow updating features         |
| `deleteEnabled`              | boolean      | true     | Allow deleting features         |
| `geometryUpdatesEnabled`     | boolean      | true     | Allow geometry edits            |
| `attributeUpdatesEnabled`    | boolean      | true     | Allow attribute edits           |
| `attachmentsOnCreateEnabled` | boolean      | true     | Allow attachments when creating |
| `attachmentsOnUpdateEnabled` | boolean      | true     | Allow attachments when updating |

## Feature Form

### Standalone Feature Form

```javascript
import FeatureForm from "@arcgis/core/widgets/FeatureForm.js";

const form = new FeatureForm({
  container: "formDiv",
  layer: featureLayer,
  formTemplate: {
    title: "Edit Feature",
    elements: [
      {
        type: "field",
        fieldName: "name",
        label: "Name",
      },
      {
        type: "group",
        label: "Location Details",
        elements: [
          { type: "field", fieldName: "address" },
          { type: "field", fieldName: "city" },
          { type: "field", fieldName: "zip" },
        ],
      },
    ],
  },
});

// Set feature to edit
form.feature = graphic;

// Listen for submit
form.on("submit", async () => {
  if (form.valid) {
    const values = form.getValues();
    graphic.attributes = { ...graphic.attributes, ...values };
    await featureLayer.applyEdits({
      updateFeatures: [graphic],
    });
  }
});
```

### Feature Form Component

```html

  const featureForm = document.querySelector("arcgis-feature-form");

  // Configure the form
  featureForm.formTemplate = {
    title: "Edit Feature",
    elements: [
      { type: "field", fieldName: "name", label: "Name" },
      { type: "field", fieldName: "status", label: "Status" },
    ],
  };

  // Set feature to edit
  featureForm.feature = selectedGraphic;

  // Listen for value changes
  featureForm.addEventListener("arcgisValueChange", (event) => {
    console.log("Field changed:", event.detail.fieldName, event.detail.value);
  });

  // Listen for submit
  featureForm.addEventListener("arcgisSubmit", (event) => {
    console.log("Form submitted");
  });

```

### Form with Grouped Elements

```javascript
const formTemplate = {
  title: "Asset Details",
  elements: [
    {
      type: "group",
      label: "Basic Information",
      elements: [
        { type: "field", fieldName: "asset_id" },
        { type: "field", fieldName: "asset_name" },
        { type: "field", fieldName: "asset_type" },
      ],
    },
    {
      type: "group",
      label: "Maintenance",
      initialState: "collapsed",
      elements: [
        { type: "field", fieldName: "last_inspection" },
        { type: "field", fieldName: "next_inspection" },
        { type: "field", fieldName: "condition" },
      ],
    },
  ],
};
```

### Expression-Based Visibility

```javascript
const formTemplate = {
  expressionInfos: [
    {
      name: "type-requires-subtype",
      expression: "$feature.type == 'complex'",
    },
  ],
  elements: [
    {
      type: "field",
      fieldName: "type",
    },
    {
      type: "field",
      fieldName: "subtype",
      visibilityExpression: "type-requires-subtype",
    },
  ],
};
```

### Form Validation

```javascript
const form = new FeatureForm({
  layer: featureLayer,
  formTemplate: {
    elements: [
      {
        type: "field",
        fieldName: "email",
        label: "Email",
        requiredExpression: "email-required",
      },
    ],
    expressionInfos: [
      {
        name: "email-required",
        expression: "$feature.contact_method == 'email'",
      },
    ],
  },
});

// Available expression types on FieldElement:
// - visibilityExpression: controls field visibility
// - editableExpression: controls whether field is editable
// - requiredExpression: controls whether field is required
// - valueExpression: computes a calculated value for the field

if (form.valid) {
  // Submit
}
```

## Programmatic Editing (applyEdits)

```javascript
// Add features
const addResult = await featureLayer.applyEdits({
  addFeatures: [
    {
      attributes: {
        name: "New Feature",
        category: "Type A",
      },
      geometry: {
        type: "point",
        longitude: -118.805,
        latitude: 34.027,
      },
    },
  ],
});

// Update features
const updateResult = await featureLayer.applyEdits({
  updateFeatures: [
    {
      attributes: {
        OBJECTID: 123,
        name: "Updated Name",
      },
    },
  ],
});

// Delete features
const deleteResult = await featureLayer.applyEdits({
  deleteFeatures: [{ objectId: 123 }],
});

// Check results
addResult.addFeatureResults.forEach((result) => {
  if (result.error) {
    console.error("Add failed:", result.error.message);
  } else {
    console.log("Added feature OID:", result.objectId);
  }
});
```

## Subtypes

### Working with Subtypes

```javascript
const layer = new FeatureLayer({
  url: "https://services.arcgis.com/.../FeatureServer/0",
});

await layer.load();

const subtypeField = layer.subtypeField;
const subtypes = layer.subtypes;

subtypes.forEach((subtype) => {
  console.log("Code:", subtype.code);
  console.log("Name:", subtype.name);
  console.log("Default values:", subtype.defaultValues);
});
```

### Subtype Group Layer

```javascript
import SubtypeGroupLayer from "@arcgis/core/layers/SubtypeGroupLayer.js";

const subtypeLayer = new SubtypeGroupLayer({
  url: "https://services.arcgis.com/.../FeatureServer/0",
});

await subtypeLayer.load();

// Access sublayers by subtype
subtypeLayer.sublayers.forEach((sublayer) => {
  console.log("Subtype:", sublayer.subtypeCode, sublayer.title);
  // Each sublayer can have different renderer/popup
});
```

### Editor with Subtype Support

```javascript
const editor = new Editor({
  view: view,
  layerInfos: [
    {
      layer: subtypeGroupLayer,
      addEnabled: true,
      updateEnabled: true,
    },
  ],
});
```

## Versioning

### Branch Versioning Overview

Branch versioning allows multiple users to edit the same data simultaneously without conflicts until reconciliation.

```javascript
import VersionManagementService from "@arcgis/core/versionManagement/VersionManagementService.js";

const vms = new VersionManagementService({
  url: "https://services.arcgis.com/.../VersionManagementServer",
});

await vms.load();
console.log("Default version:", vms.defaultVersionIdentifier);
```

### Get Version Information

```javascript
const versions = await vms.getVersionInfos();
versions.forEach((v) => {
  console.log("Version:", v.versionName);
  console.log("  Owner:", v.versionOwner);
  console.log("  Access:", v.access); // public, protected, private
  console.log("  Parent:", v.parentVersionName);
});
```

### Create, Alter, Delete Versions

```javascript
// Create new version
const newVersion = await vms.createVersion({
  versionName: "MyEditVersion",
  description: "Version for editing project X",
  access: "private",
  parentVersionName: "sde.DEFAULT",
});

// Alter version properties
await vms.alterVersion({
  versionName: "sde.MyEditVersion",
  description: "Updated description",
  access: "protected",
});

// Delete a version
await vms.deleteVersion({
  versionName: "sde.MyEditVersion",
});
```

### Switching Versions

```javascript
// Set version on layer at creation
const featureLayer = new FeatureLayer({
  url: "https://services.arcgis.com/.../FeatureServer/0",
  gdbVersion: "sde.MyEditVersion",
});

// Or change version dynamically
await featureLayer.load();
featureLayer.gdbVersion = "sde.AnotherVersion";
await featureLayer.refresh();
```

### Edit Session and Reconcile

```javascript
const versionIdentifier = version.versionIdentifier;

// Start editing session
await vms.startEditing({ versionIdentifier });

// Apply edits to feature layer
await featureLayer.applyEdits(edits);

// Reconcile with parent
const reconcileResult = await vms.reconcile({
  versionIdentifier: versionIdentifier,
  abortIfConflicts: false,
  conflictDetection: "by-attribute",
  conflictResolution: "favorEditVersion",
  withPost: false,
});

if (!reconcileResult.hasConflicts) {
  await vms.post({ versionIdentifier });
}

// Stop editing
await vms.stopEditing({
  versionIdentifier: versionIdentifier,
  saveEdits: true,
});
```

### Complete Version Workflow

```javascript
async function editInVersion(vms, featureLayer, edits) {
  const version = await vms.createVersion({
    versionName: `Edit_${Date.now()}`,
    description: "Temporary edit version",
    access: "private",
  });

  const versionIdentifier = version.versionIdentifier;

  try {
    featureLayer.gdbVersion = version.versionName;
    await featureLayer.refresh();

    await vms.startEditing({ versionIdentifier });
    await featureLayer.applyEdits(edits);

    const result = await vms.reconcile({
      versionIdentifier,
      abortIfConflicts: false,
      conflictResolution: "favorEditVersion",
      withPost: false,
    });

    if (result.hasConflicts) {
      throw new Error("Conflicts detected during reconcile");
    }

    await vms.post({ versionIdentifier });
    await vms.stopEditing({ versionIdentifier, saveEdits: true });
  } finally {
    featureLayer.gdbVersion = vms.defaultVersionIdentifier;
    await featureLayer.refresh();
    await vms.deleteVersion({ versionName: version.versionName });
  }
}
```

## Related Records

### Query Related Records

```javascript
const relatedRecords = await layer.queryRelatedFeatures({
  outFields: ["*"],
  relationshipId: 0,
  objectIds: [selectedFeature.attributes.OBJECTID],
});

const results = relatedRecords[selectedFeature.attributes.OBJECTID];
results.features.forEach((related) => {
  console.log("Related:", related.attributes);
});
```

## Attachments

### Enable Attachments in Editor

```javascript
const editor = new Editor({
  view: view,
  layerInfos: [
    {
      layer: featureLayer,
      attachmentsOnCreateEnabled: true,
      attachmentsOnUpdateEnabled: true,
    },
  ],
});
```

### Progr

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [SaschaBrunnerCH](https://github.com/SaschaBrunnerCH)
- **Source:** [SaschaBrunnerCH/arcgis-maps-sdk-js-ai-context](https://github.com/SaschaBrunnerCH/arcgis-maps-sdk-js-ai-context)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-saschabrunnerch-arcgis-maps-sdk-js-ai-context-arcgis-editing
- Seller: https://agentstack.voostack.com/s/saschabrunnerch
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
