<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<title>Popup with edit action | Sample | ArcGIS Maps SDK for JavaScript</title>
<!-- Load the ArcGIS Maps SDK for JavaScript from CDN -->
<script type="module" src="https://js.arcgis.com/5.0/"></script>
<arcgis-map basemap="topo-vector" center="-106.49, 31.8" zoom="15">
<arcgis-popup slot="popup"></arcgis-popup>
<arcgis-zoom slot="top-left"></arcgis-zoom>
collapse-tooltip="Close info"
expand-tooltip="Open for info">
heading="Popup with edit action"
description="Edit the feature by clicking on the 'Edit feature' action within the popup."></calcite-tile>
hide-snapping-controls-elements-enabled-toggle></arcgis-editor>
const [Map, FeatureLayer, AttachmentsContent, TextContent, reactiveUtils] =
"@arcgis/core/layers/FeatureLayer.js",
"@arcgis/core/popup/content/AttachmentsContent.js",
"@arcgis/core/popup/content/TextContent.js",
"@arcgis/core/core/reactiveUtils.js",
const viewElement = document.querySelector("arcgis-map");
const editorComponent = document.querySelector("arcgis-editor");
const popupComponent = document.querySelector("arcgis-popup");
const featureLayer = new FeatureLayer({
url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/El_Paso_Recreation_AttributeEditsOnly/FeatureServer/1",
title: "Trail name: {trailName}",
content: difficultyLevel,
// Function that creates two popup elements for the template: attachments and text
function difficultyLevel(feature) {
// 1. Set how the attachments should display within the popup
const attachmentsElement = new AttachmentsContent({
const textElement = new TextContent();
const level = feature.graphic.attributes.difficulty;
const green = "<b><span style='color:green'>" + level + "</span></b>";
const purple = "<b><span style='color:purple'>" + level + "</span></b>";
const red = "<b><span style='color:red'>" + level + "</span></b>";
// If the feature's "difficulty" attribute is a specific value, set it a certain color
textElement.text = `The {trailName} trail has a difficulty level of ${green}.`;
return [textElement, attachmentsElement];
textElement.text = `The {trailName} trail has a difficulty level of ${purple}.`;
return [textElement, attachmentsElement];
textElement.text = `The {trailName} trail has a difficulty level of ${red}.`;
return [textElement, attachmentsElement];
textElement.text = `The {trailName} trail does not have a difficulty level assigned.`;
return [textElement, attachmentsElement];
viewElement.map = new Map({
await viewElement.viewOnReady();
// Create the Editor with the specified layer and a list of field configurations
editorComponent.layerInfos = [
// autocasts to FormTemplate
name: "disablePathNameEdit",
// autocasts to FieldElement
editableExpression: "disablePathNameEdit",
hint: "The overall condition for running/biking?",
hint: "How difficult was this trail to run/bike?",
hint: "Running or biking?",
label: "Additional comments",
// Execute each time the "Edit feature" action is clicked
// If the Editor's activeWorkflow is null, make the popup not opened
if (!editorComponent.activeWorkFlow) {
popupComponent.open = false;
// Call the Editor update feature edit workflow
editorComponent.startUpdateWorkflowAtFeatureEdit(popupComponent.selectedFeature);
editorComponent.style = "display: block;";
// Remove the editor component from the display when its state is "ready", and open the popup. The ready state indicates that the initial editor panel has loaded and is prepared for editing.
// The editor displays a panel to select a feature to update if the user "backs" out of the current edit workflow. This is not needed in this specific workflow as the feature is already selected from the popup. The "ready" state indicates that this initial editor panel is active and was activated via the "back" button. In this example, we remove the editor from the map and replace it with the popup.
() => editorComponent.state === "ready",
// Remove the editor and open the popup again
editorComponent.style = "display:none;";
popupComponent.features = features;
popupComponent.setFocus();
popupComponent.open = true;
// Event handler that fires each time a popup action is clicked
if (event.detail.action.id === "edit-this") {
// Watch when the popup is opened
() => popupComponent.open,
// Check the Editor's state, if it is currently open and editing existing features, disable popups
if (editorComponent.state === "editing-existing-feature") {
popupComponent.open = false;
// Grab the features of the popup
features = popupComponent.features;
featureLayer.on("apply-edits", () => {
// Once edits are applied to the layer, remove the Editor from the UI
editorComponent.style = "display:none;";
// Iterate through the features
features.forEach((feature) => {
// Reset the template for the feature if it was edited
feature.popupTemplate = featureLayer.featureTemplate;
// Open the popup again and reset its content after updates were made on the feature
popupComponent.features = features;
popupComponent.setFocus();
popupComponent.open = true;
// Cancel the workflow so that once edits are applied, a new popup can be displayed
editorComponent.cancelWorkflow();