I can't quite grasp how to attach an event handler to the LayerList widget so that each time a user clicks (toggles) a layer, I can run a custom function. I want to attach this to every layer, not just individual ones...
I tried
const layerList = new LayerList({
view: mapView,
container: 'layerlist'
});
layerList.viewModel.on('trigger-action', myCustomFunction);
I also tried it with just
layerList.on('trigger-action', myCustomFunction)
Any tips here?
Jay,
The trigger-action is only going to occur when the user clicks the list item menu (i.e. the three dots)
layerList.on("trigger-action", function(event) {
...
});
You use the LayerList listItemCreatedFunction property when you want to do something for each item that is created in the Layerlist.
Here is a sample that when you toggle the parent item the console.logs it's visibility:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
<title>LayerList widget with actions - 4.10</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.10/esri/css/main.css">
<script src="https://js.arcgis.com/4.10/"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/GroupLayer",
"esri/layers/MapImageLayer",
"esri/widgets/LayerList"
], function(
Map, MapView, GroupLayer, MapImageLayer, LayerList
) {
// Create layer showing sample data of the United States.
var USALayer = new MapImageLayer({
url: "http://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer",
title: "US Sample Data"
});
// Create layer showing sample census data of the United States.
// Set visibility to false so it's not visible on startup.
var censusLayer = new MapImageLayer({
url: "http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer",
title: "US Sample Census",
visible: false
});
var map = new Map({
basemap: "dark-gray",
layers: [USALayer, censusLayer]
});
// Add the map to a MapView
var view = new MapView({
center: [-98.5795, 39.8282],
zoom: 5,
container: "viewDiv",
map: map
});
// Creates actions in the LayerList.
var uniqueParentItems = [];
function defineActions(event) {
var item = event.item;
if(!item.parent){
//only add the item if it has not been added before
if(!uniqueParentItems.includes(item.title)){
uniqueParentItems.push(item.title);
item.watch("visible", function(event){
console.info(event);
});
}
}
}
view.when(function() {
var layerList = new LayerList({
view: view,
// executes for each ListItem in the LayerList
listItemCreatedFunction: defineActions
});
// Add widget to the top right corner of the view
view.ui.add(layerList, "top-right");
});
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
Okay, this kind of works for my purposes. However, I've been having a hard time with the watch handlers. Sometimes the function (in your example it's defineActions) runs 5 times for adding a single layer - and I haven't really been able to figure out how to only set a watcher once on the top level. The uniqueParentItems doesn't always work - plus sometimes the item.title is "Layer" until the layer is actually loaded and able to get the title (since I'm loading layers from the portal). It's making my head spin....
Strange the item.parent and uniqueParentItems was working for me.
RobertScheitlin__GISP,
this solution works for me, tnx. But listItemCreatedFunction removes item.panel.open switcher. Is it possible to keep the item.panel.open switcher and add an observer to it?
----------
I've found it!
Only add to defineActions next code:
item.panel = {
content: 'legend',
open: true,
};
item.panel.watch('open', function (event) {
console.info(event);
});