Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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){


   //create identify tasks and setup parameters 
   identifyTaskZoning = new esri.tasks.IdentifyTask("");
   identifyTaskParcels = new esri.tasks.IdentifyTask("");

        //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);
   if (response.length > 0) {
//         console.log(response.length)
//         response is an array of identify result objects    
//         Let's return an array of features.
    return, function(result){
      var feature = result.feature;
      feature.attributes.layerName = result.layerName;
      if(result.layerName === 'TaxParcel'){
          var template = new esri.dijit.PopupTemplate({
                        description:"<b>Parcel ID:</b> {Parcel Identification Number} <br/> <b>Address:</b> {Site Address}"

            return feature;
  else {
      identifyParamsZoning.geometry = evt.mapPoint;
      identifyParamsZoning.mapExtent = map.extent;
      var deferred = identifyTaskZoning.execute(identifyParamsZoning);
        // response is an array of identify result objects    
        // Let's return an array of features.
        return, function(result){
          var feature = result.feature;
          feature.attributes.layerName = result.layerName;
        if(result.layerName === 'Zoning Classifications'){
          var template = new esri.dijit.PopupTemplate({
                        description:"<b>Zoning:</b> {Zoning Classification} <br/> <b>Description:</b> {Zoning Description}"
        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}"
                    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}"
                    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}"
                    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}"
        return feature;
share|improve this question
up vote 2 down vote accepted

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.

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 -->
To view and modify and re-download this theme, visit,%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" />

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

//javascript fragment

//at some point open the dialog to start

    autoOpen: false,
    width: 320,
    height: 400,
    position: 'right',        
    open: function (event, ui) {
    close: function (event, ui) {

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");;
    $("#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,
        aDeferreds = [],
        currentScale = map.getScale(),
        aAGSDynMapServicesToIdentify = [referenceLayer, operationalLayer];;
    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, !== -1 &&
                        (dLayInfo.minScale === undefined || dLayInfo.minScale === 0 || currentScale <= dLayInfo.minScale) &&
                        (dLayInfo.maxScale === undefined || dLayInfo.maxScale === 0 || currentScale >= dLayInfo.maxScale)) {
            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

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


    $.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) {
            finalResults = finalResults.concat(v1[1]);
    if (shouldReturn) {
    if (finalResults.length === 0) {
        $("#accordionIdentify").append("<p>No results were found.</p>");
    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

        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
    innerHtml = innerHtml + "</div>";
        autoHeight: false,
        collapsible: true,
        active: lastPanel //activate:false has all h3's closed, activate:activatePanel opens last added h3
    $("#accordionIdentify .identifyHL").on('click', function () {

var idResultsForHighlighting;
var identifyLayerKeyPrevious;
var isIdentifyHighlighted = false;
function showFeature(identifyLayerKey) {;
    //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]));
        isIdentifyHighlighted = true;
    else {
        isIdentifyHighlighted = false;
    identifyLayerKeyPrevious = identifyLayerKey;
share|improve this answer
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 Jan 28 '13 at 18:42
In my code, you would just put the 3 in the following array where I have 2. aAGSDynMapServicesToIdentify = [referenceLayer, operationalLayer]; – awesomo Jan 28 '13 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 Jan 29 '13 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. – jbchurchill Sep 16 '14 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 Sep 17 '14 at 0:15

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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