Hi, I'm trying to modify the Access features with pointer events sample code from the ArcGIS Developers site. I want it to work with an existing webmap and with a polygon layer instead of a line. I've run the code through ChapGPT, which had me make some changes from the original structure, but the code isn't working either way. (Feature layer url and portal item id have been removed from the code below, but both do load in codepen.)
Any help would be much appreciated.
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<title>Access features with pointer events | RH Planning Areas</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
#info {
background-color: black;
opacity: 0.75;
color: lightBlue;
font-size: 18pt;
padding: 8px;
visibility: hidden;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.29/esri/themes/light/main.css" />
<script src="https://js.arcgis.com/4.29/"></script>
<script>
require(["esri/WebMap", "esri/views/MapView", "esri/layers/FeatureLayer", "esri/symbols/SimpleFillSymbol"],
(WebMap, MapView, FeatureLayer, SimpleFillSymbol) => {
const PlanningAreasLayer = new FeatureLayer({
url: "https://.../FeatureServer/0",
outFields: ["*"]
});
const webmap = new WebMap({
portalItem: {
id: "itemID",
portal: "https://www.arcgis.com",
layers: [PlanningAreasLayer]
}
});
const view = new MapView({
container: "viewDiv",
map: webmap,
center: [-83.1563078,42.6645259],
zoom: 12,
highlightOptions: {
color: "lightBlue"
}
});
view.ui.add("info", "top-right");
view
.when()
.then(() => {
return PlanningAreasLayer.when();
})
.then((layer) => {
const renderer = layer.renderer.clone();
const fillSymbol = {
type: "simple-fill",
color: [255, 0, 255, 0], //transparent fill
outline: {
color: [255, 0, 0, 0], //red
width: 4
}
};
renderer.symbol = fillSymbol;
layer.renderer = renderer;
// Set up an event handler for pointer-down (mobile)
// and pointer-move events (mouse)
// and retrieve the screen x, y coordinates
return view.whenLayerView(layer);
})
.then((layerView) => {
view.on("pointer-move", eventHandler);
view.on("pointer-down", eventHandler);
function eventHandler(event) {
// only include graphics from PlanningAreasLayer in the hitTest
const opts = {
include: PlanningAreasLayer
}
// the hitTest() checks to see if any graphics from the PlanningAreasLayer
// intersect the x, y coordinates of the pointer
view.hitTest(event, opts).then(getGraphics);
}
let highlight, currentName;
function getGraphics(response) {
// the topmost graphic from the PlanningAreasLayer
// and display select attribute values from the
// graphic to the user
if (response.results.length) {
const graphic = response.results[0].graphic;
const attributes = graphic.attributes;
const areaName = attributes.Neighbor_1;
const mapLink = attributes.Neighborho
const id = attributes.OBJECTID;
if (highlight && currentName !== areaName) {
//Check if a highlight exists (is not null or undefined)
//Checks if the current name is not equal to the name
//If true, name has changed so highlight should be removed
//If condition is true, execute the following code
highlight.remove(); //Remove the highlight from the graphic
highlight = null; //Set the highlight variable to null
return; //Exit the current function
}
if (highlight) {
const query = layerView.createQuery();
query.where = "NAME = '" + areaName + "'";
layerView.queryObjectIds(query).then((ids) => {
if (highlight) {
highlight.remove()
}
highlight = layerView.highlight(ids);
currentName = areaName;
})
}
//diplay information about the feature
document.getElementById("info").style.visibility = "visible";
document.getElementById("name").innerHTML = areaName;
document.getElementById("link").innerHTML = mapLink;
} else {
// remove the highlight if no features are
// returned from the hitTest
if (highlight){
highlight.remove();
highlight = null;
}
document.getElementById("info").style.visibility = "hidden";
}
}
});
});
</script>
</head>
<body>
<div id="viewDiv"></div>
<div id="info">
<span id="name"></span> <br />
<span id="link"></span>
</div>
</body>
</html>
Solved! Go to Solution.
Thanks for the codepen.
A few things. First you already have the layer in your webmap. So there is no need to add another instance of it to your map. You can simply get the instance of the layer once the webmap is loaded. Then you have to set the outFields of the layer to all. I sent you the modified codepen directly.
What is the error you are getting? Looks like the query might not be running successfully just looking at your code. Here you are saying the areaName is coming from Neighbor_1 field.
const areaName = attributes.Neighbor_1;
But later you are using the following query where the field name is NAME. Which one is it?
query.where = "NAME = '" + areaName + "'";
I don't know JavaScript well so I thought I was inputting a string, not a variable with "NAME." I've changed that to "areaName" as well but I still don't get features to show on my map.
The message in the console is:
"[esri.views.2d.layers.MediaLayerView2D]" // [object Object]
{
"name": "element-load-error",
"message": "Element cannot be displayed",
"details": "[object]"
}
This error has nothing to do with the query action. The error is saying you have a MedialLayer in your app and that its media element cannot be displayed. You should remove the MediaLayer and start with a simpler app.
I turned off the media layer and now I get zero warnings or errors in the console. But I still don't get any popups either.
What exactly are you trying to do? The sample you referenced does not display popup. It rather displays just a few info in a DIV tag as user moves the mouse over the features. Can you provide a working codepen so that I can help you further?
Yes, that's what I mean by pop-up. It should display 2 attribute values and highlight the feature. Right now it does neither.
I won't be able to help without an actual reproducible case. Can you provide one?
Thanks for the codepen.
A few things. First you already have the layer in your webmap. So there is no need to add another instance of it to your map. You can simply get the instance of the layer once the webmap is loaded. Then you have to set the outFields of the layer to all. I sent you the modified codepen directly.
I just had time to look at this some more and I realized that the attributes are showing up in the info Div but the layer still isn't highlighting. Can you please help with that?