2

Is it possible to have a single layer visible on the map in this ESRI tutorial LayerList widget ?

Each time you click on a layer, the previous one should deactivate. So you always have only one layer on the map.

Michelle

enter image description here

Michelle
  • 99
  • 2
  • 9

2 Answers2

2

Updated answer with version 4 of the API. It is possible to add the functionality at creating the widget using 2 features.

The listItemCreatedFunction function-

https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-LayerList.html#listItemCreatedFunction

According to the api:

Specifies a function that accesses each ListItem. Each list item can be modified according to its modifiable properties. Actions can be added to list items using the actionsSections property of the ListItem.

and the operationalItems property-

https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-LayerList.html#operationalItems

According to the api:

A collection of ListItems representing operational layers.

var LayerListWidget = new LayerList({
      listItemCreatedFunction: (event) => {
        var itemView = event.item; // layer-view of selection
        itemView.watch("visible", (event) => {
          LayerListWidget.operationalItems.forEach((layerView) => {
            if (layerView.layer.id != itemView.layer.id) {
              layerView.visible = false;
            }
          });
        });
      },
      view: view,
    });
Shaked
  • 93
  • 1
  • 9
  • Yours the only answer I found related to the 4.X version, I find it very useful, but the toggle has some issues, 1) need to click twice on the eye icon when toggling, ex: layer 1 click and when click on layer 2 it was just unchecking the layer 1, I am looking for a radio button functionality 2) current toggle applies for both layer and sublayers, I am looking for toggle only for the top layers, sublayers should just work as a checkbox. Could you please check my fiddle below? https://jsfiddle.net/skesani/3jacqf0p/ – angular_architect May 22 '21 at 21:03
  • Hi @angular_architect you were right about problems that arose. The listItemCreatedFunction is a bit tricky so I took another approach that would do the job. I didn't want to fight with it just for the hell of it. Hope this will help you [https://jsfiddle.net/wgoemp5x/2/](https://jsfiddle.net/wgoemp5x/2/) – Shaked May 24 '21 at 08:10
1

I managed to write a code for you . Check it and let me know :

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
<title>Layer List Dijit</title>
<link rel="stylesheet" href="https://js.arcgis.com/3.20/dijit/themes/claro/claro.css">
<link rel="stylesheet" href="https://js.arcgis.com/3.20/esri/css/esri.css">
<script language="javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<style>
html, body, .container, #map {
height:100%;
width:100%;
margin:0;
padding:0;
margin:0;
font-family: "Open Sans";
}
#map {
padding:0;
}
#layerListPane{
width:25%;
}
.esriLayer{
  background-color: #fff;
}
.esriLayerList .esriList{
    border-top:none;
}
.esriLayerList .esriTitle {
  background-color: #fff;
  border-bottom:none;
}
.esriLayerList .esriList ul{
  background-color: #fff;
}

</style>
<script>var dojoConfig = { parseOnLoad: true };var busy=false;</script>
<script src="https://js.arcgis.com/3.20/"></script>
<script>
require([
"esri/arcgis/utils",
"esri/dijit/LayerList",
"dijit/layout/BorderContainer",
"dijit/layout/ContentPane",
"dojo/domReady!"
], function(
arcgisUtils,
LayerList
) {
//Create a map based on an ArcGIS Online web map id
arcgisUtils.createMap("f63fed3f87fc488489e27c026fa5d434", "map").then(function(response){
    var myWidget = new LayerList({
       map: response.map,
       layers: arcgisUtils.getLayerList(response)
    },"layerList");

    myWidget.on("toggle",function(evt){
        if(busy) return;

        selectedLayerSubIndex = evt.subLayerIndex;
        if(selectedLayerSubIndex) return;

        selectedLayerIndex = evt.layerIndex;
        visibility = evt.visible;

        elm = $("#layerListPane input[type=checkbox][data-layer-index="+selectedLayerIndex+"]:not([data-sublayer-index])");


        otherCheckedElems = $("#layerListPane input[type=checkbox][data-layer-index!="+selectedLayerIndex+"]:not([data-sublayer-index]):checked");
        if(visibility){
            busy=true;
            otherCheckedElems.each(function () {
                $(this).click();
            });
            busy=false;
        }
        else{
            checkedLength = otherCheckedElems.length
            if(checkedLength==0) setTimeout("elm.click();", 100);
        }
    })

    myWidget.startup();
});

});
</script>
</head>
<body class="claro">
<div class="container" data-dojo-type="dijit/layout/BorderContainer"
data-dojo-props="design:'headline',gutters:false">
<div id="layerListPane" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'right'">
    <div id="layerList"></div>
</div>
<div id="map" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'"></div>
</div>
</body>
</html>
Ashraf
  • 2,612
  • 1
  • 20
  • 35
  • Lovely. Just started to learn to code, very useful for me. Would it be possible to always have one layer on the map (like mentioned in the question)? At this point you can deactivate the layer and have none on the map; can this behaviour be prevented? – Michelle Apr 24 '17 at 05:59
  • Initially , you'll get the layers as their visibility in the map service . So do you want to override that ? you can for example switch only the first layer on . If this was your question please let me know so I update the code . And for sure you can keep at least one layer on . Will update the answer later after confirming your question. – Ashraf Apr 24 '17 at 09:48
  • Hi @Ashraf I do not want to override the initial visibility from the map service. While selecting a layer from the list, at this moment you can also deselect it and remain with no layers on the map. I would like to prevent this behaviour so you always have one layer on. – Michelle Apr 24 '17 at 11:21
  • Hi @Ashraf Not sure it works, clicking the name of the layer you can deselect it and remain with no layers on the map :( – Michelle Apr 25 '17 at 11:13
  • @Michelle clicking the checkboxes works . But clicking labels is not working . you are correct . Will modify the code and update you . – Ashraf Apr 25 '17 at 14:58
  • @Michelle I went ahead and modified the code for you . Also I published a copy here to see it in action : https://jsbin.com/xanepazodo/edit?html,output – Ashraf Apr 26 '17 at 05:21
  • Hi @Ashraf The code is working great, thank you for your time :) – Michelle Apr 26 '17 at 15:09
  • I am looking for exact same functionality in 4.x, I am able to make it work little bit but it had some issues 1) need to click twice on the eye icon when toggling, ex: layer 1 click and then click on layer 2 it was just unchecking the layer 1, I am looking for a radio button functionality 2) current toggle applies for both layer and sublayers, I am looking for toggle only for the top layers, sublayers should just work as a checkbox. Could you please check my fiddle below? https://jsfiddle.net/skesani/3jacqf0p/ – angular_architect May 22 '21 at 21:05