Multiple Layerlists and Label Visibility JS API 4.xx

238
3
Jump to solution
01-20-2022 01:07 PM
MinaN_SCCWRP
New Contributor III
Hi all,
 
I'm working on creating multiple layerlists so that each layer has it's own. The multiple layerlists are functional and work fine, the problem I'm running into now is that the the label visibility feature doesn't seem to be working properly.
 
 I was stoked to find great examples in threads Multiple LayerLists In Web App , & Toggle Labels On and Off  , and attempted to merge what was learned from both but with no luck.

 

Can anyone point me in the right direction on how to make this code work? I have several more layers I want to add to this web app but I figured starting small and slowly scaling was the best approach @ChristianBischof @RobertScheitlin__GISP 

 

<!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.22</title>

    <link rel="stylesheet" href="https://js.arcgis.com/4.22/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/Map",
            "esri/geometry/Point",
            "esri/views/MapView",
            "esri/layers/FeatureLayer",
            "esri/widgets/LayerList",
            "esri/widgets/Expand",
            "dojo/query",
            "esri/core/watchUtils",
            "dojo/dom-style"
        ], function (Map, Point, MapView, FeatureLayer, LayerList, Expand, query, watchUtils, domStyle) {

            const watershedLabel = ({
                symbol: {
                    type: "text",  // autocasts as new TextSymbol()
                    color: "white",
                    font: {  // autocast as new Font()
                        family: "Playfair Display",
                        size: 12,
                        weight: "bold"
                    }
                },
                labelPlacement: "above-center",
                labelExpressionInfo: {
                    expression: "$feature.HRNAME"
                },
                deconflictionStrategy: "none"
            });
            const waterRend = {
                type: "simple",  // autocasts as new SimpleRenderer()
                symbol: {
                    type: "simple-fill",  // autocasts as new SimpleFillSymbol()
                    color: [0, 200, 200, 0.3],
                    outline: {  // autocasts as new SimpleLineSymbol()
                        width: 0.5,
                        color: "black"
                    }
                }
            };
            const watersheds = new FeatureLayer({
                url: "https://gis.sccwrp.org/arcserver/rest/services/Hosted/California_Watersheds/FeatureServer",
                renderer: waterRend,
                title: "Watersheds",
                labelingInfo: watershedLabel
            });

            const rwqcbLabel = ({
                symbol: {
                    type: "text",  // autocasts as new TextSymbol()
                    color: "white",
                    font: {  // autocast as new Font()
                        family: "Playfair Display",
                        size: 12,
                        weight: "bold"
                    }
                },
                labelPlacement: "above-center",
                labelExpressionInfo: {
                    expression: "$feature.RBNAME"
                },
                deconflictionStrategy: "none"
            });
            const rwqcbRend = {
                type: "simple",  // autocasts as new SimpleRenderer()
                symbol: {
                    type: "simple-fill",  // autocasts as new SimpleFillSymbol()
                    color: [0, 76, 115, 0.1],
                    outline: {  // autocasts as new SimpleLineSymbol()
                        width: 2,
                        color: "brown"
                    }
                }
            };
            const rwqcb = new FeatureLayer({
                url: "https://gis.sccwrp.org/arcserver/rest/services/Hosted/Regional_Water_Quality_Control_Boards/FeatureServer", // Taken from sccwrp ArcOnline account
                title: "Regional Water Quality Control Boards", // naming layer as it'll be seen on the legend + layerlist dropdown menu
                renderer: rwqcbRend,
                labelingInfo: rwqcbLabel
            });

            // Setting up map
            const map = new Map({
                basemap: "satellite",
                layers: [watersheds, rwqcb]
            });

            var view = new MapView({  // take that new map we just made above and display it
                container: "viewDiv",
                center: [-118.243683, 36.052235],
                zoom: 6,
                map: map,
                popup: {
                    autoOpenEnabled: false,
                    dockEnabled: true,
                    dockOptions: {
                        // dock popup at bottom-right side of view
                        buttonEnabled: true,
                        breakpoint: false,
                        position: "bottom-right"
                    }
                }
            });

            // Multiple layerlist function
            view.when(function () {

                // New Layerlist (dropdown)
                // Visble layer function
                // Add widget to the top right corner of the view
                //workaround for making sure layerlist is ready
                var layerList = new LayerList({
                    view: view,
                    listItemCreatedFunction: function (event) {
                        const item = event.item;
                        item.actionsSections = [
                            [
                                {
                                    title: "Labels",
                                    className: "esri-icon-labels",
                                    id: "labels"
                                }
                            ]
                        ];
                    }
                });
                layerList.on("trigger-action", function (rwqcbevent) {
                    if (rwqcbevent.action.id === "labels") {
                        if (rwqcb.labelsVisible == false) {
                            rwqcb.labelsVisible = true;
                            console.log(rwqcb.labelsVisible);
                        } else {
                            rwqcb.labelsVisible = false;
                            console.log(rwqcb.labelsVisible);
                        }
                    }
                });
                watchUtils.when(layerList, 'operationalItems.length', function () {
                    var lis = query('li[aria-labelledby $= "__title"]', layerList.domNode);
                    lis.map(function (li) {
                        if (li.innerText === "Regional Water Quality Control Boards") {
                            domStyle.set(li, "display", "none");
                        }
                    });
                });
                view.ui.add(layerList, "top-right");

                
                // New Layerlist (dropdown)
                // Visble layer function
                // Add widget to the top right corner of the view
                //workaround for making sure layerlist is ready
                var layerList2 = new LayerList({
                    view: view,
                    listItemCreatedFunction: function (event) {
                        const item = event.item;
                        item.actionsSections = [
                            [
                                {
                                    title: "Labels",
                                    className: "esri-icon-labels",
                                    id: "labels2"
                                }
                            ]
                        ];
                    }
                });         
                layerList2.on("trigger-action", function (watershedevent) {
                    if (watershedevent.action.id === "labels2") {
                        if (watersheds.labelsVisible == false) {
                            watersheds.labelsVisible = true;
                            console.log(watersheds.labelsVisible);
                        } else {
                            watersheds.labelsVisible = false;
                            console.log(watersheds.labelsVisible);
                        }
                    }
                });
                watchUtils.when(layerList2, 'operationalItems.length', function () {
                    var lis = query('li[aria-labelledby $= "__title"]', layerList2.domNode);
                    lis.map(function (li) {
                        if (li.innerText === "Watersheds") {
                            domStyle.set(li, "display", "none");
                        }
                    });
                });
                view.ui.add(layerList2, "top-right");
            });
      
        });
    </script>
</head>

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

</html>

 

0 Kudos
1 Solution

Accepted Solutions
KenBuja
MVP Honored Contributor

Your problem is in lines 165 and 206. You're excluding the layer that you actually want to include for each LayerList. By changing them to

 

if (li.innerText !== "Regional Water Quality Control Boards") {
and
if (li.innerText !== "Watersheds") {

 

you can be well-prepared for adding additional LayerLists.

 

View solution in original post

0 Kudos
3 Replies
KenBuja
MVP Honored Contributor

Your problem is in lines 165 and 206. You're excluding the layer that you actually want to include for each LayerList. By changing them to

 

if (li.innerText !== "Regional Water Quality Control Boards") {
and
if (li.innerText !== "Watersheds") {

 

you can be well-prepared for adding additional LayerLists.

 

0 Kudos
MinaN_SCCWRP
New Contributor III

That worked splendidly @KenBuja,  much appreciation!

0 Kudos
MinaN_SCCWRP
New Contributor III

Attaching a working code for anyone else who might benefit from this:

<!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.22</title>

    <link rel="stylesheet" href="https://js.arcgis.com/4.22/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/Map",
            "esri/geometry/Point",
            "esri/views/MapView",
            "esri/layers/FeatureLayer",
            "esri/widgets/LayerList",
            "esri/widgets/Expand",
            "esri/widgets/Legend",
            "esri/widgets/BasemapGallery",
            "dojo/query",
            "esri/core/watchUtils",
            "dojo/dom-style"
        ], function (Map, Point, MapView, FeatureLayer, LayerList, Expand, Legend, BasemapGallery, query, watchUtils, domStyle) {

            // Rivers label + renderer + feature layer + add layer
            const priorityLabel = ({
                symbol: {
                    type: "text",  // autocasts as new TextSymbol()
                    color: "white",
                    font: {  // autocast as new Font()
                        family: "Playfair Display",
                        size: 12,
                        weight: "regular"
                    }
                },
                labelPlacement: "above-center",
                labelExpressionInfo: {
                    expression: "$feature.Actn_Rc"
                },
                deconflictionStrategy: "none"
            });
            const priRend = {
                type: "unique-value",  // autocasts as new UniqueValueRenderer()
                field: "Actn_Rc",
                defaultSymbol: { type: "simple-fill" },  // autocasts as new SimpleFillSymbol()
                uniqueValueInfos: [{
                    value: "Low Priority",
                    symbol: {
                        type: "simple-fill",  // autocasts as new SimpleFillSymbol()
                        color: "brown"
                    }
                }, {
                    value: "Restoration & Management",
                    symbol: {
                        type: "simple-fill",
                        color: "orange"
                    }
                }, {
                    value: "Management",
                    symbol: {
                        type: "simple-fill",
                        color: "blue"
                    }
                }, {
                    value: "Restoration",
                    symbol: {
                        type: "simple-fill",
                        color: "green"
                    }
                }, {
                    value: "Protection",
                    symbol: {
                        type: "simple-fill",
                        color: "yellow"
                    }
                }]
            };
            const priority = new FeatureLayer({
                url: "https://services1.arcgis.com/gfvMa5URH3rFRQ7T/arcgis/rest/services/StressorRating_Statewide_Median_ReachAction_R4_1_2/FeatureServer",
                title: "Watershed Prioritization Recommended Actions",
                renderer: priRend,
                labelingInfo: priorityLabel
            });

            // Bight layer
            const bight = new FeatureLayer({
                url: "https://gis.sccwrp.org/arcserver/rest/services/Hosted/Bight_Strata_2018/FeatureServer",
                title: "Bight",
                outFields: ["*"]
            });

            // Stations layer
            let renderer = {
                type: "unique-value",
                field: "grp",
                uniqueValueInfos: [{
                    value: "Projects",
                    symbol: {
                        size: 3,
                        type: "simple-marker",
                        color: "red",
                        outline: null
                    },
                    label: "Projects"
                }, {
                    value: "Regional Monitoring",
                    symbol: {
                        size: 3,
                        type: "simple-marker",
                        color: "red",
                        outline: null
                    },
                    label: "Regional Monitoring"
                }]

            };
            const layer = new FeatureLayer({
                portalItem: {
                    id: "4ce8725b7968421eaa945025e2eca221"
                },
                title: "Stations",
                renderer: renderer,
                outFields: ["*"]
            });

            // County layer
            const countyLabel = ({
                symbol: {
                    type: "text",  // autocasts as new TextSymbol()
                    color: "white",
                    font: {  // autocast as new Font()
                        family: "Playfair Display",
                        size: 12,
                        weight: "regular"
                    }
                },
                labelPlacement: "above-center",
                labelExpressionInfo: {
                    expression: "$feature.NAME_PCASE"
                },
                deconflictionStrategy: "none"
            });
            const countyRend = {
                type: "simple",  // autocasts as new SimpleRenderer()
                symbol: {
                    type: "simple-fill",  // autocasts as new SimpleFillSymbol()
                    color: [0, 76, 115, 0.1],
                    outline: {  // autocasts as new SimpleLineSymbol()
                        width: 1,
                        color: "white"
                    }
                }
            };
            const county = new FeatureLayer({
                url: "https://gis.sccwrp.org/arcserver/rest/services/Hosted/Counties/FeatureServer",
                title: "County",
                renderer: countyRend,
                labelingInfo: countyLabel,
                outFields: ["*"]
            });

            const watershedLabel = ({
                symbol: {
                    type: "text",  // autocasts as new TextSymbol()
                    color: "white",
                    font: {  // autocast as new Font()
                        family: "Playfair Display",
                        size: 12,
                        weight: "bold"
                    }
                },
                labelPlacement: "above-center",
                labelExpressionInfo: {
                    expression: "$feature.HRNAME"
                },
                deconflictionStrategy: "none"
            });
            const waterRend = {
                type: "simple",  // autocasts as new SimpleRenderer()
                symbol: {
                    type: "simple-fill",  // autocasts as new SimpleFillSymbol()
                    color: [0, 200, 200, 0.3],
                    outline: {  // autocasts as new SimpleLineSymbol()
                        width: 0.5,
                        color: "black"
                    }
                }
            };
            const watersheds = new FeatureLayer({
                url: "https://gis.sccwrp.org/arcserver/rest/services/Hosted/California_Watersheds/FeatureServer",
                renderer: waterRend,
                title: "Watersheds",
                labelingInfo: watershedLabel
            });

            const rwqcbLabel = ({
                symbol: {
                    type: "text",  // autocasts as new TextSymbol()
                    color: "white",
                    font: {  // autocast as new Font()
                        family: "Playfair Display",
                        size: 12,
                        weight: "bold"
                    }
                },
                labelPlacement: "above-center",
                labelExpressionInfo: {
                    expression: "$feature.RBNAME"
                },
                deconflictionStrategy: "none"
            });
            const rwqcbRend = {
                type: "simple",  // autocasts as new SimpleRenderer()
                symbol: {
                    type: "simple-fill",  // autocasts as new SimpleFillSymbol()
                    color: [0, 76, 115, 0.1],
                    outline: {  // autocasts as new SimpleLineSymbol()
                        width: 2,
                        color: "brown"
                    }
                }
            };
            const rwqcb = new FeatureLayer({
                url: "https://gis.sccwrp.org/arcserver/rest/services/Hosted/Regional_Water_Quality_Control_Boards/FeatureServer", // Taken from sccwrp ArcOnline account
                title: "Regional Water Quality Control Boards", // naming layer as it'll be seen on the legend + layerlist dropdown menu
                renderer: rwqcbRend,
                labelingInfo: rwqcbLabel
            });

            // Setting up map
            const map = new Map({
                basemap: "satellite",
                layers: [watersheds, rwqcb, priority, county, bight, layer]
            });

            var view = new MapView({  // take that new map we just made above and display it
                container: "viewDiv",
                center: [-118.243683, 36.052235],
                zoom: 6,
                map: map,
                popup: {
                    autoOpenEnabled: false,
                    dockEnabled: true,
                    dockOptions: {
                        // dock popup at bottom-right side of view
                        buttonEnabled: true,
                        breakpoint: false,
                        position: "bottom-right"
                    }
                }
            });

            // Multiple layerlist function
            view.when(function () {

                // New Layerlist (dropdown)
                // Visble LABEL function
                // Function: if layerlist doesn't have exact layer name, take every other layer out of layerlist
                //workaround for making sure layerlist is ready
                var layerList = new LayerList({
                    view: view,
                    listItemCreatedFunction: function (event) {
                        const item = event.item;
                        item.actionsSections = [
                            [
                                {
                                    title: "Labels",
                                    className: "esri-icon-labels",
                                    id: "labels"
                                }
                            ]
                        ];
                    }
                });
                layerList.on("trigger-action", function (event) {
                    if (event.action.id === "labels") {
                        if (rwqcb.labelsVisible == false) {
                            rwqcb.labelsVisible = true;
                            console.log(rwqcb.labelsVisible);
                        } else {
                            rwqcb.labelsVisible = false;
                            console.log(rwqcb.labelsVisible);
                        }
                    }
                });
                watchUtils.when(layerList, 'operationalItems.length', function () {
                    var lis = query('li[aria-labelledby $= "__title"]', layerList.domNode);
                    lis.map(function (li) {
                        if (li.innerText !== "Regional Water Quality Control Boards") {
                            domStyle.set(li, "display", "none");
                        }
                    });
                });
                view.ui.add(layerList, "top-right");
                
                var layerList2 = new LayerList({
                    view: view,
                    listItemCreatedFunction: function (event) {
                        const item = event.item;
                        item.actionsSections = [
                            [
                                {
                                    title: "Labels",
                                    className: "esri-icon-labels",
                                    id: "labels2"
                                }
                            ]
                        ];
                    }
                });         
                layerList2.on("trigger-action", function (event) {
                    if (event.action.id === "labels2") {
                        if (watersheds.labelsVisible == false) {
                            watersheds.labelsVisible = true;
                            console.log(watersheds.labelsVisible);
                        } else {
                            watersheds.labelsVisible = false;
                            console.log(watersheds.labelsVisible);
                        }
                    }
                });
                watchUtils.when(layerList2, 'operationalItems.length', function () {
                    var lis = query('li[aria-labelledby $= "__title"]', layerList2.domNode);
                    lis.map(function (li) {
                        if (li.innerText !== "Watersheds") {
                            domStyle.set(li, "display", "none");
                        }
                    });
                });
                view.ui.add(layerList2, "top-right");

                var layerList3 = new LayerList({
                    view: view,
                    listItemCreatedFunction: function (event) {
                        const item = event.item;
                        item.actionsSections = [
                            [
                                {
                                    title: "Labels",
                                    className: "esri-icon-labels",
                                    id: "labels3"
                                }
                            ]
                        ];
                    }
                });         
                layerList3.on("trigger-action", function (event) {
                    if (event.action.id === "labels3") {
                        if (priority.labelsVisible == false) {
                            priority.labelsVisible = true;
                            console.log(priority.labelsVisible);
                        } else {
                            priority.labelsVisible = false;
                            console.log(priority.labelsVisible);
                        }
                    }
                });
                watchUtils.when(layerList3, 'operationalItems.length', function () {
                    var lis = query('li[aria-labelledby $= "__title"]', layerList3.domNode);
                    lis.map(function (li) {
                        if (li.innerText !== "Watershed Prioritization Recommended Actions") {
                            domStyle.set(li, "display", "none");
                        }
                    });
                });
                view.ui.add(layerList3, "top-right");

                var layerList5 = new LayerList({
                    view: view,
                    listItemCreatedFunction: function (event) {
                        const item = event.item;
                        item.actionsSections = [
                            [
                                {
                                    title: "Labels",
                                    className: "esri-icon-labels",
                                    id: "labels5"
                                }
                            ]
                        ];
                    }
                });         
                layerList5.on("trigger-action", function (event) {
                    if (event.action.id === "labels5") {
                        if (county.labelsVisible == false) {
                            county.labelsVisible = true;
                            console.log(county.labelsVisible);
                        } else {
                            county.labelsVisible = false;
                            console.log(county.labelsVisible);
                        }
                    }
                });
                watchUtils.when(layerList5, 'operationalItems.length', function () {
                    var lis = query('li[aria-labelledby $= "__title"]', layerList5.domNode);
                    lis.map(function (li) {
                        if (li.innerText !== "County") {
                            domStyle.set(li, "display", "none");
                        }
                    });
                });
                view.ui.add(layerList5, "top-right");
                
                var layerList4 = new LayerList({
                    view: view
                });         
                watchUtils.when(layerList4, 'operationalItems.length', function () {
                    var lis = query('li[aria-labelledby $= "__title"]', layerList4.domNode);
                    lis.map(function (li) {
                        if (li.innerText !== "Bight") {
                            domStyle.set(li, "display", "none");
                        }
                    });
                });
                view.ui.add(layerList4, "top-right");


                var layerList6 = new LayerList({
                    view: view
                });
                watchUtils.when(layerList6, 'operationalItems.length', function () {
                    var lis = query('li[aria-labelledby $= "__title"]', layerList6.domNode);
                    lis.map(function (li) {
                        if (li.innerText !== "Stations") {
                            domStyle.set(li, "display", "none");
                        }
                    });
                });
                view.ui.add(layerList6, "top-right");
            });

            var basemapGallery = new BasemapGallery({ // This right here provides the gallery of basemaps users can pull from. I think.
                view: view,
                container: document.createElement("div")
            });
            var bgExpand = new Expand({ // This gives users the ability to choose which basemap they want to use
                view: view,
                content: basemapGallery
            });
            var legend = new Expand({ // not gonna lie bro, I have no idea how this creates the legend.
                content: new Legend({
                    view: view,
                    style: "classic"
                }),
                view: view,
                expanded: true
            });
            view.ui.add(bgExpand, "top-left");
            view.ui.add(legend, "top-left");
        });
    </script>
</head>

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

</html>
0 Kudos