I am working with ArcGIS API for Javascript 4.9. I want to create a simple map view and display a table under it.
I am using this script as a base https://developers.arcgis.com/javascript/latest/sample-code/sandbox/index.html?sample=highlight-features-by-geometry
Unlike this example, I don't need to select anything, just want to display table under the map showing all data from the layer and be able to edit this table.
My modified script is below. I don't know how to set 'data' variable to point it to the feature layer that I am using.
My script:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<title>Display Table</title>
<link rel="stylesheet" href="https://js.arcgis.com/4.9/esri/css/main.css">
<script src="https://js.arcgis.com/4.9/"></script>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
overflow: hidden;
}
#info,
#gridDisplay {
position: absolute;
bottom: 0;
left: 0;
height: 35%;
background-color: white;
border-color: grey;
width: 100%;
font-family: "Avenir Next W00", "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
}
#gridDisplay {
z-index: 80;
}
#info {
z-index: 90;
font-size: 16px;
padding-left: 20px;
}
#info * {
padding-right: 20px;
}
.info {
line-height: 20px;
padding-left: 5px ! important;
}
.dgrid-header,
.dgrid-header-row {
background-color: #eee;
color: #57585A;
}
.dgrid-row-even {
background-color: #F7F8F8;
}
.dgrid-row-odd {
background-color: #EFEFEF;
}
.dgrid-selected {
background: #B4DAF5;
}
.dgrid-row {
border: none
}
</style>
<script>
require([
"esri/Map",
"esri/WebMap",
"esri/views/MapView",
"esri/layers/FeatureLayer",
"esri/widgets/Legend",
"esri/widgets/Expand",
"dgrid/OnDemandGrid",
"dojo/store/Memory",
"dstore/legacy/StoreAdapter",
"dgrid/Selection"
],
function(
Map, WebMap, MapView, FeatureLayer,
Legend, Expand,
OnDemandGrid, Memory, StoreAdapter, Selection
) {
let map, view, fLayer, grid;
const gridDiv = document.getElementById("grid");
const infoDiv = document.getElementById("info");
// create new map, view and flayer
setupTheView();
const gridFields = ["__OBJECTID", "WAL_NAME", "REGION", "WAL_ZONE", "REGION_WAL", "WAL_Value", "SWAL_Value"
];
let dataStore = new StoreAdapter({
objectStore: new Memory({
idProperty: "__OBJECTID"
})
});
var sortAttr = [{
attribute: "name",
descending: true
}];
grid = new OnDemandGrid({
store: Memory({
idProperty: "OBJECTID"
}),
columns: {
WAL_NAME: "WAL_NAME",
REGION: "REGION",
WAL_Value: "WAL_Value",
SWAL_Value: "SWAL_Value",
},
loadingMessage: "Loading data...",
noDataMessage: "No results found.",
sort: sortAttr
}, "grid");
// how to set up this data variable to point back to my feature layer??
data = ????
grid.store.setData(data);
grid.refresh();
function setupTheView() {
map = new Map({
basemap: "topo"
});
view = new MapView({
container: "viewDiv", // Reference to the scene div created in step 5
map: map, // Reference to the map object created before the scene
zoom: 5, // Sets zoom level based on level of detail (LOD)
center: [146, -25], // Sets center point of view using longitude,latitude
//popup: {dockEnabled: false}
});
fLayer = new FeatureLayer({
url: "https://--------/arcgis/rest/services/GCX/QFESAlertLevels_GCX/FeatureServer/1",
outFields: ["*"],
title: "WAL"
//popupTemplate: popupReport
});
map.layers.add(fLayer);
const legendExpand = new Expand({
view: view,
content: new Legend({
view: view,
style: "card"
})
});
view.ui.add(legendExpand, "top-left");
view.popup.watch("visible", function(newValue) {
if (newValue) {
clearUpSelection();
}
});
}
function errorCallback(error) {
console.log("error:", error)
}
});
</script>
</head>
<body>
<div id="viewDiv">
<div>title="Display Table"
</div>
<div id="info">
<span class="info">
<b>Table</b>
</span>
<br />
</div>
<div id="grid"></div>
</div>
</body>
</html>
1 Answer 1
You need to create an array of objects, where each object contains the attributes for each feature in the layer:
data = [{
field0 : value, //Feature 0
field1: value
},
field0: value, //Feature 1
field1: value
}]
You can get the fields and features from a layer using queryFeatures()
, where layer is layer variable:
var layer = new FeatureLayer({
portalItem: {
id: '87eefb4c13c242349af2cc2b7e4df19b'
},
title: 'Some Tile'
})
layer.queryFeatures()
.then(function (response) {
console.log(response)
//Map the fields to dgrid format.
var QueryFields = array.map(response.fields, function (field) {
return {
field: field.name,
label: field.alias
}
})
var TableFeatures = []
array.forEach(response.features, function (feature) {
var TableAttributes = {}
var TableFields = Object.keys(feature.attributes)
for (var i = 0; i < TableFields.length; i++) {
TableAttributes[TableFields[i]] = feature.attributes[TableFields[i]]
}
TableFeatures.push(TableAttributes)
})
var DataStore = new Memory({
data: TableFeatures,
idProperty: "OBJECTID",
})
var grid = new (declare([OnDemandGrid, Selection, ColumnHider, ColumnResizer,
ColumnReorder]))({
bufferRows: Infinity,
selectionMode: 'extended',
columns: QueryFields
}, divID)
grid.set('collection', DataStore)
Also, I believe "dojo/store/Memory"
is now "dstore/Memory"
and OnDemandGrid
needs to be set with grid.set('collection, yourStore)
.
Here is the code to a Feature Table Widget I'm working on and here is an example of the working code.