Select to view content in your preferred language

How to add generic popup templates for all FeatureLayers in all MapImageLayers in a map

164
8
Jump to solution
yesterday
PeterK
by
Occasional Contributor

Not a question but hopefully this will help someone who was struggling with the same issue.  The code below will add generic popupTemplates for all FeatureLayers in all MapImageLayers in a map.  This code should be run after you have added all of your layers to a map.  If someone can figure out how to expand this to include RasterLayers (if that is possible) that would be fantastic.  Since I'm still in the learning phase, any improvements or feedback would be appreciated.

require([
    "esri/config"
    , "esri/Map"
    , "esri/views/MapView"
    , "esri/layers/ImageryLayer"
    , "esri/layers/FeatureLayer"
    , "esri/identity/IdentityManager"
    , "esri/layers/MapImageLayer"
    , "esri/support/actions/ActionButton"
    , "esri/core/Collection"
    , "esri/geometry/Extent"
    , "esri/Basemap"]
    , function (
        esriConfig
        , Map
        , MapView
        , ImageryLayer
        , FeatureLayer
        , esriId
        , MapImageLayer
        , ActionButton
        , Collection
        , Extent
        , identify
        , IdentifyParameters
        , PopupTemplate
        , FieldInfo
        , Basemap
    ) {

        const arcgisMap = document.querySelector("arcgis-map");

        arcgisMap.addEventListener("arcgisViewReadyChange", (event) => {
            arcgisMap.map.addMany(['Add you MapImageLayers here...']);

            arcgisMap.map.layers.map(layer => {
                layer.load().then(function (layer) {
                    layer.sublayers.forEach(sublayer => {
                        sublayer.load().then(function (loadedSubLayer) {
                            var template = { type: "fields", fieldInfos: [] };
                            if (loadedSubLayer.fields != null) {
                                loadedSubLayer.fields.forEach((field) => {
                                    if (field.name.toLowerCase() != 'shape') {
                                        template.fieldInfos.push({ fieldName: field.name, label: field.name, isEditable: false, tooltip: "", visible: true, format: null, stringFieldOption: "text-box" });
                                    }
                                });
                                loadedSubLayer.popupEnabled = true;
                                loadedSubLayer.popupTemplate = {
                                    title: layer.title + ': ' + loadedSubLayer.title,
                                    content: [template]
                                }
                            }
                        });
                    });
                });
            });
        });
    });

  

0 Kudos
1 Solution

Accepted Solutions
UndralBatsukh
Esri Regular Contributor

Hi there, 

You need to load all sublayers from the MapImageLayer by calling loadAll() on the MapImageLayer instance as shown below:

layer.loadAll().then(() => {
  layer.sublayers.map((sublayer) => {
    sublayer.popupTemplate = sublayer.createPopupTemplate();
  });
 });

This codepen shows how to setup popupTemplate for sublayers - https://codepen.io/U_B_U/pen/QwbrLXO?editors=100

Hope this helps,

-Undral

View solution in original post

0 Kudos
8 Replies
JeffreyThompson2
MVP Frequent Contributor

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

Maybe you missed the defaultPopupTemplateEnabled property?

GIS Developer
City of Arlington, Texas
0 Kudos
PeterK
by
Occasional Contributor

Couldn't figure out how to do that for all FeatureLayers inside a MapImageLayer.  If you have an example I would appreciate it.

0 Kudos
JeffreyThompson2
MVP Frequent Contributor

https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-Sublayer.html#popu...

Any layer that does not have a defined popupTemplate should automatically get a default popup with defaultPopupTemplateEnabled = true. 

To answer your question: Raster layers do not support popups at all.

GIS Developer
City of Arlington, Texas
0 Kudos
PeterK
by
Occasional Contributor

Thank you for the reply.  In the online reference, it does not show any property or method for Popups for MapImageLayer.   My map has only MapImageLayers in it. 

I tried this and it didn't work:

arcgisMap.view.popup.defaultPopupTemplateEnabled = true;

arcgisMap.map.layers.map(layer => {
    layer.when(() => {
        var mapFeatureLayers = [];
        layer.sourceJSON.layers.forEach((sublayer) => {
            if (sublayer.type == 'Feature Layer') {
                sublayer.popupEnabled = true;
            }
        });
    })
});

 

For ImageryLayers, I do see references to popups so I'm not sure how that would work with those types of layers.

0 Kudos
JeffreyThompson2
MVP Frequent Contributor

Looking at your code, I think your fundamental problem may have been not loading the Popup module. Calling this should be all you need to do:

arcgisMap.popup = new Popup({
    defaultPopupTemplateEnabled: true
})

Additionally, the type for a subtype is always 'subtype', so the if statement above will never be entered.

Yes, it is possible to have popups on a ImageryLayer, but I don't know enough about them to say what you need to do to make them work. 

GIS Developer
City of Arlington, Texas
0 Kudos
PeterK
by
Occasional Contributor

Thank you for your response.  What you reference in your last post works fine if I have added a FeatureLayer to the map but not for a MapImageLayer.

On the link you posted above (https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Popup.html#defaultPopupTe... it says this about the layers that are supported, it doesn't mention MapImageLayers:  

"Supported for FeatureLayer, GeoJSONLayer, OGCFeatureLayer, SceneLayer, CSVLayer, PointCloudLayer, StreamLayer, ImageryLayer, and VoxelLayer"

I was able to get the popup working for an ImageryLayer but not for Raster Layers embedded in a MapImageLayer.

0 Kudos
UndralBatsukh
Esri Regular Contributor

Hi there, 

You need to load all sublayers from the MapImageLayer by calling loadAll() on the MapImageLayer instance as shown below:

layer.loadAll().then(() => {
  layer.sublayers.map((sublayer) => {
    sublayer.popupTemplate = sublayer.createPopupTemplate();
  });
 });

This codepen shows how to setup popupTemplate for sublayers - https://codepen.io/U_B_U/pen/QwbrLXO?editors=100

Hope this helps,

-Undral

0 Kudos
PeterK
by
Occasional Contributor

Thank you UndralBatsukh, your solution is much more straight forward than mine.  I edited my original post but this is much better!

0 Kudos