Select to view content in your preferred language

Multiple actions on Layerlist

1339
5
Jump to solution
10-13-2022 07:45 AM
TheGamer
Regular Contributor

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>

 

 

0 Kudos
2 Solutions

Accepted Solutions
Sage_Wall
Esri Contributor

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

View solution in original post

0 Kudos
TheGamer
Regular Contributor

@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

View solution in original post

0 Kudos
5 Replies
Sage_Wall
Esri Contributor

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/

0 Kudos
TheGamer
Regular Contributor

Hi @Sage_Wall I tried to implement that for labels, but does not work, here's my code: https://codepen.io/Charanb98/pen/bGMzvPX

 

0 Kudos
Sage_Wall
Esri Contributor

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

0 Kudos
TheGamer
Regular Contributor

@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

0 Kudos
Sage_Wall
Esri Contributor

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;
})