Hi, I was wondering if there is a way to add additional actions to the layer list. I currently have the ability to change opacity but I also want to implement the option to turn labels on/off but I don't know how to show both actions. I don't want to create another layer list
<html>
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="initial-scale=1, maximum-scale=1,user-scalable=no"
/>
<title>
LayerList widget with actions | Sample | ArcGIS API for JavaScript 4.24
</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
overflow: hidden;
}
</style>
<link
rel="stylesheet"
href="https://js.arcgis.com/4.24/esri/themes/light/main.css"
/>
<script src="https://js.arcgis.com/4.24/"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/GroupLayer",
"esri/layers/MapImageLayer",
"esri/widgets/LayerList",
"esri/widgets/Slider",
"esri/widgets/Expand",
"esri/widgets/Legend",
"esri/widgets/BasemapToggle"
], (Map, MapView, GroupLayer, MapImageLayer, LayerList, Slider, Expand, Legend, BasemapToggle) => {
const USALayer = new MapImageLayer({
url: "http://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer",
title: "US Sample Data"
});
const censusLayer = new MapImageLayer({
url: "http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer",
title: "US Sample Census",
visible: false
});
const layer1 = new GroupLayer({
title: "USALayer",
visible: true,
visibilityMode: "exclusive",
layers: [USALayer],
opacity: 1
});
const layer2 = new GroupLayer({
title: "CensusLayer",
visible: true,
visibilityMode: "exclusive",
layers: [censusLayer],
opacity: 0.75
});
const map = new Map({
basemap: "gray-vector",
layers: [layer1, layer2],
});
const view = new MapView({
center: [-98.5795, 39.8282],
zoom: 4,
container: "viewDiv",
map: map
});
const toggle = new BasemapToggle({
view: view,
nextBasemap: "hybrid"
});
function defineActions(event) {
const item = event.item;
if (item.children.length > 1 && item.parent) {
const slider = new Slider({
min: 0,
max: 1,
precision: 2,
values: [1],
visibleElements: {
labels: true,
rangeLabels: true
}
});
item.panel = {
content: slider,
className: "esri-icon-sliders-horizontal",
title: "Change layer opacity"
};
slider.on("thumb-drag", (event) => {
const { value } = event;
item.layer.opacity = value;
});
}
}
view.when(() => {
const layerList = new LayerList({
view: view,
listItemCreatedFunction: defineActions
});
layerList.on("trigger-action", (event) => {
const visibleLayer = USALayer.visible ? USALayer : censusLayer;
const id = event.action.id;
if (id === "increase-opacity") {
if (demographicGroupLayer.opacity < 1) {
demographicGroupLayer.opacity += 0.25;
}
} else if (id === "decrease-opacity") {
if (demographicGroupLayer.opacity > 0) {
demographicGroupLayer.opacity -= 0.25;
}
}
});
view.ui.add(layerList, "top-right");
const legend = new Expand({
content: new Legend({
view: view,
//style: "card"
}),
view: view
});
view.ui.add(legend, "bottom-left");
view.ui.add(toggle, "top-left");
});
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
Solved! Go to Solution.
I wrote a codepen to demonstrate one way to add both an opacity slider and a button to toggle labels. It's not a prefect implementation but hopefully will get you started in the right direction.
https://codepen.io/sagewall/pen/zYjeJya?editors=1000
This was made by combining parts of these two samples:
I hope this helps
@Sage_Wall Thank you so much, i just have a question how is your code able to change opacity even though you dont have a trigger
Hi @TheGamer , take a look at this sample. It shows how to add multiple actions to the LayerList widget.
https://developers.arcgis.com/javascript/latest/sample-code/widgets-layerlist-actions/
Hi @Sage_Wall I tried to implement that for labels, but does not work, here's my code: https://codepen.io/Charanb98/pen/bGMzvPX
I wrote a codepen to demonstrate one way to add both an opacity slider and a button to toggle labels. It's not a prefect implementation but hopefully will get you started in the right direction.
https://codepen.io/sagewall/pen/zYjeJya?editors=1000
This was made by combining parts of these two samples:
I hope this helps
@Sage_Wall Thank you so much, i just have a question how is your code able to change opacity even though you dont have a trigger
Glad to help,
The defineActions() method is assigned to a property called listItemCreatedFunction which is function that executes each time a ListItem is created. So we first get a reference for the ListItem in our defineActions() method as a constant named item.
function defineActions(event) {
// The event object contains an item property.
// This is a ListItem referencing the associated layer
// and other properties.
const item = event.item;
.....
Then later in the same defineActions() method (around line 238) we use that ListItem to change the associated layer's opacity to the current value of the slider.
slider.on("thumb-drag", (event) => {
const { value } = event;
item.layer.opacity = value;
})