Event Handler for LayerList widget item toggle in 4.9

02-20-2019 10:22 AM
Regular Contributor

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?

0 Kudos
4 Replies
MVP Esteemed Contributor


  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>

  <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>

    #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
      overflow: hidden;

  <link rel="stylesheet" href="https://js.arcgis.com/4.10/esri/css/main.css">
  <script src="https://js.arcgis.com/4.10/"></script>

    ], 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;
          //only add the item if it has not been added before
            item.watch("visible", function(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");


  <div id="viewDiv"></div>

Regular Contributor

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....

0 Kudos
MVP Esteemed Contributor

Strange the item.parent and uniqueParentItems was working for me.

0 Kudos
New Contributor

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) {



0 Kudos