Can someone please help me understand why my highlights on mouseover are not working here? I am (slowly) working on learning the js api by cobbling together a new version of an app I made in leaflet (many years ago from the new api samples. Very interesting. I am trying to get the mouseover highlight to work as it does in that app. I know there are other things I may not be doing optimally, feel free to chime in. Eventually I want to use the reactiveUtils I think. Thanks.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>Arkansas District Finder</title>
<script src="https://js.arcgis.com/calcite-components/1.6.1/calcite.esm.js" type="module"></script>
<link rel="stylesheet" href="https://js.arcgis.com/calcite-components/1.6.1/calcite.css" />
<script src="https://js.arcgis.com/4.28/"></script>
<link rel="stylesheet" href="https://js.arcgis.com/4.28/esri/themes/light/main.css" />
</head>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
body {
display: flex;
}
calcite-loader {
align-self: center;
justify-self: center;
}
#header-title {
margin-left: 1rem;
margin-right: 1rem;
}
#info-content {
padding: 0.75rem;
}
calcite-rating {
margin-top: 0.25rem;
}
#search-container.esri-search.esri-widget {
width: 100% !important;
align-items: flex-start;
/* do not want scroll bar on panel. Clicking it makes
search suggestions disappear */
min-height: 300px;
padding: 0px;
overflow: auto;
/* overflow: hidden; */
}
button:disabled {
opacity: 0.4;
-moz-opacity: 0.4;
-webkit-opacity: 0.4;
cursor: default;
}
#info {
visibility: hidden;
}
.esri-feature {
letter-spacing: 0em;
line-height: 1.55rem;
font-feature-settings: "liga"1, "calt"0;
background: #fff;
padding: 1em;
}
</style>
<body>
<calcite-loader></calcite-loader>
<calcite-shell hidden>
<calcite-shell-panel slot="panel-start">
<calcite-panel>
<calcite-block open>
<div
style="width: 100%; background:red; color:white; max-width: 100%; display: flex; flex-direction: row; align-items: center;justify-content: center">
<h2>Arkansas District Finder</h2>
</div>
</calcite-block>
<calcite-block heading="Select Chamber" open>
<div style="width: 360px; max-width: 100%; display: flex; flex-direction: row">
<calcite-button class="esri-button style-button" id="senate" type="button" disabled>
State Senate
</calcite-button>
<calcite-button class="esri-button style-button" id="house" type="button">
State House
</calcite-button>
</div>
</calcite-block>
<calcite-block id="senBlock" heading="Search Arkansas State Senators" collapsible open>
<calcite-label>
Senators
<calcite-combobox id="senSelect" selection-mode="single" placeholder="Select a Senator">
</calcite-combobox>
</calcite-label>
</calcite-block>
<calcite-block id="repBlock" heading="Arkansas State Reps" collapsible open hidden>
<calcite-label>
Representatives
<calcite-combobox id="repSelect" selection-mode="single" placeholder="Select a Representative">
</calcite-combobox>
<calcite-label>
</calcite-block>
<calcite-block heading="Find My Districts" collapsible closed>
<div id="search-container"></div>
</calcite-block>
<calcite-block heading="Legend" collapsible open>
<div id="legend-container"></div>
</calcite-block>
</calcite-panel>
</calcite-shell-panel>
<div id="overviewDiv">
<div id="extentDiv"></div>
</div>
<div id="viewDiv"></div>
<calcite-shell-panel slot="panel-start" width-scale="s" id="info" align="center">
<calcite-panel heading="Arkansas Senate">
<calcite-card>
<img slot="thumbnail" alt="Sample image alt" src="https://placebear.com/280/200">
<span slot="title">Senator Name Here</span>
<span slot="subtitle"></span></span>
<div slot="footer-start" id="example-slotted-footer">
<calcite-chip id="badge-1" value="calcite chip" icon="check-circle" scale="s"></calcite-chip>
<calcite-chip id="badge-2" value="calcite chip" icon="globe" scale="s"></calcite-chip>
<calcite-chip id="badge-3" value="calcite chip" icon="security" scale="s"></calcite-chip>
</div>
<div slot="footer-end">
<calcite-chip id="badge-4" value="calcite chip" icon="user" scale="s"></calcite-chip>
<calcite-action scale="s" icon="ellipsis" id="example-slotted-action"></calcite-action>
</div>
</calcite-card>
</calcite-panel>
</calcite-shell-panel>
</calcite-shell>
<script>
require([
"esri/core/promiseUtils",
"esri/core/reactiveUtils",
"esri/WebMap",
"esri/views/MapView",
"esri/widgets/Home",
"esri/widgets/Features"
] , function(promiseUtils, reactiveUtils, WebMap, MapView, Home, Features){
const webmapId = new URLSearchParams(window.location.search).get("webmap")
?? "c7e90511a9094e14a6b373c5d47916f6";
// Create a Map with a basemap, to be used with in the main view
const map = new WebMap({
portalItem: {
id: webmapId
}
});
map.load()
.then(() => {
map.layers
.filter(layer => { return layer.type === 'feature' })
.map(layer => {
let featLayer = layer;
featLayer.outFields = ['*'];
return featLayer;
});
});
const view = new MapView({
container: "viewDiv",
map: map,
popupEnabled: false
});
// Provide graphic to a new instance of a Feature widget
const featuresWidget = new Features({
container: 'features-widget',
view: view
});
const popup = "<div id='features-widget'></div>"
view.ui.add(featuresWidget, "bottom-right");
view.ui.move("zoom", "top-left");
var home = new Home({
view: view
});
view.ui.add(home, "top-left");
view.ui.add("info", "bottom-left");
// Open the Features widget with features fetched from
// the view click event location.
reactiveUtils.on(
() => view,
"click",
(event) => {
featuresWidget.open({
location: event.mapPoint,
fetchFeatures: true
});
}
);
map.when(() => {
// 2016 election layer
const senateLayer = map.layers.items[0];
senateLayer.outFields = ['*'];
view.whenLayerView(senateLayer).then((layerView) => {
let highlight;
let objectId;
const debouncedUpdate = promiseUtils.debounce(async (event) => {
// Perform a hitTest on the View
const hitTest = await view.hitTest(event);
// Make sure graphic is for the current layer
const results = hitTest.results.filter((result) => {
return result.graphic.layer.title === "Arkansas State Senate";
});
if(results.length){
const result = results[0];
const newObjectId = result && result.graphic.attributes[result.layer.objectIdField];
document.getElementById("info").style.visibility = "hidden";
if (!newObjectId) {
highlight?.remove();
objectId = null;
} else if (objectId !== newObjectId) {
highlight?.remove();
objectId = newObjectId;
highlight = layerView.highlight(result.graphic);
}
//result.forEach((graphicHit) => {
const graphic = result.graphic;
const attributes = graphic.attributes;
const firstName = attributes.FirstName;
const lastName = attributes.LastName;
const email = attributes.Email;
const party = attributes.Party;
const district = attributes.district;
const chamber = attributes.Chamber;
const id = attributes.OBJECTID;
document.getElementById("info").style.visibility = "visible";
var panel = document.querySelector('#info');
panel.children[0].heading = firstName + " " + lastName + " (" + party +")";
document.querySelector('[slot="title"]').innerText= "Arkansas " + chamber + " District " + district;
document.querySelector('[slot="subtitle"]').innerText=email;
document.querySelector('[slot="thumbnail"]').src=attributes.PhotoURL;
document.querySelector('[slot="thumbnail"]').width="320px";
}else{
highlight?.remove();
document.getElementById("info").style.visibility = "hidden";
}
});
// Listen for the pointer-move event on the View
view.on("pointer-move", (event) => {
debouncedUpdate(event).catch((err) => {
if (!promiseUtils.isAbortError(err)) {
throw err;
}
});
});
});
});
document.querySelector("calcite-shell").hidden = false;
document.querySelector("calcite-loader").hidden = true;
});
</script>
</body>
</html>
Solved! Go to Solution.
With the following changes I got it to highlight on mouseover:
1) Line 215 should be:
const senateLayer = map.layers.items[3];
2) Line 242 should be:
highlight = layerView.highlight([newObjectId]);
3) Technically not necessary, but I also changed line 227 to:
return result.graphic.layer == layerView.layer;
With the following changes I got it to highlight on mouseover:
1) Line 215 should be:
const senateLayer = map.layers.items[3];
2) Line 242 should be:
highlight = layerView.highlight([newObjectId]);
3) Technically not necessary, but I also changed line 227 to:
return result.graphic.layer == layerView.layer;
Thanks very much for your help.