2

I am trying to have one infowindow/popup show from multiple services. I have successfully added the second service to my code, however, only 1 result will display.

Ex. if I am at full scale, only the zoning layer is returned in the popup. If I zoom in, only the parcel layer is returned in the popup.

How can I get both services to show within the popup? Additionally, how can I make it so only the visible layers show within the popup?

Here is the code I have edited:

dojo.require("esri.dijit.Popup"); //Infowindow

var identifyTask,identifyParams;    

  function mapReady(map){

   dojo.connect(map,"onClick",executeIdentifyTask);

   //create identify tasks and setup parameters 
   identifyTaskZoning = new esri.tasks.IdentifyTask("https://www.marioncountyfl.org/arcgis/rest/services/Dynamic/Zoning/MapServer");
   identifyTaskParcels = new esri.tasks.IdentifyTask("https://www.marioncountyfl.org/arcgis/rest/services/Dynamic/Parcels/MapServer");

        //Set Zoning Parameters
   identifyParamsZoning = new esri.tasks.IdentifyParameters();
   identifyParamsZoning.tolerance = 7;
   identifyParamsZoning.returnGeometry = true;
   identifyParamsZoning.layerIds = [0,1,2,3,4];
   identifyParamsZoning.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_VISIBLE;
   identifyParamsZoning.width  = map.width;
   identifyParamsZoning.height = map.height;
        //Set Parcel Parameters
   identifyParamsParcels = new esri.tasks.IdentifyParameters();
   identifyParamsParcels.tolerance = 15;
   identifyParamsParcels.returnGeometry = true;
   identifyParamsParcels.layerIds = [0,1,2,3,4];
   identifyParamsParcels.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_VISIBLE;
   identifyParamsParcels.width  = map.width;
   identifyParamsParcels.height = map.height;

   //resize the map when the browser resizes
   dojo.connect(dijit.byId('map'), 'resize', map,map.resize);
  };

  function executeIdentifyTask(evt){
 identifyParamsParcels.geometry = evt.mapPoint;
 identifyParamsParcels.mapExtent = map.extent;
 var deferred = identifyTaskParcels.execute(identifyParamsParcels);
 deferred.addCallback(function(response){
   if (response.length > 0) {
//         console.log(response.length)
//         response is an array of identify result objects    
//         Let's return an array of features.
    return dojo.map(response, function(result){
      var feature = result.feature;
      feature.attributes.layerName = result.layerName;
      if(result.layerName === 'TaxParcel'){
          console.log(feature.attributes.NAME);
          var template = new esri.dijit.PopupTemplate({
                        title:"Parcels",
                        description:"<b>Parcel ID:</b> {Parcel Identification Number} <br/> <b>Address:</b> {Site Address}"
                        });
          feature.setInfoTemplate(template);
        }

            return feature;
    });
    }
  else {
      identifyParamsZoning.geometry = evt.mapPoint;
      identifyParamsZoning.mapExtent = map.extent;
      var deferred = identifyTaskZoning.execute(identifyParamsZoning);
      deferred.addCallback(function(response){
        // response is an array of identify result objects    
        // Let's return an array of features.
        return dojo.map(response, function(result){
          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);
        }
        else if (result.layerName === 'Assisted Living Facilities'){
          var template = new esri.dijit.PopupTemplate({
                        title:"Assisted Living Facilities",
                        description:"<b>Parcel ID:</b> {Parcel} <br/> <b>Applicant:</b> {BusinessApplicantName} <br/> <b>No. of Residents</b> {NbrResidents}"
                        });
          feature.setInfoTemplate(template);
        }
                    else if (result.layerName === 'Family Divisions'){
          var template = new esri.dijit.PopupTemplate({
                        title:"Family Divisions",
                        description:"<b>Parcel ID:</b> {Parcel} <br/> <b>Project Number:</b> {project_nbr} </br> <b>Status:</b> {Status}"
                        });
          feature.setInfoTemplate(template);
        }
                    else if (result.layerName === 'Policy 120'){
          var template = new esri.dijit.PopupTemplate({
                        title:"Policy 120",
                        description:"<b>Parcel ID:</b> {Parcel} <br/> <b>Business Name:</b> {BusinessName} </br> <b>Date of Letter:</b> {DateOfLetter}"
                        });
          feature.setInfoTemplate(template);
        }
                    else if (result.layerName === 'Zoning Changes'){
          var template = new esri.dijit.PopupTemplate({
                        title:"Zoning Changes",
                        description:"<b>Parcel ID:</b> {Parcel} <br/> <b>Request Number:</b> {REQUEST_NBR} </br> <b>Property Owner:</b> {PROPERTY_OWNER}"
                        });
          feature.setInfoTemplate(template);
        }
        return feature;
        });
      });
  };
    map.infoWindow.setFeatures([deferred]);
    map.infoWindow.show(evt.mapPoint);          
  });
    map.infoWindow.setFeatures([deferred]);
    map.infoWindow.show(evt.mapPoint);      
  };

1 Answer 1

2

Check out this blog entry I wrote about identifying multiple services with dojo DeferredList. It address only the visible layers. Once you have the result, you'll have to create a custom popup. http://www.spatialexception.org/posts/arcgis-javascript-identifytask-returns-scale-dependent-layers

Edit
I'm using jqueryUI to create widgets so I'm not sure if you want to use this, but here's the way I'm displaying. It's not really a popup, but more like an ArcMap Identify. The code needs to be cleaned up, e.g. get the html out of the javascript, but here it is...

<!-- html fragment -->

<!-- Use local custom theme copy of jQuery ui -->
<!-- http://docs.jquery.com/UI/Theming/API
To view and modify and re-download this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,%20Arial,%20sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=6px&bgColorHeader=444444&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=44&borderColorHeader=333333&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=000000&bgTextureContent=14_loop.png&bgImgOpacityContent=25&borderColorContent=555555&fcContent=ffffff&iconColorContent=cccccc&bgColorDefault=222222&bgTextureDefault=03_highlight_soft.png&bgImgOpacityDefault=35&borderColorDefault=444444&fcDefault=eeeeee&iconColorDefault=cccccc&bgColorHover=003147&bgTextureHover=03_highlight_soft.png&bgImgOpacityHover=33&borderColorHover=0b93d5&fcHover=ffffff&iconColorHover=ffffff&bgColorActive=0972a5&bgTextureActive=04_highlight_hard.png&bgImgOpacityActive=20&borderColorActive=26b3f7&fcActive=ffffff&iconColorActive=222222&bgColorHighlight=eeeeee&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=80&borderColorHighlight=cccccc&fcHighlight=2e7db2&iconColorHighlight=4b8e0b&bgColorError=ffc73d&bgTextureError=02_glass.png&bgImgOpacityError=40&borderColorError=ffb73d&fcError=111111&iconColorError=a83300&bgColorOverlay=5c5c5c&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=50&opacityOverlay=80&bgColorShadow=cccccc&bgTextureShadow=01_flat.png&bgImgOpacityShadow=30&opacityShadow=60&thicknessShadow=7px&offsetTopShadow=-7px&offsetLeftShadow=-7px&cornerRadiusShadow=8px
-->
<script type="text/javascript" src="js/jquery-ui-1.8.23.custom/js/jquery-1.8.0.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.8.23.custom/js/jquery-ui-1.8.23.custom.min.js"></script>
<link href="js/jquery-ui-1.8.23.custom/css/dark-hive/jquery-ui-1.8.23.custom.css" rel="stylesheet" type="text/css" />

<body>    
    <div id="dialogIdentify" title="Identify Features">
        <div id="accordionIdentify">
        </div>
    </div>
</body>

//javascript fragment

//at some point open the dialog to start
('#dialogIdentify').dialog('open');

$('#dialogIdentify').dialog({
    autoOpen: false,
    width: 320,
    height: 400,
    position: 'right',        
    open: function (event, ui) {
        startIdentify();
    },
    close: function (event, ui) {
        endIdentify();
    }
});

var identifyTask, identifyParams, symbol;
var identify_connect;
var resultsRefTemp, resultsOpTemp, numResultSets;

function startIdentify() {
    //$("#map_layers").css("cursor", "url(img/identify2.cur), crosshair");
    $("#accordionIdentify").append("<p>(Click on map to identify features)</p>");
    identify_connect = dojo.connect(map, "onClick", doIdentify);
}

function endIdentify() {
    //$("#map_layers").css("cursor", "auto");
    map.graphics.clear();
    $("#accordionIdentify").accordion("destroy");
    $("#accordionIdentify").empty();
    dojo.disconnect(identify_connect);
    $("#dialogIdentify").dialog("option", "position", ['right']);
    $('#accordionIdentify .identifyHL').off('click');
    identifyLayerKeyPrevious = undefined;
}

function executeIdentify(geom, serviceName, aLayerIds) {
    var identifyParams = new esri.tasks.IdentifyParameters(),
        identifyTask = new esri.tasks.IdentifyTask(serviceName);
    identifyParams.geometry = geom;
    identifyParams.mapExtent = map.extent;
    identifyParams.tolerance = 3;
    identifyParams.returnGeometry = true;
    identifyParams.layerIds = aLayerIds;
    //refers to default visible layers as defined on the server
    identifyParams.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_ALL;
    identifyParams.width = map.width;
    identifyParams.height = map.height;
    return identifyTask.execute(identifyParams);
}

function doIdentify(evt) {
    var geom = evt.mapPoint,
        aLayersInScale,
        aDeferreds = [],
        deferredList,
        currentScale = map.getScale(),
        aVisibleSubLayers,
        aAGSDynMapServicesToIdentify = [referenceLayer, operationalLayer];

    map.graphics.clear();
    identifyLayerKeyPrevious = undefined;

    //loop thru dynamic services, then thru visible sublayers that are not group layers, then check within scale
    dojo.forEach(aAGSDynMapServicesToIdentify, function (agsDynMapService) {
        aVisibleSubLayers = agsDynMapService.visibleLayers;
        if (agsDynMapService.visible === true && aVisibleSubLayers.length !== 0 && aVisibleSubLayers[0] !== -1) {
            aLayersInScale = [];
            dojo.forEach(agsDynMapService.createDynamicLayerInfosFromLayerInfos(), function (dLayInfo) {
                if (dLayInfo.subLayerIds === null && dojo.indexOf(aVisibleSubLayers, dLayInfo.id) !== -1 &&
                        (dLayInfo.minScale === undefined || dLayInfo.minScale === 0 || currentScale <= dLayInfo.minScale) &&
                        (dLayInfo.maxScale === undefined || dLayInfo.maxScale === 0 || currentScale >= dLayInfo.maxScale)) {
                    aLayersInScale.push(dLayInfo.id);
                }
            });
            if (aLayersInScale.length > 0) {
                aDeferreds.push(executeIdentify(evt.mapPoint, agsDynMapService.url, aLayersInScale));
            }
        }
    });

    // create a deferred list to aggregate the state for all identify queries
    deferredList = new dojo.DeferredList(aDeferreds);
    deferredList.then(function (aIdentifyResults) {
        // "aIdentifyResults" is 2D array of results
        // array[n][0] boolean true or false, success or failure of individual call
        // array[n][1] is the array of identity results returned
        formatIdentifyResults(aIdentifyResults);
    });
}

function formatIdentifyResults(res) {
    var finalResults = [],
        shouldReturn = false;

    $("#accordionIdentify").accordion("destroy");
    $("#accordionIdentify").empty();

    $.each(res, function (k1, v1) {
        // array[n][0] indicates success or failure
        if (v1[0] === false) {
            $("#accordionIdentify").append("<p>An error occurred during the identify query.</p>");
            shouldReturn = true;
            return false; //only breaks loop
        }
        // array[n][1] is the array of identity results returned
        if (v1 !== undefined && v1[1].length > 0) {
            v1[1].reverse();
            finalResults = finalResults.concat(v1[1]);
        }
    });
    if (shouldReturn) {
        return;
    }
    if (finalResults.length === 0) {
        $("#accordionIdentify").append("<p>No results were found.</p>");
        return;
    }
    idResultsForHighlighting = finalResults;

    //build the accordian widget
    var lastPanel = 0;
    var isAnotherFeature = 0;
    var prevlayerName = finalResults[0].layerName;
    var innerHtml = "<h3><a href=\"#\">" + prevlayerName + "</a></h3><div>";
    $.each(finalResults, function (layerKey, layerValue) {
        if (prevlayerName === layerValue.layerName) { //layer has not changed
            if (isAnotherFeature > 0) {
                innerHtml = innerHtml + "<hr />"; //start another feature by drawing hr
            }
        }
        else { //layer has changed
            innerHtml = innerHtml + "</div>"; //close
            innerHtml = innerHtml + "<h3><a href='#'>" + layerValue.layerName + "</a></h3><div>"; //start new accordian fold
            isAnotherFeature = 0; //reset feature count for layer
            lastPanel++;
        }

        innerHtml = innerHtml + "<a id='" + layerKey + "' href='#' style='color: blue' class='identifyHL' >Highlight Feature</a></td>";
        //create table of attributes and values for feature
        innerHtml = innerHtml + "<table><tbody>";
        $.each(layerValue.feature.attributes, function (key, value) {
            innerHtml = innerHtml + "<tr><td>" + key + "</td><td>" + value + "</td></tr>";
        });
        innerHtml = innerHtml + "</tbody></table>";

        prevlayerName = layerValue.layerName; //check for layer change
        isAnotherFeature++;
    });
    innerHtml = innerHtml + "</div>";
    $("#accordionIdentify").append(innerHtml);
    $("#accordionIdentify").accordion({
        autoHeight: false,
        collapsible: true,
        active: lastPanel //activate:false has all h3's closed, activate:activatePanel opens last added h3
    });
    $("#accordionIdentify .identifyHL").on('click', function () {
        showFeature($(this).attr('id'));
    });
}

var idResultsForHighlighting;
var identifyLayerKeyPrevious;
var isIdentifyHighlighted = false;
function showFeature(identifyLayerKey) {
    map.graphics.clear();
    //this if statement makes the highlight link toggle, if feature already highlighted
    if (isIdentifyHighlighted === false || identifyLayerKeyPrevious === undefined || identifyLayerKeyPrevious !== identifyLayerKey) {
        var idResult = idResultsForHighlighting[identifyLayerKey];
        var symbol;
        if (idResult.geometryType === "esriGeometryPoint") {
            symbol = new esri.symbol.SimpleMarkerSymbol();
            symbol.setColor(new dojo.Color([0, 255, 255, 0.7]));
        }
        else if (idResult.geometryType === "esriGeometryPolygon") {
            symbol = new esri.symbol.SimpleFillSymbol();
            symbol.setColor(new dojo.Color([0, 255, 255, 0.7]));
        }
        else { //"esriGeometryPolyline" 
            symbol = new esri.symbol.SimpleLineSymbol();
            symbol.setColor(new dojo.Color([0, 255, 255, 0.7]));
        }
        idResult.feature.setSymbol(symbol);
        map.graphics.add(idResult.feature);
        isIdentifyHighlighted = true;
    }
    else {
        isIdentifyHighlighted = false;
    }
    identifyLayerKeyPrevious = identifyLayerKey;
}
5
  • so how does it work if I have more services than I want id'd? Example: 7 total services and only want to return results on 3.
    – Craig
    Commented Jan 28, 2013 at 18:42
  • In my code, you would just put the 3 in the following array where I have 2. aAGSDynMapServicesToIdentify = [referenceLayer, operationalLayer];
    – awesomo
    Commented Jan 28, 2013 at 19:53
  • thanks for your help. I'm still learning the API, dojo, and javascript so please forgive my lack of understanding. I have taken your example and added my 3 services, but don't quite understand how to build the infowindow/popup to be unique to each service. Do you have a working sample that I might be able to look at to get a better idea of how to construct? Thanks again.
    – Craig
    Commented Jan 29, 2013 at 15:16
  • That blog entry is currently giving an error "Error establishing a database connection". I was hoping to see that as it could potentially help me with the same issue. Commented Sep 16, 2014 at 16:52
  • Yes, I need to reset the website, but I don't have the laptop that has the connection information I need. The deferredList is the heart of it, but it's changed in the current version of dojo -- so it would need to be revised anyway. Also, I see that I'm mixing jquery in there too, to make it more confusing. Sorry!
    – awesomo
    Commented Sep 17, 2014 at 0:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.