Feature Widget access multiple layers with PortalItemID

1642
12
Jump to solution
06-18-2019 06:46 AM
MarquesMunson1
Occasional Contributor

I am using JavaScript 4.11 and I am trying to get the Feature Widget to access the popupTemplate for each layer that is under the same portalItem ID. So far the widget can only access one of the layers. Is there a way to write the code to have the widget access all of the items? I have the code below.

<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">

<title>ArcGIS API for JavaScript Adoption Statistics Prototype</title>

<style>
html, body, #viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
/*******STYLE FOR THE HOVER FEATURE */
.esri-feature {
letter-spacing: 0em;
font-family: "Oswald", sans-serif;
line-height: 1.55rem;
font-feature-settings: "liga" 1, "calt" 0;
background: fff;
padding: 1em;
}

</style>

<!------------REFERECING ESRI CDN FOR JAVASCRIPT 4.11------------->
<link rel="stylesheet" href="https://js.arcgis.com/4.11/esri/css/main.css">
<script src="https://js.arcgis.com/4.11/"></script>

<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/FeatureLayer", //Adding feature layer to the application using FeatureLayer module
"esri/widgets/Legend", //Adding Legend to the application
"esri/widgets/LayerList",
"esri/widgets/Feature"
], function(Map, MapView, FeatureLayer, Legend, LayerList, Feature) { //functions must match the require statements

/***************SETTING THE BASEMAP*********** */
var map = new Map({
basemap: "dark-gray-vector", //specify the type of basemap (gray, topo, streets, dark-gray, etc)
});

/*************** CONTAINER FOR THE ACTUAL MAP WITH DIMENSIONS*********** */

var view = new MapView({
container: "viewDiv",
map: map,
center: [-25.432,34.09042], //longitude, latitude--- this is the center location of the map
zoom: 2 //zoom level, lower number = more zoomed out
});

/*************** ADDING LAYERS TO THE MAP*********** */
var adoptionstats = new FeatureLayer({
portalItem: {
id: "e5683bb09bad438aae49eef2a8796296"
}
});


map.add(adoptionstats, 0); // the zero is for adding order, since only one layer technically do not need this



/***************ADD FEATURE POP UP HERE*************************/

view.when().then(function() {
var legend = new Legend({
view: view
});
view.ui.add(legend, "bottom-left");

var layerList = new LayerList({
view: view
});

// Add widget to the top right corner of the view
view.ui.add(layerList, "top-right");

// Create a default graphic for when the application starts
var graphic = {
popupTemplate: {
content: "Mouse over features to show details..."
}
};

// Provide graphic to a new instance of a Feature widget
var feature = new Feature({
graphic: graphic,
view: view
});

view.ui.add(feature, "bottom-right");

view.whenLayerView(adoptionstats).then(function(layerView) {
let highlight;
// listen for the pointer-move event on the View
view.on("pointer-move", function(event) {
// Perform a hitTest on the View
view.hitTest(event).then(function(event) {
// Make sure graphic has a popupTemplate
let results = event.results.filter(function(result) {
return result.graphic.layer.popupTemplate;
});
let result = results[0];
highlight && highlight.remove();
// Update the graphic of the Feature widget
// on pointer-move with the result
if (result) {
feature.graphic = result.graphic;
highlight = layerView.highlight(result.graphic);
} else {
feature.graphic = graphic;
}
});
});
});
});

/****************END FEATURE POP UP HERE */


});
</script>
</head>

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

</html>
0 Kudos
1 Solution

Accepted Solutions
KellyHutchins
Esri Frequent Contributor
12 Replies
DavidWilson3
Occasional Contributor

Hi Marques,

You could use the layerId property to access other layers with in the portal item or service. Here is an example:

// loads the third layer in the given Portal Item

const layer = new FeatureLayer( 

   portalItem: {

      id: "8d26f04f31f642b6828b7023b84c2188"

   },

   layerId: 2

});

MarquesMunson1
Occasional Contributor

Hi David,

Thank you for your reply! I have tried that and it only accesses one layer at a time. I would like it so that each layer is showing in the Layer list and the widget works with each layer as I turn them on/off respectively. Apologies if I did not explain that in the initial post.

0 Kudos
DavidWilson3
Occasional Contributor

Marques,

In that case a work around I can think of is to make a GroupLayer with the individual layerId-layers/portal-items and add that GroupLayer to the map instead of the indivdual portal items. This method will also allow you to have more customization control when making certain layers visible or not and if you want to add actions to the LayerList such as decreasing opacity of a layer or GroupLayer.

KellyHutchins
Esri Frequent Contributor

Here's one approach you could use: JS Bin - Collaborative JavaScript Debugging 

MarquesMunson1
Occasional Contributor

Yes!!! thank you so much!!!

0 Kudos
MarquesMunson1
Occasional Contributor

would I use the visibilityMode to manage only having one layer visibile at a time?

0 Kudos
DavidWilson3
Occasional Contributor

Hi Marques,

If you set the visibilityMode of the GroupLayer to "independent" then it will treat child layers independently and allow you to click on and off on the child layers. Also if you declare each layer as a separate layer you can set their visibility as false or true if you want to initially show specific layers on startup.

Here is documentation on GroupLayer and its properties: GroupLayer | ArcGIS API for JavaScript 4.11 

0 Kudos
MarquesMunson1
Occasional Contributor

So would it be something like the following....(apologies I am learning JS as I go along)

Layer.fromPortalItem({
portalItem: {
id: "e5683bb09bad438aae49eef2a8796296",

visibilityMode: "independent",
// portal ID number
},
layerId: 2,
visible: false

}).then(function (groupLayer) { // adding all layers into a group layer


var map = new Map({
basemap: "dark-gray-vector",
layers: groupLayer //adding group layer to the map
});
0 Kudos
DavidWilson3
Occasional Contributor

Hi Marques,

I have redone the code for you here: JS Bin - Collaborative JavaScript Debugging  

You can further edit the GroupLayer and the individual layers as you want from here. You can also create actions for the LayerList, like decreasing opacity if you so wish.