Select to view content in your preferred language

NLiu's Table of Contents(TOC)/Legend widget and Visibility States

4114
27
Jump to solution
03-09-2012 04:21 AM
AlexDeVine
Occasional Contributor
Hi Forum,

I am using NLiu's TOC Widget in a web application I am developing: http://www.arcgis.com/home/item.html?id=9c43bdf76a23452ba1d95684f7cd76d8

It is a great widget and it is working great, except one thing... I also have an Identify task that I would like to be able to only have work on the visible layers, but as the widget is handling the visibility, it has effectively "blackboxed" the layer visibility state for me. I was hoping to be able to obtain an array from the TOC widget and feed that to my identify task so that it had the latest info on what should be returned, but I am stymied. Any tips?

Thank you, in advance, for any help.

Alex DeVine
University of Georgia
0 Kudos
27 Replies
DavidBoyd
Emerging Contributor
You do not need the TOC to tell you which layer is visible.
For service level layer, you should be using Layer.visible. For layers underneath a dynamic map service, use ArcGISDynamicMapServiceLayer.visibleLayers.


My web map includes one dymanamic mapservice with 13 layers, all listed in the TOC and most used in the identify.  I want to do the same thing...only identify on layers that are visible, or checked in the TOC.  I think this reply would work for me, but I don't quite follow it (still learning).  If someone could explain a little more I think I can get there.  I don't understand what nliu meant with "using layer.visible" or "using ArcGISDynamicMapServiceLayer.visibleLayers".  Would this be a parameter with the identify function?  Any clarification would be greatly appreciated!  Thanks.
0 Kudos
CraigMcDade
Deactivated User
My web map includes one dymanamic mapservice with 13 layers, all listed in the TOC and most used in the identify.  I want to do the same thing...only identify on layers that are visible, or checked in the TOC.  I think this reply would work for me, but I don't quite follow it (still learning).  If someone could explain a little more I think I can get there.  I don't understand what nliu meant with "using layer.visible" or "using ArcGISDynamicMapServiceLayer.visibleLayers".  Would this be a parameter with the identify function?  Any clarification would be greatly appreciated!  Thanks.


Here is a fiddle done by another user that was very helpful in figuring out how to combine the TOC widget and identify from multiple services/layers when visible.
0 Kudos
KevinMacLeod1
Frequent Contributor
Hi all, I think I just worked on something similar. I used Nianwei's TOC widget, which is awesome.

I wanted an "identify' basically like the Identify in ArcMap that just works, and shows us all attribs. for all visible layers.

We had a REST endpoint with hundreds of layers, that I'd put into an .msd in ArcMap, rolling them up by grouping them in ArcMap just for use with AGSJS TOC widget.

So they display in the TOC great.

Then, I used the Identify logic from here, this example identifies ALL layers:

http://jsfiddle.net/URpaW/

Now, all you need to do to identify only visible layers (not all as in the sample) is put the following line in, in the IdentifyParams section:

  identifyParams.layerIds = YOURLAYERNAME.visibleLayers;


where YOURLAYERNAME is the variable that you assigned your dynamic layer service to that has all your layers (i.e. the URL to the root REST endpoint, where it ends in mapserver/ , as this is just a variable you assigned your DynamicLayer to )



Now... if anyone can help take this to the finish line.. I would like to have the title of the popup (up in the top of the infoWindow) say what each layer is. In the bottom of each infoWindow I see "layerName" then the name of the layer. Interestingly this isn't an attribute. I guess it's just a built in part of a REST service layer? But I want THAT as my title. So I put this following line in


                var infoTemplate = new esri.InfoTemplate('${layerName}', "${*}");


I also tried r.layerName. Nothing appears in the title of the infowindow. However the infowindow still comes up at least, with all the attributes. So if someone solves that I think this is the solution it looks like we are looking for, here...


Here is the inline code from my javascript file if anyone would like to look or borrow:


//// Identify Widget ////

    var popup = new esri.dijit.Popup({ fillSymbol: new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255, 0, 0]), 2), new dojo.Color([255, 255, 0, 0.25]))}, dojo.create("div"));


    dojo.connect(map,'onLoad',function(){
        //setup generic identify parameters 
        identifyParams = new esri.tasks.IdentifyParameters();
        identifyParams.tolerance = 5;
        identifyParams.returnGeometry = true;
        identifyParams.layerIds = KSAVDynamicLayersALL.visibleLayers;

        dojo.connect(map,'onClick',doIdentify);
    });

 


   
    dojo.connect(map,'onLayersAddResult', setupIdentify);


function setupIdentify(results){
    //loop through operational layers and add identify task for each. 
    tasks = dojo.map(results,function(result){
        return new esri.tasks.IdentifyTask(result.layer.url);
    });


}
function doIdentify(evt){

    map.infoWindow.hide();
    clickPoint = evt.mapPoint;

    identifyParams.geometry = evt.mapPoint;
    identifyParams.mapExtent = map.extent;
    identifyParams.width  = map.width;
    identifyParams.height = map.height;

    var deferreds = dojo.map(tasks,function(task){
        return task.execute(identifyParams);
    });
    var dlist = new dojo.DeferredList(deferreds);
    dlist.then(handleQueryResults);

}
function handleQueryResults(results){

    var features = [];
    dojo.forEach(results,function(result){
        // for a simplified test let's just display all the attributes in the popup 
        if(result[1].length > 0){
            dojo.forEach(result[1],function(r){
                var feature = r.feature;
                console.log(feature);
                feature.attributes.layerName =r.layerName;

                var infoTemplate = new esri.InfoTemplate('${r.layerName}', "${*}");
                feature.setInfoTemplate(infoTemplate);
                features.push(feature);
                ///// NOTE the above infoTemplate isn'try working in that "layerName' should be the layer's name. I want a layer //name like "Water Mains" to be in the title of the popup InfoWindow. Not working. i need to maybe make a variable that is //LayersALL.layerName as an array or something

            });
        }

    });
    map.infoWindow.setFeatures(features);
    map.infoWindow.show(clickPoint);

}


    //// ^^^  Identify Widget ////
0 Kudos
ZhujingXia
Frequent Contributor

K M,

Did you find the way to pass the dynamic layer automatically dependent on the map service the toc use or the the mouse clicked on. I used this toc widget with 4 map services, but I can not figure out how to let the program know which map service the identify is going to use. I could  use YOURLAYERNAME to pass the map service, but only can hard code it one map service. Is there a way to know which map service is using dynamically?

identifyParams.layerIds = YOURLAYERNAME.visibleLayers; 

Thanks

Zhujing

  
0 Kudos
CraigMcDade
Deactivated User
This probably should have been split into a new thread... but. This is what I do:

I use a popup to set a title so my code is something like this...

 var feature = result.feature;
        feature.attributes.layerName = result.layerName;
        if (result.layerName === 'Zoning Classifications') {
            console.log(feature.attributes.NAME);
            var template = new esri.dijit.PopupTemplate({
                title: "Zoning",
                description: "<b>Zoning:</b> {Zoning Classification} <br/> <b>Description:</b> {Zoning Description}"
            });
            feature.setInfoTemplate(template);

return feature;
});
if (results.length === 0) {
        map.infoWindow.clearFeatures();
    } else {
        map.infoWindow.setFeatures(results);
    }
    map.infoWindow.show(idParams.geometry);
    return results;
}



You'll need to set up your popup with code similar to:
var popup = new esri.dijit.Popup({
                    fillSymbol: new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255, 0, 0]), 2), new dojo.Color([255, 255, 0, 0.25]))
                }, dojo.create("div"));

                map = new esri.Map("map", {
                    infoWindow: popup,
                    extent: startExtent,
                    logo: false
                });


making sure to call:

dojo.require("esri.dijit.Popup");
0 Kudos
KevinMacLeod1
Frequent Contributor
Thanks mcdade.  I want to display all visible layers in a popup, displaying all features in the click tolerance (multiple coincident featurse with the arrows in the upper-right of infowindow). However this overwrites a set title so I'll have to put it into the infowindow content apparently.

So far I have this almost working. I had some basemap layers (ESRI's basemaps and imagery) and they were showing up in the infowindows below even though I'd set it to only display visible layers. I moved them below the Identify widget code and they are gone which is good.

But I still have layers show up that are not visible at a certain scale. (I set scale dependencies in the ArcMap MXD/MSD). I have to manually turn them off in the AGS TOC widget.

//// Identify Widget ////
        var identifyParams;
        var tasks;
        var clickPoint;

            //var popup = new esri.dijit.Popup({ fillSymbol: new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255, 0, 0]), 2), new dojo.Color([255, 255, 0, 0.25]))}, dojo.create("div"));


        dojo.connect(map, 'onLoad', function () {
            //setup generic identify parameters 
            identifyParams = new esri.tasks.IdentifyParameters();
            identifyParams.tolerance = 5;
            identifyParams.returnGeometry = true;
            identifyParams.layerIds = MYDYNAMICLAYER.visibleLayers;
            identifyParams.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_VISIBLE;

            dojo.connect(map, 'onClick', doIdentify);
        });





        dojo.connect(map, 'onLayersAddResult', setupIdentify);


        function setupIdentify(results) {
            //loop through operational layers and add identify task for each. 
            tasks = dojo.map(results, function (result) {
                return new esri.tasks.IdentifyTask(result.layer.url);
            });


        }
        function doIdentify(evt) {

            map.infoWindow.hide();
            clickPoint = evt.mapPoint;

            identifyParams.geometry = evt.mapPoint;
            identifyParams.mapExtent = map.extent;
            identifyParams.width = map.width;
            identifyParams.height = map.height;
            identifyParams.layerIds = MYDYNAMICLAYER.visibleLayers;
            identifyParams.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_VISIBLE;

            var deferreds = dojo.map(tasks, function (task) {
                return task.execute(identifyParams);
            });
            var dlist = new dojo.DeferredList(deferreds);
            dlist.then(handleQueryResults);

        }
        function handleQueryResults(results) {

            var features = [];
            dojo.forEach(results, function (result) {
                // for a simplified test let's just display all the attributes in the popup 
                if (result[1].length > 0) {
                    dojo.forEach(result[1], function (r) {
                        var feature = r.feature;
                        console.log(feature);
                        feature.attributes.layerName = r.layerName;


                        var infoTemplate = new esri.InfoTemplate("${name}", "${*}");
                        

                        feature.setInfoTemplate(infoTemplate);
                        features.push(feature);

                    });
                }

            });
            map.infoWindow.setFeatures(features);
            map.infoWindow.show(clickPoint);

        }


        //// ^^^  Identify Widget ////
0 Kudos
ZhujingXia
Frequent Contributor

Hi,

It seems this TOC only can have 2 Dynamic map services show in the TOC window, Is there a way to show more dynamic map services?

Thanks

Zhujing

0 Kudos
KenBuja
MVP Esteemed Contributor

You can have as many services as you'd like. You have to add them into the layerInfos object as described in the documentation.

0 Kudos
ZhujingXia
Frequent Contributor

Ken,

In my application, no any map service show in the legend window after I add in the third map service to the layerInfos, but i could add in any 2 of the map services in different ways.

What do you think the problem is?

Thanks

Zhujing

>>> Ken Buja <geonet@esri.com> 9/25/2014 3:53 PM >>>

Ken Buja replied to the discussion

"NLiu's Table of Contents(TOC)/Legend widget and Visibility States"

To view the discussion, visit: https://community.esri.com/message/425141?et=watches.email.thread#425141

0 Kudos
KenBuja
MVP Esteemed Contributor

Can you post your code or create a Fiddle to show what's going on?

0 Kudos