TOC/Legend Widget and sub layer popups

1450
10
11-15-2013 08:04 AM
PatKeegan
Occasional Contributor
The wicked awesome TOC/Legend Widget allows users to change visibility of sub layers, but it does not control the popup on sub layers. This means a sub layer can be turned off but that sub layer's popup will still appear on a map click.

Any advice on how to use this tool to also control sub layer popup visibility?

This is the widget i am referring to:
https://wheaton.maps.arcgis.com/home/item.html?id=9b6280a6bfb0430f8d1ebc969276b109#

Much thanks!
0 Kudos
10 Replies
KenBuja
MVP Esteemed Contributor
Are you using an IdentifyTask to get the features on a map click? If so, the IdentifyParameters has two properties that will control which sublayers will be returned. Use layerIds to set them manually or set layerOption to LAYER_OPTION_VISIBLE to only show the visible layers.

I've used the TOC in my project and have no issue in getting only getting the features from the visible layers in a popup. I set the layerIds property to the layer's visibleLayers property on each map click

map.on("click", executeIdentifyTask);

    function executeIdentifyTask(evt) {
        map.graphics.clear();
        layerClickGraphic.clear();
        layerResultsGraphic.clear();

        identifyParams.geometry = evt.mapPoint;
        identifyParams.mapExtent = map.extent;
        identifyParams.layerIds = layerDynamic.visibleLayers;

        layerClickGraphic.add(new esri.Graphic(evt.mapPoint, symbolClick));

        identifyTask.execute(identifyParams, function (results) { populateTC(results, evt); });
    }
0 Kudos
PatKeegan
Occasional Contributor
I am not using the IdentifyTask, I was hoping not to override the response.clickEventHandle in the AGOL webmap. I have all the popups defined in AGOL and I am trying to avoid manually coding popups.

Thanks!
0 Kudos
deleted-user-1T_bOHag6M8d
Occasional Contributor
I am not using the IdentifyTask, I was hoping not to override the response.clickEventHandle in the AGOL webmap. I have all the popups defined in AGOL and I am trying to avoid manually coding popups.

Thanks!


Hi Pat, I'm facing the same issue. Did you discover a solution?
0 Kudos
PatKeegan
Occasional Contributor
I sorta found a solution. It is a bit convoluted and involved overriding the response.clickEventHandle of the AGOL webmap.

I created global var that includes popup info from AGOL.

  
  //added global var to handle TOC popups
    if (configOptions.custPopup === "TOC") {  
      operationalLayers = response.itemInfo.itemData.operationalLayers;
      dojo.forEach(operationalLayers, function(layer) {
        dojo.forEach(layer.layers, function(sublayer) {
          dojo.forEach(sublayer.popupInfo.fieldInfos, function(fieldInfo) {
            //move alias values into fieldname so it will work as fieldInfo
            fieldInfo.fieldName = fieldInfo.label;
          }); 
        }); 
      });  
    }


Then i added function to execute ID task using the AGOL popups.


function executeTOCIdentifyTask(evt) {
 
 //set the visible layers for the ID
 var layers = [];
 dojo.forEach(toc.layerInfos[0].layer._tocInfos, function(layer) {
  if (layer.visible) {
   layers.push(layer.id);
  }
 });

    if (layers.length > 0) {

     identifyParams.geometry = evt.mapPoint;
     identifyParams.mapExtent = map.extent;
     identifyParams.tolerance = 9;
     identifyParams.returnGeometry = true;
     identifyParams.layerIds = layers;
     identifyParams.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_VISIBLE;
     identifyParams.width = map.width;
     identifyParams.height = map.height;
     identifyParams.timeExtent = map.timeExtent;
    
     var deferred = identifyTask.execute(identifyParams);
     deferred.addCallback(function(response) {
      
      return dojo.map(response, function(result) {
       var feature = result.feature;
       var template;
    
       dojo.forEach(operationalLayers[0].layerObject.layerInfos, function(layer) {
        //get the right layer from operationalLayers
        if (result.layerName == layer.name) {
         //get the right popup from operationalLayers
         dojo.forEach(operationalLayers[0].layers, function(popup) {
          if (popup.id == layer.id) {
           template = new esri.dijit.PopupTemplate({
            title: popup.popupInfo.title,
            fieldInfos: popup.popupInfo.fieldInfos,
            showAttachments : popup.popupInfo.showAttachments
           });
          }
         });
        }
       });   
    
       feature.setInfoTemplate(template);
       return feature;
      });
     });
    
     map.infoWindow.setFeatures([deferred]);
     map.infoWindow.show(evt.mapPoint);

    }
    
}
0 Kudos
deleted-user-1T_bOHag6M8d
Occasional Contributor
I sorta found a solution. It is a bit convoluted and involved overriding the response.clickEventHandle of the AGOL webmap.

I created global var that includes popup info from AGOL.

  
  //added global var to handle TOC popups
    if (configOptions.custPopup === "TOC") {  
      operationalLayers = response.itemInfo.itemData.operationalLayers;
      dojo.forEach(operationalLayers, function(layer) {
        dojo.forEach(layer.layers, function(sublayer) {
          dojo.forEach(sublayer.popupInfo.fieldInfos, function(fieldInfo) {
            //move alias values into fieldname so it will work as fieldInfo
            fieldInfo.fieldName = fieldInfo.label;
          }); 
        }); 
      });  
    }


Then i added function to execute ID task using the AGOL popups.


function executeTOCIdentifyTask(evt) {
 
 //set the visible layers for the ID
 var layers = [];
 dojo.forEach(toc.layerInfos[0].layer._tocInfos, function(layer) {
  if (layer.visible) {
   layers.push(layer.id);
  }
 });

    if (layers.length > 0) {

     identifyParams.geometry = evt.mapPoint;
     identifyParams.mapExtent = map.extent;
     identifyParams.tolerance = 9;
     identifyParams.returnGeometry = true;
     identifyParams.layerIds = layers;
     identifyParams.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_VISIBLE;
     identifyParams.width = map.width;
     identifyParams.height = map.height;
     identifyParams.timeExtent = map.timeExtent;
    
     var deferred = identifyTask.execute(identifyParams);
     deferred.addCallback(function(response) {
      
      return dojo.map(response, function(result) {
       var feature = result.feature;
       var template;
    
       dojo.forEach(operationalLayers[0].layerObject.layerInfos, function(layer) {
        //get the right layer from operationalLayers
        if (result.layerName == layer.name) {
         //get the right popup from operationalLayers
         dojo.forEach(operationalLayers[0].layers, function(popup) {
          if (popup.id == layer.id) {
           template = new esri.dijit.PopupTemplate({
            title: popup.popupInfo.title,
            fieldInfos: popup.popupInfo.fieldInfos,
            showAttachments : popup.popupInfo.showAttachments
           });
          }
         });
        }
       });   
    
       feature.setInfoTemplate(template);
       return feature;
      });
     });
    
     map.infoWindow.setFeatures([deferred]);
     map.infoWindow.show(evt.mapPoint);

    }
    
}


Thanks, Pat! This is very helpful!
0 Kudos
SimonRoss_User
Occasional Contributor
Pat

This looks like exactly what I need but I can't see exactly how to get it to work in my application.  We have a modified version of the ESRI Basic Viewer Template with the TOC widget up and running

I'm not clear on a few things that hopefully you can provide some more detail on

1. How to ovverride the response.clickeventhandle
2. Where this code should be inserted (I'm assuming in the main layout.js rather than in the TOC.js)
3. how to call the executeTOCIdentifyTask function

Any help would be greatly appreciated
Thanks

Simon
0 Kudos
SimonRoss_User
Occasional Contributor
Pat

This looks like exactly what I need but I can't see exactly how to get it to work in my application.  We have a modified version of the ESRI Basic Viewer Template with the TOC widget up and running

I'm not clear on a few things that hopefully you can provide some more detail on

1. How to ovverride the response.clickeventhandle
2. Where this code should be inserted (I'm assuming in the main layout.js rather than in the TOC.js)
3. how to call the executeTOCIdentifyTask function

Any help would be greatly appreciated
Thanks

Simon


I can see I'm also missing the definition of IdentifyTask - how do you do this for a webmap rather than with a url as a parameter?
0 Kudos
SimonRoss_User
Occasional Contributor
So I believe I've made some progress with this but still needing a few pointers 🙂

I've created a stripped down version of the basic viewer and have a very basic working application pulling a public webmap and using the TOC widget (there are some issues with the tOC widget functionality itself I want to resolve but I believe I know what to do there)

I've disabled the default click event handler so default popups are no longer appearing but I can't work out how to connect up a new onClick event to point to the custom identify task.  I've attached a full copy of the code.  No changes have been made to the TOC.js.  all code is in javascript/layout.js

Line 138 - disconnect existing click event handler
Line 139 - attempted to connect onClick event
Line 365 - initate TOC
Line 404 - identify task function

I'm fairly new to JavaScript so please bear with me with any major/stupid errors.  One final question.  If I understand the identify code correctly then it is only looking at a single operationalLayer (Line 433: "operationalLayers[0]") so I'll need to add in an additional loop to manage multiple operational layers?
Thanks in advance

Simon
0 Kudos
SimonRoss_User
Occasional Contributor
Looks like I've resolved all issues.  I'll post up some helpful tips once I've done final troubleshooting on the code (Pat - please ignore my private message and thanks very much for getting me started!)
0 Kudos