arcgis-tables-forms
Skill0 starsChanged 7 months agoMITView on GitHub
Configure FeatureTable for tabular data display and FormTemplate with input elements for feature editing forms. Use when adding spreadsheet-style data grids, building attribute edit forms, configuring form input types and validation, or surfacing related records in forms.
1 other project uses a version of this.
Adopted by
Most recently taken up by
- geoai-latam/SKILL_JS5_ARCGIStheir own version, first seen Nov 8, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- geoai-latam/SKILL_JS5_ARCGIS★ 1same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository47 other files it gives its agents.
- AGENTS.mdAGENTS.md
- skills/arcgis-ai-components/AGENTS.mdAGENTS.md
- skills/arcgis-authentication/AGENTS.mdAGENTS.md
- skills/arcgis-charts/AGENTS.mdAGENTS.md
- skills/arcgis-coding-components/AGENTS.mdAGENTS.md
- skills/arcgis-core-maps/AGENTS.mdAGENTS.md
- skills/arcgis-editing/AGENTS.mdAGENTS.md
- skills/arcgis-embeddable-maps/AGENTS.mdAGENTS.md
- skills/arcgis-interaction/AGENTS.mdAGENTS.md
- skills/arcgis-layers/AGENTS.mdAGENTS.md
- skills/arcgis-starter-app/AGENTS.mdAGENTS.md
- skills/arcgis-visualization/AGENTS.mdAGENTS.md
- skills/arcgis-widgets-ui/AGENTS.mdAGENTS.md
- arcgis-3d-layersSkill
- arcgis-advanced-layersSkill
- arcgis-ai-componentsSkill
- arcgis-arcadeSkill
- arcgis-authenticationSkill
- arcgis-chartsSkill
- arcgis-cim-symbolsSkill
- arcgis-coding-componentsSkill
- arcgis-coordinates-projectionSkill
- arcgis-core-mapsSkill
- arcgis-core-utilitiesSkill
- arcgis-custom-renderingSkill
- arcgis-editingSkill
- arcgis-embeddable-mapsSkill
- arcgis-feature-effectsSkill
- arcgis-geometry-operationsSkill
- arcgis-imagerySkill
- arcgis-interactionSkill
- arcgis-knowledge-graphsSkill
- arcgis-layersSkill
- arcgis-map-toolsSkill
- arcgis-performanceSkill
- arcgis-popup-templatesSkill
- arcgis-portal-contentSkill
- arcgis-rest-servicesSkill
- arcgis-scene-environmentSkill
- arcgis-smart-mappingSkill
- arcgis-spatial-analysisSkill
- arcgis-starter-appSkill
- arcgis-time-animationSkill
- arcgis-utility-networksSkill
- arcgis-visualizationSkill
- arcgis-widgets-advancedSkill
- arcgis-widgets-uiSkill
The file
We split this skill into the rules it gives an agent
2 rules. About 0 are common, 2 are distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 8
Use this skill for configuring FeatureTable components/widgets and FormTemplate with various input elements.
- Distinctive: line 931
Layer must be editable: Check capabilities before enabling editing.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
ArcGIS Tables & Forms
Use this skill for configuring FeatureTable components/widgets and FormTemplate with various input elements.
Import Patterns
Direct ESM Imports
import FeatureTable from "@arcgis/core/widgets/FeatureTable.js";
import FeatureForm from "@arcgis/core/widgets/FeatureForm.js";
import FormTemplate from "@arcgis/core/form/FormTemplate.js";
import FieldColumnTemplate from "@arcgis/core/widgets/FeatureTable/support/FieldColumnTemplate.js";Dynamic Imports (CDN)
const FeatureTable = await $arcgis.import(
"@arcgis/core/widgets/FeatureTable.js",
);
const FeatureForm = await $arcgis.import("@arcgis/core/widgets/FeatureForm.js");
const FormTemplate = await $arcgis.import("@arcgis/core/form/FormTemplate.js");
const FieldColumnTemplate = await $arcgis.import(
"@arcgis/core/widgets/FeatureTable/support/FieldColumnTemplate.js",
);Note: The examples in this skill use Direct ESM imports. For CDN usage, replace
import X from "path"withconst X = await $arcgis.import("path").
FeatureTable Component
Basic Usage
<arcgis-map item-id="YOUR_WEBMAP_ID">
<arcgis-zoom slot="top-left"></arcgis-zoom>
</arcgis-map>
<arcgis-feature-table reference-element="arcgis-map"></arcgis-feature-table>
<script type="module">
const map = document.querySelector("arcgis-map");
const table = document.querySelector("arcgis-feature-table");
const view = await map.view;
await view.when();
const layer = view.map.layers.find((l) => l.type === "feature");
table.layer = layer;
</script>Key Properties
| Property | Type | Default | Description |
layer | FeatureLayer | The layer to display | |
attribute-table-template | AttributeTableTemplate | Table configuration (new in 5.0) | |
editing-enabled | boolean | false | Enable inline editing |
filter-by-selection-enabled | boolean | false | Filter by selected features |
highlight-disabled | boolean | false | Disable row highlighting |
hide-header | boolean | false | Hide the table header |
hide-menu | boolean | false | Hide the table menu |
hide-selection-column | boolean | false | Hide the selection column |
multiple-selection-disabled | boolean | false | Disable multi-row selection |
multiple-sort-enabled | boolean | false | Enable multi-column sorting |
page-size | number | Rows per page | |
auto-save-disabled | boolean | false | Disable auto-saving edits |
definition-expression | string | Filter expression | |
time-zone | string | Time zone for dates |
Hide Menu Items
| Property | Description |
hide-menu-items-clear-selection | Hide clear selection menu item |
hide-menu-items-delete-selection | Hide delete selection menu item |
hide-menu-items-export-selection-to-csv | Hide export to CSV menu item |
hide-menu-items-refresh-data | Hide refresh data menu item |
hide-menu-items-toggle-columns | Hide toggle columns menu item |
hide-menu-items-zoom-to-selection | Hide zoom to selection menu item |
Key Events
| Event | Description |
arcgisSelectionChange | Fires when row selection changes |
arcgisCellClick | Fires when a cell is clicked |
arcgisCellKeydown | Fires on keyboard interaction in a cell |
arcgisCellPointerover | Fires when pointer enters a cell |
arcgisCellPointerout | Fires when pointer leaves a cell |
arcgisColumnReorder | Fires when columns are reordered |
arcgisPropertyChange | Fires when a property changes |
arcgisReady | Fires when the component is ready |
Component with Configuration
<arcgis-feature-table
reference-element="arcgis-map"
editing-enabled
multiple-sort-enabled
page-size="50"
hide-menu-items-delete-selection
></arcgis-feature-table>
<script type="module">
const table = document.querySelector("arcgis-feature-table");
table.layer = featureLayer;
table.addEventListener("arcgisSelectionChange", (event) => {
console.log("Selection changed");
});
</script>FeatureTable Widget (Core API)
Basic Widget
import FeatureTable from "@arcgis/core/widgets/FeatureTable.js";
const featureTable = new FeatureTable({
view: view,
layer: featureLayer,
container: "tableDiv",
});Configured Widget
const featureTable = new FeatureTable({
view: view,
layer: featureLayer,
container: "tableDiv",
editingEnabled: true,
multiSortEnabled: true,
highlightEnabled: true,
attachmentsEnabled: true,
relatedRecordsEnabled: true,
pageSize: 50,
filterGeometry: view.extent,
});Column Templates
import FieldColumnTemplate from "@arcgis/core/widgets/FeatureTable/support/FieldColumnTemplate.js";
const featureTable = new FeatureTable({
view: view,
layer: featureLayer,
tableTemplate: {
columnTemplates: [
new FieldColumnTemplate({
fieldName: "name",
label: "Name",
initialSortPriority: 0,
direction: "asc",
}),
new FieldColumnTemplate({
fieldName: "status",
label: "Status",
}),
new FieldColumnTemplate({
fieldName: "value",
label: "Value ($)",
textAlign: "right",
}),
],
},
});FieldColumnTemplate Properties
| Property | Type | Description |
fieldName | string | Field to display |
label | string | Column header text |
editable | boolean | Allow editing |
visible | boolean | Column visibility |
frozen | boolean | Freeze column to left |
frozenToEnd | boolean | Freeze column to right |
resizable | boolean | Allow column resizing |
autoWidth | boolean | Auto-size column width |
width | number | Column width in pixels |
textAlign | string | Text alignment |
textWrap | boolean | Wrap text in cells |
initialSortPriority | number | Sort priority |
Group Column Template
import GroupColumnTemplate from "@arcgis/core/widgets/FeatureTable/support/GroupColumnTemplate.js";
const featureTable = new FeatureTable({
view: view,
layer: featureLayer,
tableTemplate: {
columnTemplates: [
new GroupColumnTemplate({
label: "Location",
columnTemplates: [
new FieldColumnTemplate({ fieldName: "city", label: "City" }),
new FieldColumnTemplate({ fieldName: "state", label: "State" }),
new FieldColumnTemplate({ fieldName: "country", label: "Country" }),
],
}),
new GroupColumnTemplate({
label: "Details",
columnTemplates: [
new FieldColumnTemplate({ fieldName: "name", label: "Name" }),
new FieldColumnTemplate({ fieldName: "type", label: "Type" }),
],
}),
],
},
});AttributeTableTemplate (New in 5.0)
Configure table display using AttributeTableTemplate, which can be set on a layer or on the feature table component.
import AttributeTableTemplate from "@arcgis/core/tables/AttributeTableTemplate.js";
const tableTemplate = new AttributeTableTemplate({
elements: [
{
type: "field",
fieldName: "name",
label: "Name",
},
{
type: "field",
fieldName: "status",
label: "Status",
},
{
type: "group",
label: "Location",
elements: [
{ type: "field", fieldName: "city", label: "City" },
{ type: "field", fieldName: "state", label: "State" },
],
},
],
orderByFields: [{ field: "name", order: "asc" }],
});
// Set on the feature table component
const table = document.querySelector("arcgis-feature-table");
table.attributeTableTemplate = tableTemplate;
// Or set on the layer
featureLayer.attributeTableTemplate = tableTemplate;AttributeTableTemplate Element Types
| Type | Class | Description |
field | AttributeTableFieldElement | Individual field column |
group | AttributeTableGroupElement | Group of columns |
relationship | AttributeTableRelationshipElement | Related records |
attachment | AttributeTableAttachmentElement | Attachment column |
Selection and Highlighting
Programmatic Selection
// Select by ObjectIDs
featureTable.highlightIds.add(123);
featureTable.highlightIds.addMany([124, 125, 126]);
// Clear selection
featureTable.highlightIds.removeAll();
// Select from query
const results = await featureLayer.queryObjectIds({
where: "status = 'active'",
});
featureTable.highlightIds.addMany(results);Watch Selection Changes
featureTable.highlightIds.on("change", (event) => {
console.log("Added IDs:", event.added);
console.log("Removed IDs:", event.removed);
const selectedIds = featureTable.highlightIds.toArray();
console.log("All selected:", selectedIds);
});Sync with Map Selection
// Map click selects in table
view.on("click", async (event) => {
const response = await view.hitTest(event);
const feature = response.results.find(
(r) => r.graphic.layer === featureLayer,
);
if (feature) {
featureTable.highlightIds.removeAll();
featureTable.highlightIds.add(feature.graphic.attributes.OBJECTID);
}
});
// Table selection highlights on map
let highlightHandle;
featureTable.highlightIds.on("change", async () => {
const layerView = await view.whenLayerView(featureLayer);
if (highlightHandle) {
highlightHandle.remove();
}
const objectIds = featureTable.highlightIds.toArray();
if (objectIds.length > 0) {
highlightHandle = layerView.highlight(objectIds);
}
});Filter and Refresh
// Filter by geometry
featureTable.filterGeometry = view.extent;
// Filter by expression
featureTable.layer.definitionExpression = "category = 'A'";
// Refresh data
featureTable.refresh();
// Clear filters
featureTable.filterGeometry = null;
featureTable.layer.definitionExpression = null;FormTemplate
Configure edit forms for features.
Basic FormTemplate
import FormTemplate from "@arcgis/core/form/FormTemplate.js";
const formTemplate = new FormTemplate({
title: "Edit Feature",
description: "Update the feature attributes",
elements: [
{
type: "field",
fieldName: "name",
label: "Name",
},
{
type: "field",
fieldName: "category",
label: "Category",
},
{
type: "field",
fieldName: "description",
label: "Description",
},
],
});
featureLayer.formTemplate = formTemplate;FormTemplate Properties
| Property | Type | Description |
title | string | Form title |
description | string | Form description |
elements | FormElement[] | Array of form elements |
expressionInfos | ExpressionInfo[] | Arcade expression definitions |
preserveFieldValuesWhenHidden | boolean | Keep hidden field values |
Form Element Types
| Type | Description |
field | FieldElement - Edit a specific field |
group | GroupElement - Group of elements |
text | TextElement - Static text/HTML content |
relationship | RelationshipElement - Related records |
attachment | AttachmentElement - File attachments |
Field Elements
{
type: "field",
fieldName: "name",
label: "Name",
description: "Enter the feature name",
hint: "Required field",
requiredExpression: "always-required",
editableExpression: "$feature.status != 'locked'",
visibilityExpression: "$feature.type != 'hidden'"
}Group Elements
{
type: "group",
label: "Location",
description: "Address information",
initialState: "collapsed", // expanded, collapsed
elements: [
{ type: "field", fieldName: "address", label: "Address" },
{ type: "field", fieldName: "city", label: "City" },
{ type: "field", fieldName: "state", label: "State" }
]
}Text Elements
{
type: "text",
text: "<h3>Important Instructions</h3><p>Please fill out all required fields.</p>"
}Relationship Elements
{
type: "relationship",
relationshipId: 0,
label: "Related Inspections",
description: "View and manage related inspection records",
displayCount: 5,
orderByFields: [{
field: "inspection_date",
order: "desc"
}],
editableExpression: "true"
}Input Types
TextBox Input
{
type: "field",
fieldName: "name",
label: "Name",
input: {
type: "text-box",
maxLength: 100,
minLength: 1
}
}TextArea Input
{
type: "field",
fieldName: "description",
label: "Description",
input: {
type: "text-area",
maxLength: 1000,
minLength: 0
}
}ComboBox Input
{
type: "field",
fieldName: "category",
label: "Category",
input: {
type: "combo-box",
showNoValueOption: true,
noValueOptionLabel: "Select a category..."
}
}
// Works with coded value domains - values auto-populate from domainRadio Buttons Input
{
type: "field",
fieldName: "priority",
label: "Priority",
input: {
type: "radio-buttons",
showNoValueOption: false
}
}Switch Input
{
type: "field",
fieldName: "is_active",
label: "Active",
input: {
type: "switch",
offValue: 0,
onValue: 1
}
}DatePicker Input
{
type: "field",
fieldName: "start_date",
label: "Start Date",
input: {
type: "date-picker",
min: new Date("2020-01-01"),
max: new Date("2030-12-31"),
includeTime: false
}
}DateTimePicker Input
{
type: "field",
fieldName: "event_datetime",
label: "Event Date/Time",
input: {
type: "datetime-picker",
min: new Date("2020-01-01T00:00:00"),
max: new Date("2030-12-31T23:59:59"),
includeTime: true
}
}TimePicker Input
{
type: "field",
fieldName: "event_time",
label: "Event Time",
input: {
type: "time-picker"
}
}Barcode Scanner Input
{
type: "field",
fieldName: "barcode",
label: "Barcode",
input: {
type: "barcode-scanner"
}
}Expression-Based Configuration
Visibility Expressions
const formTemplate = new FormTemplate({
expressionInfos: [
{
name: "show-commercial-fields",
expression: "$feature.property_type == 'commercial'",
},
{
name: "show-residential-fields",
expression: "$feature.property_type == 'residential'",
},
],
elements: [
{ type: "field", fieldName: "property_type", label: "Property Type" },
{
type: "group",
label: "Commercial Details",
visibilityExpression: "show-commercial-fields",
elements: [
{ type: "field", fieldName: "business_name", label: "Business Name" },
{ type: "field", fieldName: "num_employees", label: "Employees" },
],
},
{
type: "group",
label: "Residential Details",
visibilityExpression: "show-residential-fields",
elements: [
{ type: "field", fieldName: "num_bedrooms", label: "Bedrooms" },
{ type: "field", fieldName: "num_bathrooms", label: "Bathrooms" },
],
},
],
});Required and Editable Expressions
// Conditionally required
{
type: "field",
fieldName: "inspection_notes",
label: "Inspection Notes",
requiredExpression: "notes-required"
}
// Conditionally editable
{
type: "field",
fieldName: "approved_by",
label: "Approved By",
editableExpression: "is-pending"
}FeatureForm Widget
import FeatureForm from "@arcgis/core/widgets/FeatureForm.js";
const featureForm = new FeatureForm({
container: "formDiv",
layer: featureLayer,
formTemplate: formTemplate,
});
// Set feature to edit
featureForm.feature = selectedGraphic;
// Listen for submit
featureForm.on("submit", () => {
if (featureForm.feature) {
const updated = featureForm.getValues();
featureLayer.applyEdits({
updateFeatures: [
{
attributes: {
...featureForm.feature.attributes,
...updated,
},
geometry: featureForm.feature.geometry,
},
],
});
}
});
// Handle value changes
featureForm.on("value-change", (event) => {
console.log(`${event.fieldName} changed to ${event.value}`);
});Complete Example: FeatureTable with Map
<!DOCTYPE html>
<html>
<head>
<script src="https://js.arcgis.com/5.0/"></script>
<script
type="module"
src="https://js.arcgis.com/5.0/map-components/"
></script>
<style>
html,
body {
height: 100%;
margin: 0;
}
#container {
display: flex;
flex-direction: column;
height: 100%;
}
arcgis-map {
flex: 1;
}
#tableDiv {
height: 300px;
}
</style>
</head>
<body>
<div id="container">
<arcgis-map
basemap="streets-navigation-vector"
center="-118.805,34.027"
zoom="11"
>
<arcgis-zoom slot="top-left"></arcgis-zoom>
</arcgis-map>
<arcgis-feature-table
reference-element="arcgis-map"
editing-enabled
></arcgis-feature-table>
</div>
<script type="module">
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 featureLayer = new FeatureLayer({
url: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/FeatureServer/0",
});
mapElement.map.add(featureLayer);
const table = document.querySelector("arcgis-feature-table");
table.layer = featureLayer;
// Highlight table selection on map
let highlightHandle;
table.addEventListener("arcgisSelectionChange", async () => {
const layerView = await view.whenLayerView(featureLayer);
if (highlightHandle) {
highlightHandle.remove();
}
const objectIds = table.highlightIds?.toArray();
if (objectIds && objectIds.length > 0) {
highlightHandle = layerView.highlight(objectIds);
}
});
</script>
</body>
</html>Complete Example: FormTemplate with Editor
<!DOCTYPE html>
<html>
<head>
<script src="https://js.arcgis.com/5.0/"></script>
<script
type="module"
src="https://js.arcgis.com/5.0/map-components/"
></script>
<style>
html,
body {
height: 100%;
margin: 0;
}
</style>
</head>
<body>
<arcgis-map
basemap="streets-navigation-vector"
center="-118.805,34.027"
zoom="13"
>
<arcgis-zoom slot="top-left"></arcgis-zoom>
<arcgis-editor slot="top-right"></arcgis-editor>
</arcgis-map>
<script type="module">
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: "Property Information",
description: "Enter property details",
preserveFieldValuesWhenHidden: true,
expressionInfos: [
{
name: "is-commercial",
expression: "$feature.type == 'commercial'",
},
],
elements: [
{
type: "field",
fieldName: "name",
label: "Property Name",
input: { type: "text-box", maxLength: 100 },
},
{
type: "field",
fieldName: "type",
label: "Property Type",
input: { type: "combo-box" },
},
{
type: "group",
label: "Commercial Details",
visibilityExpression: "is-commercial",
elements: [
{
type: "field",
fieldName: "business_type",
label: "Business Type",
},
{ type: "field", fieldName: "sqft", label: "Square Footage" },
],
},
{
type: "field",
fieldName: "inspection_date",
label: "Last Inspection",
input: { type: "date-picker" },
},
{
type: "field",
fieldName: "notes",
label: "Notes",
input: { type: "text-area", maxLength: 500 },
},
],
},
},
];
</script>
</body>
</html>Reference Samples
feature-table- FeatureTable component usagewidgets-featuretable-editing- Editing with FeatureTablewidgets-featuretable-map- FeatureTable with map integrationwidgets-featuretable-relates- FeatureTable with related recordsediting-groupedfeatureform- Grouped feature form layoutediting-featureform-fieldvisibility- Controlling field visibility in forms
Common Pitfalls
Field names must match:
fieldNamemust exactly match the layer field name (case-sensitive).// Layer has field "PropertyName" { fieldName: "PropertyName"; } // Correct { fieldName: "propertyname"; } // Wrong - case sensitiveCoded value domains: ComboBox automatically populates from domain values.
// If field has coded value domain, values come from domain { type: "field", fieldName: "status", input: { type: "combo-box" } } // Dropdown shows domain values automatically - no manual options neededExpression names: Reference expressions by name string, not expression text.
expressionInfos: [{ name: "my-expr", expression: "..." }], elements: [{ visibilityExpression: "my-expr" // String reference to name }]Layer must be editable: Check capabilities before enabling editing.
await layer.load(); if (layer.capabilities?.editing?.supportsUpdateByOthers) { featureTable.editingEnabled = true; }Container size: FeatureTable widget needs explicit height on its container.
#tableDiv { height: 400px; /* Required - table won't render without explicit height */ width: 100%; }- Highlight ID type:
highlightIdsexpects ObjectID numbers, not strings.featureTable.highlightIds.add(123); // Correct - number featureTable.highlightIds.add("123"); // Wrong - string
Related Skills
- See
arcgis-editingfor Editor configuration, applyEdits, and versioning. - See
arcgis-popup-templatesfor PopupTemplate configuration. - See
arcgis-interactionfor hit testing and map selection. - See
arcgis-layersfor FeatureLayer configuration.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

