Select to view content in your preferred language

Adding additional layer list actions to layer list with legend example

428
6
08-08-2023 07:34 AM
Key
by
New Contributor II

Hi,

Was hoping someone can show me how to add the opacity slider to a layer list with legend.

I am essentially trying to combine these two examples. preferably adding action items to the layer list with legend example. 

https://developers.arcgis.com/javascript/latest/sample-code/sandbox/?sample=widgets-layerlist-legend 

https://developers.arcgis.com/javascript/latest/sample-code/sandbox/?sample=widgets-layerlist-action... 

0 Kudos
6 Replies
JoelBennett
MVP Regular Contributor

In the Add a Legend to LayerList sample, you can add an opacity slider by changing the contents of the script tag beginning on line 32 to the following:

      require(["esri/WebMap", "esri/views/MapView", "esri/widgets/LayerList", "esri/widgets/Slider"], (
        WebMap,
        MapView,
        LayerList,
        Slider
      ) => {
        const map = new WebMap({
          portalItem: {
            id: "d5dda743788a4b0688fe48f43ae7beb9"
          }
        });

        // Add the map to a MapView
        const view = new MapView({
          container: "viewDiv",
          map: map
        });

        async function defineActions(event) {
          const item = event.item;

          await item.layer.when();

          if (item.title === "Census Tracts") {
            const slider = new Slider({
              min: 0,
              max: 1,
              precision: 2,
              values: [1],
              visibleElements: {
                labels: true,
                rangeLabels: true
              }
            });

            item.panel = {
              content: ["legend",slider],
              open: true,
              className: "esri-icon-sliders-horizontal",
              title: "Layer Info"
            };

            slider.on("thumb-drag", (event) => {
              const { value } = event;
              item.layer.opacity = value;
            });
          }
        }

        // Add a legend instance to the panel of a
        // ListItem in a LayerList instance
        const layerList = new LayerList({
          view: view,
          listItemCreatedFunction: defineActions
        });

        view.ui.add(layerList, "top-right");
      });

 

0 Kudos
Key
by
New Contributor II

Thank you for taking a look!

Your code appears to add the opacity slider but removes the legend items. Below is the code snippet I am using to add the legend to layer list. I'm not sure how to add the slider event to the existing event. 

       // create a layerlist and expand widget and add to the view
        const layerList = new LayerList({
            view: view,
            listItemCreatedFunction: (event) => {
                const item = event.item;
                if (item.layer.type != "group") {
                    // don't show legend twice
                    item.panel = {
                        content: "legend",
                        open: false
                    };
                }
            }
        });
        const llExpand = new Expand({
            view: view,
            content: layerList,
            expanded: false
        });
        view.ui.add(llExpand, {
            position: "top-left",
            index: 0
        });

 

0 Kudos
JoelBennett
MVP Regular Contributor

If by "legend items" you mean "action items", then perhaps this is what you're looking for:

      require(["esri/WebMap", "esri/views/MapView", "esri/widgets/LayerList", "esri/widgets/Slider"], (
        WebMap,
        MapView,
        LayerList,
        Slider
      ) => {
        const map = new WebMap({
          portalItem: {
            id: "d5dda743788a4b0688fe48f43ae7beb9"
          }
        });

        // Add the map to a MapView
        const view = new MapView({
          container: "viewDiv",
          map: map
        });

        async function defineActions(event) {
          const item = event.item;

          await item.layer.when();

          if (item.title === "Census Tracts") {
            const slider = new Slider({
              min: 0,
              max: 1,
              precision: 2,
              values: [1],
              visibleElements: {
                labels: true,
                rangeLabels: true
              }
            });

            item.panel = {
              content: ["legend",slider],
              open: true,
              className: "esri-icon-sliders-horizontal",
              title: "Layer Info"
            };

            slider.on("thumb-drag", (event) => {
              const { value } = event;
              item.layer.opacity = value;
            });

            item.actionsSections = [
              [
                {
                  title: "Go to full extent",
                  className: "esri-icon-zoom-out-fixed",
                  id: "full-extent"
                },
                {
                  title: "Layer information",
                  className: "esri-icon-description",
                  id: "information"
                }
              ],
              [
                {
                  title: "Increase opacity",
                  className: "esri-icon-up",
                  id: "increase-opacity"
                },
                {
                  title: "Decrease opacity",
                  className: "esri-icon-down",
                  id: "decrease-opacity"
                }
              ]
            ];
          }
        }

        // Add a legend instance to the panel of a
        // ListItem in a LayerList instance
        const layerList = new LayerList({
          view: view,
          listItemCreatedFunction: defineActions
        });

          layerList.on("trigger-action", (event) => {
            // The layer visible in the view at the time of the trigger.
            const visibleLayer = event.item.layer;

            // Capture the action id.
            const id = event.action.id;

            if (id === "full-extent") {
              // if the full-extent action is triggered then navigate
              // to the full extent of the visible layer
              view.goTo(visibleLayer.fullExtent).catch((error) => {
                if (error.name != "AbortError") {
                  console.error(error);
                }
              });
            } else if (id === "information") {
              // if the information action is triggered, then
              // open the item details page of the service layer
              window.open(visibleLayer.url);
            } else if (id === "increase-opacity") {
              // if the increase-opacity action is triggered, then
              // increase the opacity of the GroupLayer by 0.25

              if (visibleLayer.opacity < 1) {
                visibleLayer.opacity += 0.25;
              }
            } else if (id === "decrease-opacity") {
              // if the decrease-opacity action is triggered, then
              // decrease the opacity of the GroupLayer by 0.25

              if (visibleLayer.opacity > 0) {
                visibleLayer.opacity -= 0.25;
              }
            }
          });

        view.ui.add(layerList, "top-right");
      });

 

0 Kudos
Key
by
New Contributor II

Thanks for taking another look. If I use the code above it removes the legend within the layer list.

Screenshot 2023-08-15 121353.png

0 Kudos
JoelBennett
MVP Regular Contributor

The solutions provided are specific to the samples, because that's how your original request was framed.  If you copy and paste the code into the samples, you'll see the solutions do work, and do add an opacity slider into the layer list along with the legend.

I can't tell why it doesn't work in your application, because I can't access it or its source code.  Perhaps since the code I've provided is specific to the samples, maybe you included the condition that restricts the modifications to a layer with the title "Census Tracts" (line 24 in both snippets).

0 Kudos
Key
by
New Contributor II

Joel,

I got it to work. I feel goofy it didn't come to me earlier. Thank you for your time on this. Below is the solution, I just need to add this snippet 

        // create a layerlist and expand widget and add to the view
        async function defineActions(event) {
          const item = event.item;

          await item.layer.when();

            if (item.layer.type != "group") {
                // don't show legend twice
                item.panel = {
                    content: "legend",
                    open: false
                };
                }

            if (item.title === "Imagery") {
            const slider = new Slider({
                min: 0,
                max: 1,
                precision: 2,
                values: [1],
                visibleElements: {
                labels: true,
                rangeLabels: true
                }
            });
0 Kudos