Multiple LayerLists In Web App

2487
15
Jump to solution
09-05-2019 11:39 AM
RichardRhone
New Contributor III

Is it possible to have more than one layerlist in one web app. I would like to add another layerlist where i can have only some of the layers visible in layerList1 and other layers visible in layerList2

1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Richard,

  Through direct dom manipulation you can:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1, maximum-scale=1,user-scalable=no"
    />
    <title>LayerList widget - 4.12</title>

    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.12/esri/themes/light/main.css"
    />

    <style>
      html,
      body,
      #viewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
        overflow: hidden;
      }
    </style>

    <script src="https://js.arcgis.com/4.12/"></script>

    <script>
      require([
        "esri/views/SceneView",
        "esri/widgets/LayerList",
        "esri/WebScene",
        "dojo/query",
        "esri/core/watchUtils",
        "dojo/dom-style"
      ], function(SceneView, LayerList, WebScene, query, watchUtils, domStyle) {
        var scene = new WebScene({
          portalItem: {
            // autocasts as new PortalItem()
            id: "adfad6ee6c6043238ea64e121bb6429a"
          }
        });

        var view = new SceneView({
          container: "viewDiv",
          map: scene
        });

        view.when(function() {
          var layerList = new LayerList({
            view: view,
            id: "layerlist1"
          });

          // Add widget to the top right corner of the view
          view.ui.add(layerList, "top-right");
          
          //workaround for making sure layerlist is ready
          watchUtils.when(layerList, 'operationalItems.length', function(){
             var lis = query('li[aria-labelledby $= "__title"]', layerList.domNode);
             lis.map(function(li){
               if(li.innerText === "San Francisco"){
                 domStyle.set(li, "display", "none");
               }
               if(li.innerText === "Growth Potential"){
                 domStyle.set(li, "display", "none");
               }
             });
          });
          
          var layerList2 = new LayerList({
            view: view
          });

          // Add widget to the top right corner of the view
          view.ui.add(layerList2, "bottom-right");
          
          //workaround for making sure layerlist is ready
          watchUtils.when(layerList2, 'operationalItems.length', function(){
             var lis = query('li[aria-labelledby $= "__title"]', layerList2.domNode);
             lis.map(function(li){
               if(li.innerText === "Transit lines in service"){
                 domStyle.set(li, "display", "none");
               }
               if(li.innerText === "Transit lines planned"){
                 domStyle.set(li, "display", "none");
               }
             });
          });
        });
      });
    </script>
  </head>

  <body class="calcite">
    <div id="viewDiv"></div>
  </body>
</html>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

View solution in original post

15 Replies
RobertScheitlin__GISP
MVP Emeritus

Richard,

  Through direct dom manipulation you can:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1, maximum-scale=1,user-scalable=no"
    />
    <title>LayerList widget - 4.12</title>

    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.12/esri/themes/light/main.css"
    />

    <style>
      html,
      body,
      #viewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
        overflow: hidden;
      }
    </style>

    <script src="https://js.arcgis.com/4.12/"></script>

    <script>
      require([
        "esri/views/SceneView",
        "esri/widgets/LayerList",
        "esri/WebScene",
        "dojo/query",
        "esri/core/watchUtils",
        "dojo/dom-style"
      ], function(SceneView, LayerList, WebScene, query, watchUtils, domStyle) {
        var scene = new WebScene({
          portalItem: {
            // autocasts as new PortalItem()
            id: "adfad6ee6c6043238ea64e121bb6429a"
          }
        });

        var view = new SceneView({
          container: "viewDiv",
          map: scene
        });

        view.when(function() {
          var layerList = new LayerList({
            view: view,
            id: "layerlist1"
          });

          // Add widget to the top right corner of the view
          view.ui.add(layerList, "top-right");
          
          //workaround for making sure layerlist is ready
          watchUtils.when(layerList, 'operationalItems.length', function(){
             var lis = query('li[aria-labelledby $= "__title"]', layerList.domNode);
             lis.map(function(li){
               if(li.innerText === "San Francisco"){
                 domStyle.set(li, "display", "none");
               }
               if(li.innerText === "Growth Potential"){
                 domStyle.set(li, "display", "none");
               }
             });
          });
          
          var layerList2 = new LayerList({
            view: view
          });

          // Add widget to the top right corner of the view
          view.ui.add(layerList2, "bottom-right");
          
          //workaround for making sure layerlist is ready
          watchUtils.when(layerList2, 'operationalItems.length', function(){
             var lis = query('li[aria-labelledby $= "__title"]', layerList2.domNode);
             lis.map(function(li){
               if(li.innerText === "Transit lines in service"){
                 domStyle.set(li, "display", "none");
               }
               if(li.innerText === "Transit lines planned"){
                 domStyle.set(li, "display", "none");
               }
             });
          });
        });
      });
    </script>
  </head>

  <body class="calcite">
    <div id="viewDiv"></div>
  </body>
</html>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
JohanArtica
New Contributor

Robert Scheitlin, GISP,
 What would be the way if the layerlist were inside an expand widget?

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

No difference. Same code would apply.

0 Kudos
JohanArtica
New Contributor

I tried adding an expand widget, but I don't get it to work, what am I doing wrong?

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1, maximum-scale=1,user-scalable=no"
    />
    <title>LayerList widget - 4.12</title>

    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.12/esri/themes/light/main.css"
    />

    <style>
      html,
      body,
      #viewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
        overflow: hidden;
      }
    </style>

    <script src="https://js.arcgis.com/4.11/"></script>

    <script>
      require([
        "esri/views/SceneView",
        "esri/widgets/LayerList",
        "esri/WebScene",
        "esri/widgets/Expand",
        "dojo/query",
        "esri/core/watchUtils",
        "dojo/dom-style"
      ], function(SceneView, LayerList, WebScene, Expand, query, watchUtils, domStyle) {
        var scene = new WebScene({
          portalItem: {
            // autocasts as new PortalItem()
            id: "adfad6ee6c6043238ea64e121bb6429a"
          }
        });

        var view = new SceneView({
          container: "viewDiv",
          map: scene
        });

        view.when(function() {
          
      var layerList = new LayerList({
        container: document.createElement("div"),
        view: view,
        id: "layerlist1"
      });
      
      var layerListExpand = new Expand({
        expandIconClass: "esri-icon-layers", 
        expandTooltip: "Operational Layers",
        view: view,
        expanded: true,
        content: layerList
      });
      
      view.ui.add(layerListExpand, "top-right");
          
         /* var layerList = new LayerList({
            view: view,
            id: "layerlist1"
          });

          // Add widget to the top right corner of the view
          view.ui.add(layerList, "top-right"); */
          
          //workaround for making sure layerlist is ready
          watchUtils.when(layerList, 'operationalItems.length', function(){
             var lis = query('li[aria-labelledby $= "__title"]', layerList.domNode);
             lis.map(function(li){
               if(li.innerText === "San Francisco"){
                 domStyle.set(li, "display", "none");
               }
               if(li.innerText === "Growth Potential"){
                 domStyle.set(li, "display", "none");
               }
             });
          });
          
          var layerList2 = new LayerList({
            view: view
          });

          // Add widget to the top right corner of the view
          view.ui.add(layerList2, "bottom-right");
          
          //workaround for making sure layerlist is ready
          watchUtils.when(layerList2, 'operationalItems.length', function(){
             var lis = query('li[aria-labelledby $= "__title"]', layerList2.domNode);
             lis.map(function(li){
               if(li.innerText === "Transit lines in service"){
                 domStyle.set(li, "display", "none");
               }
               if(li.innerText === "Transit lines planned"){
                 domStyle.set(li, "display", "none");
               }
             });
          });
        });
      });
    </script>
  </head>

  <body class="calcite">
    <div id="viewDiv"></div>
  </body>
</html>
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Johan,

  OK, I see the issue is the dom node the query needs to work with is now the expand widgets dom node:

var lis = query('li[aria-labelledby $= "__title"]', layerListExpand.domNode);

Instead of the layerList.domNode

RichardRhone
New Contributor III

I am trying with the expand but not getting the desired result :

var layerList2 = new LayerList({ view: view, container: document.createElement("div"), listItemCreatedFunction: function (event) { item = event.item; item.panel = { content: "legend" }; } });
var expandLyr = new Expand({ view: view, content: layerList2.domNode, expandTooltip: "Layers With Legend", collaseTooltip: "Layers With Legend", expandIconClass: "esri-icon-layers" });
view.ui.add(expandLyr, "bottom-right");

watchUtils.when(layerList2, 'operationalItems.length', function () 
{
setTimeout(function () 
{
var lis = query('li[aria-labelledby $= "__title"]', expandLyr.domNode);

console.log("LIS ", lis);

lis.map(function (li) 
{
 console.log(li.innerText);
});
}, 0)
});

Results :

Notice that only subs have a innerText. How do I get around this as I need to remove these from the layerList

I do not have this issue with the layerList by itself; only with Expand

0 Kudos
RichardRhone
New Contributor III

Issue resolved by putting the code outside view.when()

JohanArtica
New Contributor

Robert,

I'm sorry to bother you again with my inconveniences, but when the expanded property is changed to false, in the expand widget, it doesn't work properly, do you know why this happens?

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

because when the expand is hiding the layerlist then the query can not find the nodes it is searching for. You will have to watch the expand to see if it is expanded before you execute the query code.

0 Kudos