0

I am using webamp to show the map created in ArcGIS (Javascript API in PHP website). In the map, a popup also appears when clicking on the layer's points. Recently I have updated the version 4.14 from 4.13. After updating it, the popup is not working properly. I have a custom popup template. After research in the documentation, I came to know there required a return function to show the custom div on the popup. The below code I have added to show my custom popups.

var template = { content: function(){ var div = document.createElement("div"); div.className = "myClass"; div.innerHTML = "<span>My custom content!</span>"; return div; } }

layers[layerIndex].popupTemplate = template;

Now the popup appears fine. But I have to show the field values on the popup. I have used the required field attributes in double brackets eg: {Name}. But in the latest version, the field values are not appearing when I used the same.

The code I have used in version 4.13 and it was working,

popupTemplate = {
title: "{Name}",
content: '<div id="popup_address">{Address}</div><div class="right"><div href="#" id="popupRight" class="toggle"><p onClick="openPopupDetails({FACILITYID})">+</p></div></div>' };

layers[layerIndex].popupTemplate = popupTemplate;

Please help me to fix this issue.

Thanks.

The complete code for the Webmap and custom popup map.js

// The map classes and includ1a65d527bfd04cc180c87edf0908907bes
require([
  "esri/views/MapView",
  "esri/WebMap",
  "esri/widgets/Search",
  "esri/widgets/Zoom",
  "esri/widgets/Locate"
], function(MapView, WebMap, Search, Zoom, Locate) {
  var webmap = new WebMap({
    portalItem: {
      id: "d1ca798d8c7d4afab8983d911df8326b"
    }
  });

  var view = new MapView({
    map: webmap,
    container: "map",
    center: [-95.9406, 41.26],
    zoom: 16,
    maxZoom: 21,
    minZoom: 13,
    basemap: "topo",

    ui: {
      components: ["attribution"]
    }
  });

  webmap
    .load()
    .then(function() {
      return webmap.basemap.load();
    })
    .then(function() {
      let allLayers = webmap.allLayers;
      console.log(allLayers);

      var promises = allLayers.map(function(layer) {
        return layer.load();
      });
      return Promise.all(promises.toArray());
    })
    .then(function(layers) {
      // Position of the popup in relation to the selected feature.
      view.popup.alignment = "top-center";
      // To disable the collapse functionality
      view.popup.collapseEnabled = false;
      // A spinner appear at the pointer
      view.popup.spinnerEnabled = false;
      // To disable the dock (The popup will be appear in bottom or any corner of the window)
      view.popup.dockEnabled = false;
      // Disable the pagination
      view.popup.featureNavigationEnabled = false;
      // Popup template details, Keep only name and address in the popup and avoid all other details
      view.popup.viewModel.actions.getItemAt(0).visible = false;

      // view.on("click", function(event) {
      // keep a delay to align the popup and the pointer together positioned to the map center
      // Add animation only if the browser not IE
      // });

      layers.forEach(function(popupLayers, layerIndex) {
        console.log(popupLayers);

        var template = {
          title: "{Name}",
          content: function() {
            var div = document.createElement("div");
            div.className = "myClass";
            div.innerHTML = "<span>{Address}</span>";
            return div;
          }
        };
        layers[layerIndex].popupTemplate = template;

        // popupTemplate = {
        //   title: "{Name}",
        //   content:
        //     '<div id="popup_address">{Address}</div><div class="right"><div href="#" id="popupRight" class="toggle"><p onClick="openPopupDetails({FACILITYID})">+</p></div></div>'
        // };
        // layers[layerIndex].popupTemplate = popupTemplate;
      });

      // To close the popup when hit on esc button
      document.onkeyup = function(evt) {
        var key = evt.keyCode;
        if (key == 27) {
          view.popup.close();
        }
      };
    })
    .catch(function(error) {
      //   console.log(error);
    });
});

Index.php

<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />

<title>Load a basic WebMap - 4.14</title>

    <style>
      html,
      body,
      #map {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
      }
    </style>

    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.14/esri/themes/light/main.css"
    />

    <script src="https://js.arcgis.com/4.14/"></script>
<script src="map.js"></script>
  </head>

  <body>
    <div id="map"></div>
  </body>
</html>

I have modified the code,

 for (let i = 2; i < layers.length; i++) {
        var template = {
          title: "{Name}",
          content: function() {
            var div = document.createElement("div");
            div.innerHTML =
              '<div id="popup_address">{Address}</div><div class="right"><div href="#" id="popupRight" class="toggle"><p onClick="openPopupDetails({FACILITYID})">+</p></div></div>';
            return div;
          }
        };
        layers[i].popupTemplate = template;
        console.log(layer[i]);
      }

When I apply custom div, the {Address} part is not rendering. It appears like {Address} itself.

Adam-KER
  • 67
  • 9

2 Answers2

0

I think you are a bit confuse, you still can use a string, or you can use a function for the content of the popup template. So if you want to use a function, you can use something like this,

popupTemplate = {
    title: "{Name}",
    content: popupContentChange
}

layers[layerIndex].popupTemplate = template;

function popupContentChange(feature) {
    let div = document.createElement("div");
    div.className = "myClass";
    div.innerHTML = "<span>"+feature.graphic.attributes.Address+"</span>";
    return div;
}

There are several examples in the API documentation, take a look there. Just to reference one, ArcGIS JavaScript API Examples - Intro to Popups

Here an example I made for you taking your code as base adding some fixes to display what you want.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />
    <title>Sketch Feature Coords</title>
    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.14/esri/themes/light/main.css"
    />
    <script src="https://js.arcgis.com/4.14/"></script>
    <style>
      html,
      body,
      #map {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
      }
    </style>
    <script>
      require([
        "esri/views/MapView",
        "esri/WebMap",
        "esri/widgets/Search",
        "esri/widgets/Zoom",
        "esri/widgets/Locate"
      ], function(MapView, WebMap, Search, Zoom, Locate) {
        var webmap = new WebMap({
          portalItem: {
            id: "d1ca798d8c7d4afab8983d911df8326b"
          }
        });

        var view = new MapView({
          map: webmap,
          container: "map",
          center: [-95.9406, 41.26],
          zoom: 16,
          maxZoom: 21,
          minZoom: 13,
          basemap: "topo",
          ui: {
            components: ["attribution"]
          }
        });
        webmap
          .load()
          .then(function() {
            return webmap.basemap.load();
          })
          .then(function() {
            let allLayers = webmap.allLayers;
            console.log(allLayers);
            var promises = allLayers.map(function(layer) {
              return layer.load();
            });
            return Promise.all(promises.toArray());
          })
          .then(function(layers) {
            // Position of the popup in relation to the selected feature.
            view.popup.alignment = "top-center";
            // To disable the collapse functionality
            view.popup.collapseEnabled = false;
            // A spinner appear at the pointer
            view.popup.spinnerEnabled = false;
            // To disable the dock (The popup will be appear in bottom or any corner of the window)
            view.popup.dockEnabled = false;
            // Disable the pagination
            view.popup.featureNavigationEnabled = false;
            // Popup template details, Keep only name and address in the popup and avoid all other details
            view.popup.viewModel.actions.getItemAt(0).visible = false;

            // it is only going to work on the last two layers
            // those are the one that have fields: Name and Address
            for (let i = 2; i < layers.length; i++) {
              var template = {
                title: "{Name}",
                content: "<span>Address: {Address}</span>"
              };
              layers[i].popupTemplate = template;
              console.log(layer[i]);
            }
            
            // To close the popup when hit on esc button
            document.onkeyup = function(evt) {
              var key = evt.keyCode;
              if (key == 27) {
                view.popup.close();
              }
            };
          })
          .catch(function(error) {
            console.log(error);
          });
    });
    </script>
  </head>
  <body>
    <div id="map"></div>
  </body>
</html>

If you want to use a function as content, you have to set the outFields parameter to include the fields you want to use in the function. The selected feature is pass as a parameter to the function, and inside you use feature.graphic.attributes to access the attributes. This should work,

var template = {
    title: "{Name}",
    // content: "<span>Address: {Address}</span>"
    content: function(feature) {
        console.log(feature);
        var div = document.createElement("div");
        div.className = "myClass";
        div.innerHTML = "<span>Address:"+feature.graphic.attributes.Address+"</span>";
        return div;
    },
    outFields: ["Name", "Address"]
};
cabesuon
  • 4,860
  • 2
  • 15
  • 24
  • I can show the custom popup with the function. My problem is, in the popup if I am using "{Name}" to show the title, it's not showing. But if I kept any string its coming in the popup. Eg: title:"{Name} is {Address}" shows "is" in the popup. Not showing the corresponding field value for Name and Address. – Adam-KER Feb 20 '20 at 15:57
  • For what you are commenting the code of your post is incomplete, not the one you are trying. Update the actual code you are using so I can check it. – cabesuon Feb 20 '20 at 16:55
  • Thank you so much. Now its working. Let me check why the foreach and for loop makes the difference. Thanks again :) – Adam-KER Feb 24 '20 at 16:37
  • Can you please check my latest comment. Seems when I added the {Address} it is not rendering. I have custom css for that popup. – Adam-KER Feb 24 '20 at 16:55
  • Glad it helps you!. – cabesuon Feb 25 '20 at 02:07
  • Hi Cabesuon, can you please check this thread. Its about adding an image in the popup. https://stackoverflow.com/questions/60488592/arcgis-javascript-api-4-14-add-attached-image-in-custom-popup-template – Adam-KER Mar 02 '20 at 22:49
  • Can anyone help me out at this question https://stackoverflow.com/questions/69630872/display-info-window-on-the-multiple-coordinates-on-the-arcgis-map-in-next-js I have to display pop up for each point on the map – Deep Kakkar Oct 20 '21 at 16:04
0

featureNavigationEnabled is deprecated as of version 4.15. Use Popup.visibleElements.featureNavigation instead.

https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Popup.html#featureNavigationEnabled

M--
  • 25,431
  • 8
  • 61
  • 93
Gregory Bologna
  • 270
  • 1
  • 6
  • 20