Select to view content in your preferred language

Combine InfoWindow and Dialog Popup from Mouseover and Click Events

3837
22
Jump to solution
03-18-2017 06:00 PM
LloydBronn
Frequent Contributor

I'm working on a map that has a neighborhood feature layer. When a user mouses over a neighborhood, I want to have a menu in the corner of the map that displays demographics and other data, like this example. That is in Leaflet, but I'm wondering if something similar is possible with the ArcGIS JavaScript? Should I use the popup content in side panel exampleIf the user then clicks on a neighborhood, I want a popup to display a link to a page with more in depth data analysis. I've gotten the click to work. However, if I specify an info template for the layer, both the link dialog and and the infoWindow pop up on top of each other when the neighborhood is clicked. 

Here is the part that's working: 

neighborhoodsLayer.on("click", function(evt){
            var name = evt.graphic.attributes.NAME;
            var nameNoDot = name.replace(/\./g,"");
            var nameDash = nameNoDot.replace(/_/g, "-");
            var nameLower = nameDash.toLowerCase();
           
          var t = "<b>${NAME}</b><hr><a target='_blank' href='http://<theserver>.org/profiles/" + nameLower +
              "'><b>Neighborhood Profile</b></a>";

          var content = esriLang.substitute(evt.graphic.attributes,t);
          var highlightGraphic = new Graphic(evt.graphic.geometry,highlightSymbol);
          map.graphics.add(highlightGraphic);
            
          dialog.setContent(content);

          domStyle.set(dialog.domNode, "opacity", 0.75);
            
          dijitPopup.open({
            popup: dialog,
            x: evt.pageX,
            y: evt.pageY
          });
        });
        function closeDialog() {
          map.graphics.clear();
          dijitPopup.close(dialog);
        }

I've gotten a mouseover function to work as well, but I can't get it to trigger the infoWindow. 

0 Kudos
22 Replies
RobertScheitlin__GISP
MVP Emeritus

Lloyd,

  I have edited your code in the above reply to fix the things I saw wrong or need to be updated to not use depreciated classes like connect. I am not sure about the layer visibility thing as I don't have access to your layer url. Do you have a min and max scale for that layer in your map service? I see you have a min and max zoom applied for your map.

0 Kudos
LloydBronn
Frequent Contributor

Thanks. I applied these changes and I'm still getting the same behavior. I checked the service and there is a min and max scale (I didn't create this service so I was unaware of it). 

Min Scale: 300005  Max Scale: 249995

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Lloyd,

   I see that you are not defining a popuptemplate for your featurelayer so the layer would not have a popup. With the map service having a min and max scale that is why the layer disappears when zooming in. If you set a min and max scale for the FeatureLayer you can override the services min and max.

0 Kudos
LloydBronn
Frequent Contributor

When I do define a popuptemplate, the popup shows up over the feature, not in the side panel. 

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Lloyd,

   Hmm. That strange with the 

map.infoWindow.set("popupWindow", false);

line in your code if anything the popup would never display. Maybe you should re-post all of your current code.

0 Kudos
LloydBronn
Frequent Contributor

Here it is. I can see the layers, but nothing happens when I click them. 

<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
  <title>Popup - Sidebar</title>
  <link rel="stylesheet" href="https://js.arcgis.com/3.20/dijit/themes/claro/claro.css" />
  <link rel="stylesheet" href="https://js.arcgis.com/3.20/esri/css/esri.css" />
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open Sans">

  <style>
    html,
    body {
      height: 100%;
      width: 100%;
      margin: 0;
      padding: 0;
      margin: 0;
      font-family: "Open Sans";
    }

    #leftPane {
      width: 20%;
      margin: 0;
      border: none;
    }

    #map {
      padding: 0;
    }

    .nav {
      padding: 5px 10px;
      background: #4479BA;
      color: #FFF;
      border-radius: 5px;
      border: solid 1px #20538D;
      text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.4);
      -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 1px 1px rgba(0, 0, 0, 0.2);
      -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 1px 1px rgba(0, 0, 0, 0.2);
      box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 1px 1px rgba(0, 0, 0, 0.2);
    }

    #header {
      text-align: center;
      height: 60px;
      border-bottom: solid 1px #ccc;
    }
  </style>

  <script src="https://js.arcgis.com/3.20/"></script>
  <script>
    var map;
    require([
      "dojo/ready",
      "dojo/on",
      "dojo/dom",
      "dijit/registry",
      "dojo/dom-construct",
      "dojo/parser",
      "dijit/layout/BorderContainer",
      "esri/layers/FeatureLayer",
      "esri/InfoTemplate",
      "dijit/layout/ContentPane",
      "esri/map",
      "esri/arcgis/utils",
      "esri/domUtils",
      "esri/dijit/Popup"
    ], function(
      ready,
      on,
      dom,
      registry,
      domConstruct,
      parser,
      BorderContainer,
      FeatureLayer,
      InfoTemplate,
      ContentPane,
      Map,
      arcgisUtils,
      domUtils,
      Popup
    ) {
      ready(function() {
        parser.parse();

        //setup event handlers for the next/previous buttons
        on(dom.byId("previous"), "click", selectPrevious);
        on(dom.byId("next"), "click", selectNext);

        map = new Map("map", {
          showLabels: false,
          basemap: "gray",
          center: [-122.675, 45.570],
            zoom: 11
        });
          
              var neighborhoodsLayer = new FeatureLayer("http://arcgis.research.pdx.edu/arcgis/rest/services/IMS_Services/Neighborhoods_Complete_nolabels/Map...");
               map.addLayer(neighborhoodsLayer);

        map.infoWindow.set("popupWindow", false);
        initializeSidebar(map);

        var infoContent = "${NAME}"
             "<b>White Population</b>: ${WhiteAlone_not_Hisp}" +
             "<br><b>Total Population 2010</b>: ${TotPOP_2010}" +
             "<br><b>Neighborhood Coalition</b>: ${LABEL_NAME_COALITION}";

          //var template = new esri.InfoTemplate(infoContent);

        function initializeSidebar(map) {
          var popup = map.infoWindow;
          //when the selection changes update the side panel to display the popup info for the
          //currently selected feature.
          on(popup, "selection-change", function() {
            displayPopupContent(popup.getSelectedFeature());
          });

          //when the selection is cleared remove the popup content from the side panel.
          on(popup, "clear-features", function() {
            //dom.byId replaces dojo.byId
            dom.byId("featureCount").innerHTML = "Click to select feature(s)";
            //registry.byId replaces dijit.byId
            registry.byId("leftPane").set("content", "");
            domUtils.hide(dom.byId("pager"));
          });

          //When features are associated with the  map's info window update the sidebar with the new content.
          on(popup, "set-features", function() {
            displayPopupContent(popup.getSelectedFeature());
            dom.byId("featureCount").innerHTML = popup.features.length + " feature(s) selected";
            //enable navigation if more than one feature is selected
            popup.features.length > 1 ? domUtils.show(dom.byId("pager")) : domUtils.hide(dom.byId("pager"));
          });
        }

        function displayPopupContent(feature) {
          if (feature) {
            var content = feature.getContent(infoContent);
            registry.byId("leftPane").set("content", content);
          }
        }

        function selectPrevious() {
          map.infoWindow.selectPrevious();
        }

        function selectNext() {
          map.infoWindow.selectNext();
        }
      });
    });
  </script>
</head>

<body class="claro">
  <div id="mainWindow" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline',gutters:false" style="width:100%; height:100%;">
    <div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="gutters:false" region="left" style="width: 20%;height:100%;">
      <div id="leftPane" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'"></div>
      <div id="header" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'top'">
        <div id="featureCount" style="margin-bottom:5px;">Click to select feature(s)</div>
        <div id="pager" style="display:none;">
          <a href='javascript:void(0);' id="previous" class='nav' style="text-decoration: none;">
                    &lt; Prev
                </a>  
          <a href='javascript:void(0);' id="next" class='nav' style="text-decoration: none;">
                    Next &gt;
                </a>
        </div>
      </div>
    </div>
    <div id="map" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'"></div>
  </div>
</body>

</html>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

One of the problems that I've had is that the example is based on an ArcGIS online map. This section here. 

 arcgisUtils.createMap("a3f1f198208b4f1f917a91895c895e21", "map").then(function(response){
                window.map = response.map;
                //set the popup's popupWindow property to false. This prevents the popup from displaying
                map.infoWindow.set("popupWindow", false);
                initializeSidebar(window.map);
            }, function(error){
                console.log("Map creation failed: ", dojo.toJson(error));
            });
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Lloyd,

   Here is your code working:

<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
  <title>Popup - Sidebar</title>
  <link rel="stylesheet" href="https://js.arcgis.com/3.20/dijit/themes/claro/claro.css" />
  <link rel="stylesheet" href="https://js.arcgis.com/3.20/esri/css/esri.css" />
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open Sans">

  <style>
    html,
    body {
      height: 100%;
      width: 100%;
      margin: 0;
      padding: 0;
      margin: 0;
      font-family: "Open Sans";
    }

    #leftPane {
      width: 20%;
      margin: 0;
      border: none;
    }

    #map {
      padding: 0;
    }

    .nav {
      padding: 5px 10px;
      background: #4479BA;
      color: #FFF;
      border-radius: 5px;
      border: solid 1px #20538D;
      text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.4);
      -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 1px 1px rgba(0, 0, 0, 0.2);
      -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 1px 1px rgba(0, 0, 0, 0.2);
      box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 1px 1px rgba(0, 0, 0, 0.2);
    }

    #header {
      text-align: center;
      height: 60px;
      border-bottom: solid 1px #ccc;
    }
  </style>

  <script src="https://js.arcgis.com/3.20/"></script>
  <script>
    var map;
    require([
      "dojo/ready",
      "dojo/on",
      "dojo/dom",
      "dijit/registry",
      "dojo/dom-construct",
      "dojo/parser",
      "dijit/layout/BorderContainer",
      "esri/layers/FeatureLayer",
      "esri/InfoTemplate",
      "dijit/layout/ContentPane",
      "esri/map",
      "esri/arcgis/utils",
      "esri/domUtils",
      "esri/dijit/Popup"
    ], function(
      ready,
      on,
      dom,
      registry,
      domConstruct,
      parser,
      BorderContainer,
      FeatureLayer,
      InfoTemplate,
      ContentPane,
      Map,
      arcgisUtils,
      domUtils,
      Popup
    ) {
      ready(function() {
        parser.parse();

        //setup event handlers for the next/previous buttons
        on(dom.byId("previous"), "click", selectPrevious);
        on(dom.byId("next"), "click", selectNext);

        map = new Map("map", {
          showLabels: false,
          basemap: "gray",
          center: [-122.675, 45.570],
            zoom: 11
        });
          
        var neighborhoodsLayer = new FeatureLayer("http://arcgis.research.pdx.edu/arcgis/rest/services/IMS_Services/Neighborhoods_Complete_nolabels/Map...");
        map.addLayer(neighborhoodsLayer);

        map.infoWindow.set("popupWindow", false);
        initializeSidebar(map);

        var infoContent = "${NAME}"
             "<b>White Population</b>: ${WhiteAlone_not_Hisp}" +
             "<br><b>Total Population 2010</b>: ${TotPOP_2010}" +
             "<br><b>Neighborhood Coalition</b>: ${LABEL_NAME_COALITION}";
        //You needed to set the layer info template that is why you were not getting a popup.
        var template = new InfoTemplate(infoContent);
        neighborhoodsLayer.setInfoTemplate(template);

        function initializeSidebar(map) {
          var popup = map.infoWindow;
          //when the selection changes update the side panel to display the popup info for the
          //currently selected feature.
          on(popup, "selection-change", function() {
            displayPopupContent(popup.getSelectedFeature());
          });

          //when the selection is cleared remove the popup content from the side panel.
          on(popup, "clear-features", function() {
            //dom.byId replaces dojo.byId
            dom.byId("featureCount").innerHTML = "Click to select feature(s)";
            //registry.byId replaces dijit.byId
            registry.byId("leftPane").set("content", "");
            domUtils.hide(dom.byId("pager"));
          });

          //When features are associated with the  map's info window update the sidebar with the new content.
          on(popup, "set-features", function() {
            displayPopupContent(popup.getSelectedFeature());
            dom.byId("featureCount").innerHTML = popup.features.length + " feature(s) selected";
            //enable navigation if more than one feature is selected
            popup.features.length > 1 ? domUtils.show(dom.byId("pager")) : domUtils.hide(dom.byId("pager"));
          });
        }

        function displayPopupContent(feature) {
          if (feature) {
            //not sure why you had infoContent in the getContent method
            var content = feature.getContent();
            registry.byId("leftPane").set("content", content);
          }
        }

        function selectPrevious() {
          map.infoWindow.selectPrevious();
        }

        function selectNext() {
          map.infoWindow.selectNext();
        }
      });
    });
  </script>
</head>

<body class="claro">
  <div id="mainWindow" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline',gutters:false" style="width:100%; height:100%;">
    <div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="gutters:false" region="left" style="width: 20%;height:100%;">
      <div id="leftPane" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'"></div>
      <div id="header" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'top'">
        <div id="featureCount" style="margin-bottom:5px;">Click to select feature(s)</div>
        <div id="pager" style="display:none;">
          <a href='javascript:void(0);' id="previous" class='nav' style="text-decoration: none;">
                    &lt; Prev
                </a>  
          <a href='javascript:void(0);' id="next" class='nav' style="text-decoration: none;">
                    Next &gt;
                </a>
        </div>
      </div>
    </div>
    <div id="map" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'"></div>
  </div>
</body>

</html>
0 Kudos
LloydBronn
Frequent Contributor

It is working, but I'm not seeing the fields from the infoTemplate. Just OID and Coalition. Also, where can I change the code to display the fields on mouse-over instead of click?

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Lloyd,

  I did not notice your other code mistakes. The popup info is now resolved and the mouseover and mouseout are now working. Now you will have to figure out the dialog stuff, as I shouldn't do all the coding for you 

<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
  <title>Popup - Sidebar</title>
  <link rel="stylesheet" href="https://js.arcgis.com/3.20/dijit/themes/claro/claro.css" />
  <link rel="stylesheet" href="https://js.arcgis.com/3.20/esri/css/esri.css" />
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open Sans">

  <style>
    html,
    body {
      height: 100%;
      width: 100%;
      margin: 0;
      padding: 0;
      margin: 0;
      font-family: "Open Sans";
    }

    #leftPane {
      width: 20%;
      margin: 0;
      border: none;
    }

    #map {
      padding: 0;
    }

    .nav {
      padding: 5px 10px;
      background: #4479BA;
      color: #FFF;
      border-radius: 5px;
      border: solid 1px #20538D;
      text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.4);
      -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 1px 1px rgba(0, 0, 0, 0.2);
      -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 1px 1px rgba(0, 0, 0, 0.2);
      box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 1px 1px rgba(0, 0, 0, 0.2);
    }

    #header {
      text-align: center;
      height: 60px;
      border-bottom: solid 1px #ccc;
    }

    .dijitDialogPaneContent {
      width: 300px !important;
      height: 100px !important;
    }
  </style>

  <script src="https://js.arcgis.com/3.20/"></script>
  <script>
    var map, timer;
    require([
      "esri/lang",
      "dojo/on",
      "dojo/dom",
      "dijit/registry",
      "dojo/dom-construct",
      "dojo/dom-style",
      "dojo/parser",
      "dijit/layout/BorderContainer",
      "esri/layers/FeatureLayer",
      "esri/dijit/PopupTemplate",
      "dijit/layout/ContentPane",
      "esri/map",
      "esri/arcgis/utils",
      "esri/domUtils",
      "esri/dijit/Popup",
      "dijit/popup",
      "dijit/Dialog",
      "dojo/domReady!"
    ], function(
      esriLang,
      on,
      dom,
      registry,
      domConstruct,
      domStyle,
      parser,
      BorderContainer,
      FeatureLayer,
      PopupTemplate,
      ContentPane,
      Map,
      arcgisUtils,
      domUtils,
      Popup,
      dijitPopup,
      Dialog
    ) {
      parser.parse();

      //setup event handlers for the next/previous buttons
      on(dom.byId("previous"), "click", selectPrevious);
      on(dom.byId("next"), "click", selectNext);

      map = new Map("map", {
        showLabels: false,
        basemap: "gray",
        center: [-122.675, 45.570],
        zoom: 11
      });

      var dialog = new Dialog({
        title: "Programmatic Dialog Creation"
      });

      var template = new PopupTemplate({
        title: "{NAME}",
        description: "<b>White Population</b>: {WhiteAlone_not_Hisp}" +
          "<br><b>Total Population 2010</b>: {TotPOP_2010}" +
          "<br><b>Neighborhood Coalition</b>: {LABEL_NAME_COALITION}"
      });

      var neighborhoodsLayer = new FeatureLayer(
        "http://arcgis.research.pdx.edu/arcgis/rest/services/IMS_Services/Neighborhoods_Complete_nolabels/Map...", {
          infoTemplate: template,
          outFields: ["*"]
        });
      map.addLayer(neighborhoodsLayer);

      on(neighborhoodsLayer, "mouse-over", function(evt) {
        clearTimeout(timer);
        displayPopupContent(evt.graphic);
      });

      on(neighborhoodsLayer, "mouse-out", function(evt) {
        timer = setTimeout(function() {
          map.infoWindow.clearFeatures();
        }, 1000)
      });

      map.infoWindow.set("popupWindow", false);
      initializeSidebar(map);

      function initializeSidebar(map) {
        var popup = map.infoWindow;
        //when the selection changes update the side panel to display the popup info for the
        //currently selected feature.
        on(popup, "selection-change", function() {
          displayPopupContent(popup.getSelectedFeature());
        });

        //when the selection is cleared remove the popup content from the side panel.
        on(popup, "clear-features", function() {
          //dom.byId replaces dojo.byId
          dom.byId("featureCount").innerHTML = "Click to select feature(s)";
          //registry.byId replaces dijit.byId
          registry.byId("leftPane").set("content", "");
          domUtils.hide(dom.byId("pager"));
        });

        //When features are associated with the  map's info window update the sidebar with the new content.
        on(popup, "set-features", function() {
          displayPopupContent(popup.getSelectedFeature());
          dom.byId("featureCount").innerHTML = popup.features.length + " feature(s) selected";
          //enable navigation if more than one feature is selected
          popup.features.length > 1 ? domUtils.show(dom.byId("pager")) : domUtils.hide(dom.byId("pager"));
        });
      }

      function displayPopupContent(feature) {
        if (feature) {
          //not sure why you had infoContent in the getContent method
          var content = feature.getContent();
          registry.byId("leftPane").set("content", content);
        }
      }

      function selectPrevious() {
        map.infoWindow.selectPrevious();
      }

      function selectNext() {
        map.infoWindow.selectNext();
      }
    });
  </script>
</head>

<body class="claro">
  <div id="mainWindow" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline',gutters:false" style="width:100%; height:100%;">
    <div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="gutters:false" region="left" style="width: 20%;height:100%;">
      <div id="leftPane" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'"></div>
      <div id="header" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'top'">
        <div id="featureCount" style="margin-bottom:5px;">Click to select feature(s)</div>
        <div id="pager" style="display:none;">
          <a href='javascript:void(0);' id="previous" class='nav' style="text-decoration: none;">
                    &lt; Prev
                </a>
          <a href='javascript:void(0);' id="next" class='nav' style="text-decoration: none;">
                    Next &gt;
                </a>
        </div>
      </div>
    </div>
    <div id="map" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'"></div>
  </div>
</body>

</html>
0 Kudos
LloydBronn
Frequent Contributor

Of course, thanks Robert! I had the dialog and mouse-over functions working separately, but I was just having trouble with this side infoWindow script. 

0 Kudos