<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" />
<title>FeatureTable widget with a map | Sample | ArcGIS API for JavaScript 4.18</title>
<link rel="stylesheet" href="https://js.arcgis.com/4.18/esri/themes/light/main.css" />
<script src="https://js.arcgis.com/4.18/"></script>
<style>
html,
body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
#viewDiv {
height: 50%;
width: 100%;
}
#zoom {
margin-bottom: 5px;
}
#actions {
padding: 5px;
}
.container,
#tableDiv,
#tableDiv2 {
height: 50%;
width: 100%;
}
</style>
</head>
<body>
<div id="viewDiv"></div>
<div class="container">
<div id="tableDiv"></div>
<div id="tableDiv2"></div>
</div>
<div id="actions" class="esri-widget">
<button class="esri-button" id="zoom">Zoom to selected feature(s)</button>
<button class="esri-button" id="fullextent">Full extent</button>
<button class="esri-button" id="newTable">New Table</button>
</div>
</body>
</html>
import WebMap from "https://js.arcgis.com/4.19/@arcgis/core/WebMap.js";
import MapView from "https://js.arcgis.com/4.19/@arcgis/core/views/MapView.js";
import FeatureLayer from "https://js.arcgis.com/4.19/@arcgis/core/layers/FeatureLayer.js";
import FeatureTable from "https://js.arcgis.com/4.19/@arcgis/core/widgets/FeatureTable.js";
const features = [];
const webmap = new WebMap({
portalItem: {
id: "3c245fe893234d4f85e4edaa41a9e0bf"
}
});
let view = new MapView({
container: "viewDiv",
map: webmap,
popup: {
autoOpenEnabled: false
} //disable popups
});
function createLayer(lyr, title, source) {
const tempLayer = new FeatureLayer({
title,
fields: lyr.fields.map((x) => x.clone()),
geometryType: lyr.geometryType,
renderer: lyr.renderer.clone(),
spatialReference: lyr.spatialReference.clone(),
source,
visible: false
});
return tempLayer;
}
view.when(function () {
const featureLayer = webmap.layers.getItemAt(0); //grabs the first layer in the map
featureLayer.title = "USFS Recreational areas";
// Create the feature table
const featureTable = new FeatureTable({
view: view, // required for feature highlight to work
layer: featureLayer,
// Autocast the FieldColumnConfigs
fieldConfigs: [
{
name: "RECAREANAM",
label: "Recreation area name",
direction: "asc"
},
{
name: "FORESTNAME",
label: "Forest name"
},
{
name: "OPENSTATUS",
label: "Open status"
},
{
name: "OPEN_SEASO",
label: "Season begins"
},
{
name: "RECAREADES",
label: "Recreation description"
},
{
name: "RESTRICTIO",
label: "Restrictions"
}
],
container: document.getElementById("tableDiv")
});
// Add buttons to the mapView
view.ui.add(document.getElementById("actions"), "top-right");
// Listen for the table's selection-change event
featureTable.on("selection-change", function (changes) {
// If the selection is removed, remove the feature from the array
changes.removed.forEach(function (item) {
const data = features.find(function (data) {
return data.feature === item.feature;
});
if (data) {
features.splice(features.indexOf(data), 1);
}
});
// If the selection is added, push all added selections to array
changes.added.forEach(function (item) {
const feature = item.feature;
features.push({
feature: feature
});
});
});
// Listen for the click on the view and select any associated row in the table
view.on("immediate-click", function (event) {
view.hitTest(event).then(function (response) {
const candidate = response.results.find(function (result) {
return (
result.graphic &&
result.graphic.layer &&
result.graphic.layer === featureLayer
);
});
// Select the rows of the clicked feature
candidate && featureTable.selectRows(candidate.graphic);
});
});
const zoomBtn = document.getElementById("zoom");
const fullExtentBtn = document.getElementById("fullextent");
const btnTable = document.getElementById("newTable");
// Wire up button click event listeners
zoomBtn.addEventListener("click", zoomToSelectedFeature);
fullExtentBtn.addEventListener("click", fullExtent);
btnTable.addEventListener("click", () => {
// do something here
const source = features.map((x) => x.feature);
const layer = createLayer(featureLayer, "Copy Layer", source);
const fTable = new FeatureTable({
view: view, // required for feature highlight to work
layer: layer,
// Autocast the FieldColumnConfigs
fieldConfigs: [
{
name: "RECAREANAM",
label: "Recreation area name",
direction: "asc"
},
{
name: "FORESTNAME",
label: "Forest name"
},
{
name: "OPENSTATUS",
label: "Open status"
},
{
name: "OPEN_SEASO",
label: "Season begins"
},
{
name: "RECAREADES",
label: "Recreation description"
},
{
name: "RESTRICTIO",
label: "Restrictions"
}
],
container: document.getElementById("tableDiv2")
});
});
// fires when "Zoom to selected feature(s)" button is clicked
function zoomToSelectedFeature() {
// Create a query off of the feature layer
const query = featureLayer.createQuery();
// Iterate through the features and grab the feature's objectID
const featureIds = features.map(function (result) {
return result.feature.getAttribute(featureLayer.objectIdField);
});
// Set the query's objectId
query.objectIds = featureIds;
// Make sure to return the geometry to zoom to
query.returnGeometry = true;
// Call queryFeatures on the feature layer and zoom to the resulting features
featureLayer.queryFeatures(query).then(function (results) {
view.goTo(results.features).catch(function (error) {
if (error.name != "AbortError") {
console.error(error);
}
});
});
}
// Fires when "Full extent" button is clicked
function fullExtent() {
// Zooms to the full extent of the feature layer
view.goTo(featureLayer.fullExtent).catch(function (error) {
if (error.name != "AbortError") {
console.error(error);
}
});
}
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.