How can I get the image node in popup?

1973
4
Jump to solution
08-23-2017 07:24 AM
ChrisMathers1
Occasional Contributor II

I have an info template that is just a single picture from a traffic camera that's inserted using the media type. Nothing fancy here. I want it to update the image every second but I cant seem to get the node for the image. I've used every kind of getElementsBy and querySelector and combination of the two that I can think of but the image eludes me. The best I have gotten is using what I have below which yields me an html collection with one object, the esri-popup-renderer__media-item, that has the image as a child but when I try to search it for the img tag I get nothing. I tried jQuery selection with $(".esri-popup-renderer__media-item img:first") but it returned the entire html document.

If there is an easier way to make this image update I'm willing to completely abandon this strategy.

    view.popup.watch("visible", function (visible) {
        if (visible === true) {
            var media_item = document.getElementsByClassName("esri-popup-renderer__media-item");
            console.log(media_item);
            var image = media_item.getElementsByTagName("img");
            console.log(image.src);
            function updateImage() {
                image.src = image.src.split("?")[0] + "?t=" + new Date().getTime();
            }
            var image_refresh_interval = setInterval(updateImage, 1000);
        }else{
            clearInterval(image_refresh_interval);
        }
    });
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Chris,

   Here is a full sample demonstrating that:

<!DOCTYPE html>
<html dir="ltr">
<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>Multiple popup elements - 4.4</title>

  <link rel="stylesheet" href="https://js.arcgis.com/4.4/esri/css/main.css">
  <link rel="stylesheet" href="https://js.arcgis.com/4.4/dijit/themes/claro/claro.css">
  <script src="https://js.arcgis.com/4.4/"></script>

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

  <script>
    require([
      "esri/Map",
      "esri/views/MapView",
      "esri/layers/FeatureLayer",
      "dojo/query",
      "esri/core/watchUtils",
      "dojo/domReady!"
    ], function(Map, MapView, FeatureLayer, query, watchUtils) {

      // setup the map
      var map = new Map({
        basemap: "hybrid"
      });
      var view = new MapView({
        container: "mapDiv",
        map: map,
        center: [-118.399400711028, 34.08713590709093],
        zoom: 17,
        // Since there are many elements, it is best to dock the popup so
        // the elements display better rather than have to scroll through them all.
        popup: {
          dockEnabled: true,
          dockOptions: {
            buttonEnabled: false,
            breakpoint: false
          }
        }
      });

      var featureLayer = new FeatureLayer({
        url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/ArcGIS/rest/services/Beverly%20Hills%20Trees%20By%20Blo...",
        popupTemplate: {
          title: "<font color='#008000'>Beverly Hills trees by block",

          // Set content elements in the order to display.
          // The first element displayed here is the fieldInfos.
          content: [{
            // It is also possible to set the fieldInfos outside of the content
            // directly in the popupTemplate. If no fieldInfos is specifically set
            // in the content, it defaults to whatever may be set within the popupTemplate.
            type: "fields",
            fieldInfos: [{
              fieldName: "Point_Count",
              visible: false,
              label: "Count of Points",
              format: {
                places: 0,
                digitSeparator: true
              }
            }, {
              fieldName: "relationships/0/Point_Count_COMMON",
              visible: true,
              label: "Sum of species tree count",
              format: {
                places: 0,
                digitSeparator: true
              },
              statisticType: "sum"
            }, {
              fieldName: "relationships/0/COMMON",
              visible: false,
              label: "Common Name"
            }, {
              fieldName: "BLOCKCE10",
              visible: true,
              label: "Block"
            }]
          }, {
            // You can also set a descriptive text element. This element
            // uses an attribute from the featurelayer which displays a
            // sentence giving the total amount of trees value within a
            // specified census block. Text elements can only be set within the content.
            type: "text",
            text: "There are {Point_Count} trees within census block {BLOCKCE10}"
          }, {
            // You can set a media element within the popup as well. This
            // can be either an image or a chart. You specify this within
            // the mediaInfos. The following creates a pie chart in addition
            // to two separate images. The chart is also set up to work with
            // related tables. Similar to text elements, media can only be set within the content.
            type: "media",
            mediaInfos: [{
              title: "<b>Welcome to Beverly Hills</b>",
              type: "image",
              value: {
                sourceURL: "https://www.beverlyhills.org/cbhfiles/storage/files/13203374121770673849/122707_039r_final.jpg"
              }
            }, {
              title: "<b>Palm tree lined street</b>",
              type: "image",
              value: {
                sourceURL: "https://cdn.loc.gov/service/pnp/highsm/21600/21679r.jpg"
              }
            }]
          }, {
            // You can set a attachment element(s) within the popup as well.
            // Similar to text and media elements, attachments can only be set
            // within the content. Any attachmentInfos associated with the feature
            // will be listed in the popup.
            type: "attachments"
          }]
        },
        outFields: ["*"]
      });
      map.add(featureLayer);
      
      view.popup.watch("visible", function (visible) {
        if (visible === true) {
          watchUtils.whenNot(view.popup.viewModel, "pendingPromisesCount", function(cnt){
            setTimeout(function(){
              var media_item = query(".esri-popup-renderer__media-item > img");
              if(media_item[0]){
                var image = media_item[0];
                console.log(image.src);
                function updateImage() {
                    image.src = image.src.split("?")[0] + "?t=" + new Date().getTime();
                }
                var image_refresh_interval = setInterval(updateImage, 1000);
              }
            }, 200);
          });
        }else{
          clearInterval(image_refresh_interval);
        }
    });
    });
  </script>

</head>

<body>
  <div id="mapDiv"></div>
</body>

</html>

View solution in original post

4 Replies
RobertScheitlin__GISP
MVP Emeritus

Chris,

   Here is a full sample demonstrating that:

<!DOCTYPE html>
<html dir="ltr">
<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>Multiple popup elements - 4.4</title>

  <link rel="stylesheet" href="https://js.arcgis.com/4.4/esri/css/main.css">
  <link rel="stylesheet" href="https://js.arcgis.com/4.4/dijit/themes/claro/claro.css">
  <script src="https://js.arcgis.com/4.4/"></script>

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

  <script>
    require([
      "esri/Map",
      "esri/views/MapView",
      "esri/layers/FeatureLayer",
      "dojo/query",
      "esri/core/watchUtils",
      "dojo/domReady!"
    ], function(Map, MapView, FeatureLayer, query, watchUtils) {

      // setup the map
      var map = new Map({
        basemap: "hybrid"
      });
      var view = new MapView({
        container: "mapDiv",
        map: map,
        center: [-118.399400711028, 34.08713590709093],
        zoom: 17,
        // Since there are many elements, it is best to dock the popup so
        // the elements display better rather than have to scroll through them all.
        popup: {
          dockEnabled: true,
          dockOptions: {
            buttonEnabled: false,
            breakpoint: false
          }
        }
      });

      var featureLayer = new FeatureLayer({
        url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/ArcGIS/rest/services/Beverly%20Hills%20Trees%20By%20Blo...",
        popupTemplate: {
          title: "<font color='#008000'>Beverly Hills trees by block",

          // Set content elements in the order to display.
          // The first element displayed here is the fieldInfos.
          content: [{
            // It is also possible to set the fieldInfos outside of the content
            // directly in the popupTemplate. If no fieldInfos is specifically set
            // in the content, it defaults to whatever may be set within the popupTemplate.
            type: "fields",
            fieldInfos: [{
              fieldName: "Point_Count",
              visible: false,
              label: "Count of Points",
              format: {
                places: 0,
                digitSeparator: true
              }
            }, {
              fieldName: "relationships/0/Point_Count_COMMON",
              visible: true,
              label: "Sum of species tree count",
              format: {
                places: 0,
                digitSeparator: true
              },
              statisticType: "sum"
            }, {
              fieldName: "relationships/0/COMMON",
              visible: false,
              label: "Common Name"
            }, {
              fieldName: "BLOCKCE10",
              visible: true,
              label: "Block"
            }]
          }, {
            // You can also set a descriptive text element. This element
            // uses an attribute from the featurelayer which displays a
            // sentence giving the total amount of trees value within a
            // specified census block. Text elements can only be set within the content.
            type: "text",
            text: "There are {Point_Count} trees within census block {BLOCKCE10}"
          }, {
            // You can set a media element within the popup as well. This
            // can be either an image or a chart. You specify this within
            // the mediaInfos. The following creates a pie chart in addition
            // to two separate images. The chart is also set up to work with
            // related tables. Similar to text elements, media can only be set within the content.
            type: "media",
            mediaInfos: [{
              title: "<b>Welcome to Beverly Hills</b>",
              type: "image",
              value: {
                sourceURL: "https://www.beverlyhills.org/cbhfiles/storage/files/13203374121770673849/122707_039r_final.jpg"
              }
            }, {
              title: "<b>Palm tree lined street</b>",
              type: "image",
              value: {
                sourceURL: "https://cdn.loc.gov/service/pnp/highsm/21600/21679r.jpg"
              }
            }]
          }, {
            // You can set a attachment element(s) within the popup as well.
            // Similar to text and media elements, attachments can only be set
            // within the content. Any attachmentInfos associated with the feature
            // will be listed in the popup.
            type: "attachments"
          }]
        },
        outFields: ["*"]
      });
      map.add(featureLayer);
      
      view.popup.watch("visible", function (visible) {
        if (visible === true) {
          watchUtils.whenNot(view.popup.viewModel, "pendingPromisesCount", function(cnt){
            setTimeout(function(){
              var media_item = query(".esri-popup-renderer__media-item > img");
              if(media_item[0]){
                var image = media_item[0];
                console.log(image.src);
                function updateImage() {
                    image.src = image.src.split("?")[0] + "?t=" + new Date().getTime();
                }
                var image_refresh_interval = setInterval(updateImage, 1000);
              }
            }, 200);
          });
        }else{
          clearInterval(image_refresh_interval);
        }
    });
    });
  </script>

</head>

<body>
  <div id="mapDiv"></div>
</body>

</html>
ChrisMathers1
Occasional Contributor II

Worked like a charm. Thanks Robert. The current cameras map is a Google Maps mashup in a 3rd party interface. Our Traffic Eng department wanted me to make them a simple esri based map to replace it that they can embed.

0 Kudos
ChrisMathers1
Occasional Contributor II

Spoke too soon. I cant stop the updates now even if I close the popup. The close button wouldn't work initially because the scope of image_refresh_interval was limited. I hitched the function in setTimeout and it fixed that but the app keeps polling the image URL for every feature you click even after closing the popup. I attached the whole page below. It might still be a scope problem.

<!DOCTYPE html>
<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">
  <link rel="stylesheet" href="https://js.arcgis.com/4.4/esri/css/main.css">
  <link rel="stylesheet" href="https://js.arcgis.com/4.4/dijit/themes/claro/claro.css">
  <script src="https://js.arcgis.com/4.4/"></script>

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

  <script>
    require([
        "esri/Map",
        "esri/views/MapView",
        "esri/WebMap",
        "esri/layers/FeatureLayer",
        "dojo/query",
        "esri/core/watchUtils",
        "dojo/_base/lang",
        "dojo/domReady!"
    ], function (
        Map,
        MapView,
        WebMap,
        FeatureLayer,
        query,
        watchUtils,
        lang
    ) {
        var cameras = new FeatureLayer({
            url: "http://gis.baycountyfl.gov/arcgis/rest/services/TrafficCameras/MapServer/0",
            outFields: ["*"],
            popupTemplate: {
                title: "{Location} {Camera}",
                content: [{
                    type: "media",
                    mediaInfos: [{
                        title: "",
                        type: "image",
                        value: {
                            sourceURL: "http://tmc.baycountyfl.gov/CameraImages/Camera{Camera}.jpg?t=" + new Date().getTime()
                        }
                    }]
                }]
            }
        }),
            mapobj = new Map({
                basemap: "streets",
                layers: [cameras]
            }),
            view = new MapView({
                map: mapobj,
                container: "mapDiv",
                center: [-85.726147, 30.183486],
                zoom: 14
            });
        view.popup.viewModel.actions = [];
        view.popup.watch("visible", function (visible) {
            if (visible === true) {
                watchUtils.whenNot(view.popup.viewModel, "pendingPromisesCount", function (cnt) {
                    setTimeout(lang.hitch(this, function () {
                        var media_item = query(".esri-popup-renderer__media-item > img");
                        if (media_item[0]) {
                            var image = media_item[0];
                            console.log(image.src);
                            function updateImage() {
                                image.src = image.src.split("?")[0] + "?t=" + new Date().getTime();
                            }
                            this.image_refresh_interval = setInterval(updateImage, 1000);
                        }
                    }, 200));
                });
            } else {
                clearInterval(this.image_refresh_interval);
            }
        });
    });
  </script>

</head>

<body>
  <div id="mapDiv"></div>
</body>

</html>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Chris,

  Well here is that issue fixed:

<!DOCTYPE html>
<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">
  <link rel="stylesheet" href="https://js.arcgis.com/4.4/esri/css/main.css">
  <link rel="stylesheet" href="https://js.arcgis.com/4.4/dijit/themes/claro/claro.css">
  <script src="https://js.arcgis.com/4.4/"></script>

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

  <script>
    var image_refresh_interval;
    require([
      "esri/Map",
      "esri/views/MapView",
      "esri/WebMap",
      "esri/layers/FeatureLayer",
      "dojo/query",
      "esri/core/watchUtils",
      "dojo/_base/lang",
      "dojo/domReady!"
    ], function(
      Map,
      MapView,
      WebMap,
      FeatureLayer,
      query,
      watchUtils,
      lang
    ) {
      var cameras = new FeatureLayer({
          url: "http://gis.baycountyfl.gov/arcgis/rest/services/TrafficCameras/MapServer/0",
          outFields: ["*"],
          popupTemplate: {
            title: "{Location} {Camera}",
            content: [{
              type: "media",
              mediaInfos: [{
                title: "",
                type: "image",
                value: {
                  sourceURL: "http://tmc.baycountyfl.gov/CameraImages/Camera{Camera}.jpg?t=" + new Date().getTime()
                }
              }]
            }]
          }
        }),
        mapobj = new Map({
          basemap: "streets",
          layers: [cameras]
        }),
        view = new MapView({
          map: mapobj,
          container: "mapDiv",
          center: [-85.726147, 30.183486],
          zoom: 14
        });
      view.popup.viewModel.actions = [];
      view.popup.watch("visible", function(visible) {
        if (visible === true) {
          watchUtils.whenNot(view.popup.viewModel, "pendingPromisesCount", function(cnt) {
            setTimeout(lang.hitch(this, function() {
              var media_item = query(".esri-popup-renderer__media-item > img");
              if (media_item[0]) {
                var image = media_item[0];
                function updateImage() {
                  image.src = image.src.split("?")[0] + "?t=" + new Date().getTime();
                  console.log(image.src);
                }
                if(!image_refresh_interval){
                  image_refresh_interval = setInterval(updateImage, 1000);
                }
              }
            }, 200));
          });
        } else {
          clearInterval(image_refresh_interval);
          image_refresh_interval = null;
        }
      });
    });
  </script>

</head>

<body>
  <div id="mapDiv"></div>
</body>

</html>
0 Kudos