Can you specify an OnClick event specific to a Layer to identify two different Popups

7033
11
01-25-2013 06:29 AM
KristenJones1
Occasional Contributor
I'm trying to figure out how to create a different InfoWindow (template) popup for each of my feature layers, since each have a different set of fields and data.  I have not been able to find any examples yet, but I figured that I could start by creating a different OnClick event. So for example dojo.connect(map, "onClick", myClickHandler);  can I do something like

dojo.connect(map(FeatureLayer1), "onClick", myClickHandler);

dojo.connect(map(FeatureLayer2), "onClick", myClickHandler);

or am I way off on how to proceed with this?

THANKS!
0 Kudos
11 Replies
KristenJones1
Occasional Contributor
Well I tried that code and it does not work. Click event never fires, then if I try manually setting the selection to a specific layer, then changing the onclicks first parameter back to Map the click event works but now it is not updating the to the current selected "permit" and the popups are calling out the same info.

Feeling discouraged with this.  I'm thinking the same as  kmacleod, how am I going to easily set the active layer after I can just get the click Event to behave.  Anyone want to take a peek at what I have so far.


<!DOCTYPE html>
 <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=7,IE=9">
    <!--The viewport meta tag is used to improve the presentation and behavior
    of the samples on iOS devices-->
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
    <title>Permit Locator</title>

    <link rel="stylesheet" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.3/js/dojo/dijit/themes/claro/claro.css">
    <link rel="stylesheet" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.3/js/esri/css/esri.css">
    <style>
      html, body {
        height: 100%;
        width: 100%;
        margin: 0;
        padding: 0;
      }
      #map {
        padding:0;
      }
    </style>

    <script>var dojoConfig = { parseOnLoad: true };</script>
    <script src="http://serverapi.arcgisonline.com/jsapi/arcgis/3.3/"></script>
    <script>
      dojo.require("dijit.layout.BorderContainer");
      dojo.require("dijit.layout.ContentPane");
      dojo.require("esri.map");
      dojo.require("esri.layers.FeatureLayer");
      dojo.require("esri.dijit.Popup");
      
      var map;
      var permits;
      var properties;
      
      function init() {
      
      var sfs = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([111, 0, 255]), 2), new dojo.Color([111, 0, 255, 0.15]));
      
       
       var popup = new esri.dijit.Popup({
          fillSymbol: sfs
        }, dojo.create("div"));
        

        map = new esri.Map("map",{
          basemap: "streets",
          center: [-84.183, 39.734],
          zoom: 13,
          infoWindow: popup
        });
        
        dojo.addClass(map.infoWindow.domNode, "myTheme");

       
      //Add all the permits and parcels to see on load   
      var operationalLayer = new esri.layers.ArcGISDynamicMapServiceLayer("http://map.miamiconservancy.org:6080/arcgis/rest/services/MCDPropertiesGeoDB/MapServer", {"opacity":0.9});
      map.addLayer(operationalLayer);
         
        
      //apply a popup template to the permits layer to format popup info 
      var popupTemplate = new esri.dijit.PopupTemplate({
          title: "{Permits.MASTERUSER.%PERMIT.ISSUEDTO}",
          fieldInfos: [{
            fieldName: "Permits.MASTERUSER.%PERMIT.MCDNUM",
            label: 'Permit Number (MCDNUM):',
            visible: true
          }, {
            fieldName: "Permits.MASTERUSER.%PERMIT.LOCATION",
            label: "Location:",
            visible: true
          }]
        });
        
        
        
        //apply a popup template to the MCD Parcels layer to format popup info 
        var popupTemplateParcels = new esri.dijit.PopupTemplate({
          title: "{MCDID}",
          fieldInfos: [{
            fieldName: "MCDID",
            label: 'MCD ID:',
            visible: true
          }, {
            fieldName: "PARCELID",
            label: "Parcel ID:",
            visible: true
          }]
        });

            

       //add the permits layer to the map as a feature layer in selection mode we'll use this layer to query and display the selected permits
        permits = new esri.layers.FeatureLayer("http://map.miamiconservancy.org:6080/arcgis/rest/services/MCDPropertiesJOINToSQL/MapServer/2", {
          outFields: ["*"],
          infoTemplate: popupTemplate,
          mode: esri.layers.FeatureLayer.MODE_SELECTION
        });
        
        
        //add the Properties layer to the map as a feature layer in selection mode
        properties = new esri.layers.FeatureLayer("http://map.miamiconservancy.org:6080/arcgis/rest/services/MCDPropertiesJOINToSQL/MapServer/0", {
          outFields: ["*"],
          infoTemplate: popupTemplateParcels,
          mode: esri.layers.FeatureLayer.MODE_SELECTION
        });




          permits.setSelectionSymbol(sfs);
          
          properties.setSelectionSymbol(sfs);
         // map.infoWindow.setFeatures(permits);



        //*****when users click on the map select the permit using the map point and update the url parameter




dojo.connect(map, 'onClick', function (e) 
 {
          var query = new esri.tasks.Query();
          query.geometry = e.mapPoint;

          permits.selectFeatures(query, esri.layers.FeatureLayer.SELECTION_NEW, function (selection) 
      {
          //update the url param if a permit was located

          if (selection.length > 0) 
            {
            var mcdnum = selection[0].attributes["Permits.MASTERUSER.%PERMIT.MCDNUM"];
             //Refresh the URL with the currently selected permit
               if (typeof history.pushState !== 'undefined') 
                {
                 window.history.pushState(null, null, "?mcdnum=" + selection[0].attributes["Permits.MASTERUSER.%PERMIT.MCDNUM"]);
                }
            }
      });
      // map.infoWindow.setFeatures(selection);
       map.infoWindow.setFeatures(permits);
       map.infoWindow.show(e.mapPoint);
   
      
 });

// Now for the Properties layer



    dojo.connect(properties, 'onClick', function (e) 
{
          var query = new esri.tasks.Query();
          query.geometry = e.mapPoint;
          map.infoWindow.setFeatures(selection);  
          map.infoWindow.show(e.mapPoint);
});



       dojo.connect(map, 'onLayersAddResult', function (result) {
          // Add a link into the InfoWindow Actions panel       
          var emailLink = dojo.create("a", {
            "class": "action",
            "innerHTML": "Email Map",
            "href": "javascript:void(0);"
          }, dojo.query(".actionList", map.infoWindow.domNode)[0]);


          // Register a function to be called when the user clicks on
          // the above link
          dojo.connect(emailLink, "onclick", function (evt) {
            var feature = map.infoWindow.getSelectedFeature();
            var url = window.location;
            var emailLink = "mailto:?subject=Permit Map of :" + feature.attributes["Permits.MASTERUSER.%PERMIT.MCDNUM"]+ "&body=Check out this permit: %0D%0A " + window.location;
            window.location.href = emailLink;
          });

          //When users navigate through the history using the browser back/forward buttons select appropriate permit  
          //https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history
          window.onpopstate = function (event) {
            var mcdnum = getPermitFromUrl(document.location.href);
            if (mcdnum) {
              selectPermit(mcdnum);
            } else {
              permits.clearSelection();
              map.infoWindow.hide();
            }
          };

          //if a mcdnum is specified in url param select that feature 
          var mcdnum = getPermitFromUrl(document.location.href);
          selectPermit(mcdnum);
        });

        map.addLayers([permits]);
        map.addLayers([properties]);
      }

      //extract the permit id from the url
      function getPermitFromUrl(url) {
        var urlObject = esri.urlToObject(url);
        if (urlObject.query && urlObject.query.mcdnum) {
          return urlObject.query.mcdnum;
        } else {
          return null;
        }
      }

      //select permit from the feature layer by creating a query to look for the input mcdnum id 
      function selectPermit(mcdnum) {
        if (mcdnum) {
          var query = new esri.tasks.Query();
          query.where = "Permits.MASTERUSER.%PERMIT.MCDNUM = " + mcdnum + "";
          //query.where = "Permits.MASTERUSER.%PERMIT.MCDNUM = 2963";
          var deferred = permits.selectFeatures(query, esri.layers.FeatureLayer.SELECTION_NEW, function (selection) {
            var center = esri.graphicsExtent(selection).getCenter();
            var extHandler = dojo.connect(map, 'onExtentChange', function () {
              dojo.disconnect(extHandler);
              //zoom to the center then display the popup 
              map.infoWindow.setFeatures(selection);
              map.infoWindow.show(center);
            });
            map.centerAt(center);
          });
        }
      }









      
      dojo.ready(init);
          </script>
  </head>
  
  <body class="claro">
    <div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design:'headline',gutters:false" 
    style="width: 100%; height: 100%; margin: 0;">
      <div id="map" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'center'" style="border:1px solid #000;padding:0;"></div>
    </div>
  </body>
</html>
 
0 Kudos
DianaBenedict
Frequent Contributor
Below is some code and pseudocode samples that will hopefully get you past the "hump". Essentially, I have provided funcitonality that will allow you to perform asychronous calls to the server to select from multiple featureLayers, wait for the return results from the server and then give you palce for you to process the results as needed.  Note that this code is still mostly "work in progress/samples" to solve a similar issue to what it seems like you are experiencing.  In my case, I have to be able to select from multiple featureLayers that I set as my editable layers and be able to display the attributes and edit as needed. I use the AttributeInspector to load the selected features so my process is a little different than yours. However, the main hurdle is to be able to perform selections from multiple featurelayers simultaneously and be able to process the results once the server has returned the selection results from all the layers (that is why I use the dojo/deferred and dojo/deferredList objectss). On that note. I am showing you two different ways to reference those objects.  The standalone method shows you using the AMD (new recomondations) the other method shows you the "regular" way. If you do not use the AMD way then you need to make sure to add a dojo.require for the dojo.deferred object.  I am also using the dojo/deferredList  object but according to the 1.8 documenation this is deprecated and we should consider uisng dojo/promise/all .. at some point I will update the code but it is working and I have too much on my plate right now.

//the code below is taken from your dojo.connect(map,...)    
dojo.connect(map, 'onClick', function (e) {
      var query = new esri.tasks.Query();
      query.geometry = e.mapPoint; //TODO: consider creating a method that expands the point to an extent 

      //call the method that performs a query from an array of feature layers...
      //note that you may need to alter the query object .. 
      //my example assumes the same query for all layers in the array
      var editFeatureLayers = [permits, properties];

      var deferred = getSelectionLayerDeferred(editFeatureLayers, query);
      deferred.then(function (results) {
        var selectionLayers = null;
        if (results.success) {
          selectionLayers = results.selectionLayers;
        } else {
          var err = results.error;
          alert("Error when attempting process selectionLayers for the EditLayers");
        }

        if (selectionLayers) {
          if (selectionLayers.length > 0) {
            //add your code here to process your selected records..
            //below is an example how you can get the info you need from the selectionLayers object
            var mySelfeatures = [];
            dojo.forEach(selectionLayers, function (selLayer) {
              var layerNameString = selLayer.featureLayer.name;
              var selFeatures = selLayer.features;
              var selFeatureCount = selLayer.features.length;
              //NOTE: in here you can process your logic as needed based on your layerNameString for example
              //added some pseudocode below to show you what I mean:
              if (layerNamestring === "premits") {

              } else if (layerNamestring === "properties") {

              }
              //note, you may need to create an array object to add all your featuers 
              //so you can use it to setFeatures for your popup
              //don't know, haven't done this before since I use the attributeInspector
              //concat the selFeatures to this array... I think this will work confirm syntax in JS
              mySelfeatures = mySelfeatures.concat(selLayer.features);    
            });

          } else {
            //hideProcessingDialog();
            //add your code here to add logic to what happens if no features get selected
          }
        }
      }, function (err) {
        // Do something on failure.
        hideProcessingDialog();
        drawToolbar.deactivate();
        alert("Error while selecting features");
      });

      map.infoWindow.setFeatures(mySelfeatures);
      //map.infoWindow.setFeatures(permits);
      map.infoWindow.show(e.mapPoint);
    });

//BELOW is the method that performs the selection from an array of FeatureLayer objects and uses one Query object
// this is really key to being able to get all the selection results in one place ... it is also pretty fast since it does not chain the 
//call to the server all calls are done asynch... 
//TODO: use dojo/promise/all instead of dojo/deferredList
function getSelectionLayerDeferred(featureLayerArray, selectQuery) {
  var returnDeferred = null;
  var selectionLayers = [];
  var defferredCallArray = [];

  require(["dojo/DeferredList", "dojo/Deferred"], function (DeferredList, Deferred) {
    returnDeferred = new Deferred();

    dojo.forEach(featureLayerArray, function (flayer) {
      var defferredCall = flayer.selectFeatures(selectQuery, esri.layers.FeatureLayer.SELECTION_NEW);
      //cast the dojo.deferred to a promise so we can use the new 
      //dojo/promise/all in lieu of dojo/DeferredList (deprecated at v 1.8)
      defferredCallArray.push(defferredCall);
    });

    var dl = new DeferredList(defferredCallArray);
    dl.then(function (results) {
      // Executed when all deferred resolved
      if (results.length > 0) {
        dojo.forEach(results, function (result) {
          if (result[0] === true && result[1].length > 0) {
            selectionLayers.push({ 'featureLayer': result[1][0].getLayer(), 'features': result[1] });
          }
        });
      }
      returnDeferred.resolve({ 'success': true, 'selectionLayers': selectionLayers });
    }, function (err) {
      returnDeferred.resolve({ 'success': false, 'selectionLayers': null, 'error': err });
    });
  });
  return returnDeferred;
}

0 Kudos