arcgis-tables-forms について
ArcGIS Maps SDK for JavaScriptでフィーチャーテーブルや属性編集フォームを作る開発者向けのスキルです。テーブル設定、選択、列構成、フォーム入力、式による動作制御を解説します。
主な機能
- 01FeatureTable の列と表示の設定
- 02レコードのインライン編集と選択管理
- 03多様な入力形式によるフォーム作成
- 04フィールドのグループ化と関連レコード表示
- 05式による表示制御と検証
活用シーン
- 01レイヤー用の編集可能な属性テーブル作成
- 02構造化されたフィーチャー編集フォームの設計
- 03テーブル選択とマップ上のフィーチャーの同期
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ saschabrunnerch/ arcgis-maps-sdk-js-ai-context --skill arcgis-tables-formsインストール後、Claude Code で/arcgis-tables-formsを入力して読み込まれたか確認します。
詳細
ArcGIS テーブルとフォーム
FeatureTable コンポーネント/ウィジェットや、さまざまな入力要素を含む FormTemplate を設定する場合に、このスキルを使用します。
インポートパターン
ESM の直接インポート
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";
動的インポート(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",
);
注: このスキルの例では、ESM の直接インポートを使用しています。CDN を使用する場合は、
import X from "path"をconst X = await $arcgis.import("path")に置き換えてください。
FeatureTable コンポーネント
基本的な使い方
<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>
主なプロパティ
| プロパティ | 型 | デフォルト | 説明 |
|---|---|---|---|
layer | FeatureLayer | 表示するレイヤー | |
attribute-table-template | AttributeTableTemplate | テーブルの設定(5.0 で追加) | |
editing-enabled | boolean | false | インライン編集を有効にする |
filter-by-selection-enabled | boolean | false | 選択したフィーチャでフィルターする |
highlight-disabled | boolean | false | 行のハイライトを無効にする |
hide-header | boolean | false | テーブルヘッダーを非表示にする |
hide-menu | boolean | false | テーブルメニューを非表示にする |
hide-selection-column | boolean | false | 選択列を非表示にする |
multiple-selection-disabled | boolean | false | 複数行の選択を無効にする |
multiple-sort-enabled | boolean | false | 複数列の並べ替えを有効にする |
page-size | number | 1 ページあたりの行数 | |
auto-save-disabled | boolean | false | 編集内容の自動保存を無効にする |
definition-expression | string | フィルター式 | |
time-zone | string | 日付のタイムゾーン |
メニュー項目を非表示にする
| プロパティ | 説明 |
|---|---|
hide-menu-items-clear-selection | 選択解除のメニュー項目を非表示にする |
hide-menu-items-delete-selection | 選択削除のメニュー項目を非表示にする |
hide-menu-items-export-selection-to-csv | CSV にエクスポートするメニュー項目を非表示にする |
hide-menu-items-refresh-data | データ更新のメニュー項目を非表示にする |
hide-menu-items-toggle-columns | 列の切り替えメニュー項目を非表示にする |
hide-menu-items-zoom-to-selection | 選択範囲にズームするメニュー項目を非表示にする |
主なイベント
| イベント | 説明 |
|---|---|
arcgisSelectionChange | 行の選択が変更されたときに発生します |
arcgisCellClick | セルがクリックされたときに発生します |
arcgisCellKeydown | セルでキーボード操作が行われたときに発生します |
arcgisCellPointerover | ポインターがセルに入ったときに発生します |
arcgisCellPointerout | ポインターがセルから出たときに発生します |
arcgisColumnReorder | 列の順序が変更されたときに発生します |
arcgisPropertyChange | プロパティが変更されたときに発生します |
arcgisReady | コンポーネントの準備ができたときに発生します |
設定を使用したコンポーネント
<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 ウィジェット(Core API)
基本的なウィジェット
import FeatureTable from "@arcgis/core/widgets/FeatureTable.js";
const featureTable = new FeatureTable({
view: view,
layer: featureLayer,
container: "tableDiv",
});
設定済みのウィジェット
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,
});
列テンプレート
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 のプロパティ
| プロパティ | 型 | 説明 |
|---|---|---|
fieldName | string | 表示するフィールド |
label | string | 列ヘッダーのテキスト |
editable | boolean | 編集を許可する |
visible | boolean | 列の表示状態 |
frozen | boolean | 列を左側に固定 |
frozenToEnd | boolean | 列を右側に固定 |
resizable | boolean | 列のサイズ変更を許可する |
autoWidth | boolean | 列幅を自動調整する |
width | number | 列幅(ピクセル単位) |
textAlign | string | テキストの配置 |
textWrap | boolean | セル内のテキストを折り返す |
initialSortPriority | number | 初期の並べ替え優先度 |
グループ列テンプレート
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(5.0 で新登場)
AttributeTableTemplate を使用してテーブルの表示を設定します。レイヤーまたはフィーチャテーブルコンポーネントに設定できます。
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 の要素タイプ
| タイプ | クラス | 説明 |
|---|---|---|
field | AttributeTableFieldElement | 個別のフィールド列 |
group | AttributeTableGroupElement | 列のグループ |
relationship | AttributeTableRelationshipElement | 関連レコード |
attachment | AttributeTableAttachmentElement | 添付ファイル列 |
選択とハイライト表示
プログラムによる選択
// 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);
選択の変更を監視する
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);
});
マップの選択と同期する
// 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 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
フィーチャの編集フォームを設定します。
基本的な 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 のプロパティ
| プロパティ | 型 | 説明 |
|---|---|---|
title | string | フォームのタイトル |
description | string | フォームの説明 |
elements | FormElement[] | フォーム要素の配列 |
expressionInfos | ExpressionInfo[] | Arcade 式の定義 |
preserveFieldValuesWhenHidden | boolean | 非表示のフィールド値を保持する |
フォーム要素のタイプ
| タイプ | 説明 |
|---|---|
field | FieldElement - 特定のフィールドを編集する |
group | GroupElement - 要素のグループ |
text | TextElement - 静的なテキスト/HTML コンテンツ |
relationship | RelationshipElement - 関連レコード |
attachment | AttachmentElement - ファイル添付 |
フィールド要素
{
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'"
}
グループ要素
{
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" }
]
}
テキスト要素
{
type: "text",
text: "<h3>Important Instructions</h3><p>Please fill out all required fields.</p>"
}
リレーションシップ要素
{
type: "relationship",
relationshipId: 0,
label: "Related Inspections",
description: "View and manage related inspection records",
displayCount: 5,
orderByFields: [{
field: "inspection_date",
order: "desc"
}],
editableExpression: "true"
}
入力タイプ
テキストボックス入力
{
type: "field",
fieldName: "name",
label: "Name",
input: {
type: "text-box",
maxLength: 100,
minLength: 1
}
}
テキストエリア入力
{
type: "field",
fieldName: "description",
label: "Description",
input: {
type: "text-area",
maxLength: 1000,
minLength: 0
}
}
コンボボックス入力
{
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 domain
ラジオボタン入力
{
type: "field",
fieldName: "priority",
label: "Priority",
input: {
type: "radio-buttons",
showNoValueOption: false
}
}
スイッチ入力
{
type: "field",
fieldName: "is_active",
label: "Active",
input: {
type: "switch",
offValue: 0,
onValue: 1
}
}
日付ピッカー入力
{
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
}
}
日時ピッカー入力
{
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
}
}
時刻ピッカー入力
{
type: "field",
fieldName: "event_time",
label: "Event Time",
input: {
type: "time-picker"
}
}
バーコードスキャナー入力
{
type: "field",
fieldName: "barcode",
label: "Barcode",
input: {
type: "barcode-scanner"
}
}
式に基づく設定
表示式
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" },
],
},
],
});
必須および編集可能の式
// 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 ウィジェット
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}`);
});
完全な例:マップを含む FeatureTable
<!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>
完全な例:Editor を含む FormTemplate
<!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>
参考サンプル
feature-table- FeatureTable コンポーネントの使用方法widgets-featuretable-editing- FeatureTable を使った編集widgets-featuretable-map- FeatureTable とマップの統合widgets-featuretable-relates- 関連レコードを含む FeatureTableediting-groupedfeatureform- グループ化されたフィーチャフォームのレイアウトediting-featureform-fieldvisibility- フォームでのフィールドの表示制御
よくある落とし穴
-
フィールド名は一致している必要があります:
fieldNameはレイヤーのフィールド名と完全に一致する必要があります(大文字と小文字を区別します)。// Layer has field "PropertyName" { fieldName: "PropertyName"; } // Correct { fieldName: "propertyname"; } // Wrong - case sensitive -
コード値ドメイン:ComboBox はドメイン値から自動的に項目を追加します。
// 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 needed -
式の名前:式のテキストではなく、名前文字列で式を参照します。
expressionInfos: [{ name: "my-expr", expression: "..." }], elements: [{ visibilityExpression: "my-expr" // String reference to name }] -
レイヤーは編集可能である必要があります:編集を有効にする前に、機能を確認してください。
await layer.load(); if (layer.capabilities?.editing?.supportsUpdateByOthers) { featureTable.editingEnabled = true; } -
コンテナーのサイズ:FeatureTable ウィジェットのコンテナーには、高さを明示的に設定する必要があります。
#tableDiv { height: 400px; /* Required - table won't render without explicit height */ width: 100%; } -
ハイライト ID の型:
highlightIdsには文字列ではなく、ObjectID の数値を指定します。featureTable.highlightIds.add(123); // Correct - number featureTable.highlightIds.add("123"); // Wrong - string
関連スキル
- Editor の構成、applyEdits、バージョン管理については、
arcgis-editingを参照してください。 - PopupTemplate の構成については、
arcgis-popup-templatesを参照してください。 - ヒットテストとマップの選択については、
arcgis-interactionを参照してください。 - FeatureLayer の構成については、
arcgis-layersを参照してください。