Convert Flex pop-up to WAB - 2 questions

4382
16
Jump to solution
11-20-2015 11:55 AM
MegPeterson
New Contributor III

Hi all -

I have a popup from my old Flex site that I would like to re-create in WAB. It's displayed below and was configured using the <description> tag with <![CDATA[ {NAME}<br> <img src="assets'images\popup_icons\{I_bike}"> <img src="assets'images\popup_icons\{I_hike}">, etc etc.>

to pull in image icons referenced in the data table.

Question #1: I'm trying to configure the pop-up in the web map using the "custom attribute display" option, but I don't see a way to display the icons horizontally referencing an <img> tag, or via a virtual directory. Is that possible to do? And if not - egads, where would I begin to recreate the popup? The images represent Yes or No values for whether the activity is available at that location.

Question #2: Ideally I'd like to configure the popup to be queried for only the activities available at each location, similar to the Park Locator Local Government template. This seems more extensive with coding, but if anyone has suggestions on where to begin or what forums to read and get started, I'd appreciate the guidance.

Thank you. - Meg


Tags (2)
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Meg,

  OK, I have completed the code additions for the MapManager.js for adding the custom infoWindow for your parks layer:

There are three new functions and one line of code to add to an existing function in MapManager.js.

New functions to add:

      _getParksLayer: function() {
        require(["jimu/LayerInfos/LayerInfos"], lang.hitch(this, function(LayerInfos){
          if (this.map.itemId) {
            LayerInfos.getInstance(this.map, this.map.itemInfo)
            .then(lang.hitch(this, function(operLayerInfos) {
              this.operLayerInfos = operLayerInfos;
              array.forEach(this.operLayerInfos.getLayerInfoArray(), function(layerInfo) {
                console.info(layerInfo);
                if(layerInfo.title === 'ParksFinder'){
                  this._setupParksPopup(layerInfo);
                }
              }, this);
            }));
          } else {
            var itemInfo = this._obtainMapLayers();
            LayerInfos.getInstance(this.map, itemInfo)
            .then(lang.hitch(this, function(operLayerInfos) {
              this.operLayerInfos = operLayerInfos;
              array.forEach(this.operLayerInfos.getLayerInfoArray(), function(layerInfo) {
                console.info(layerInfo);
                if(layerInfo.title === 'ParksFinder'){
                  this._setupParksPopup(layerInfo);
                }
              }, this);
            }));
          }
        }));
      },

      _setupParksPopup: function(LayerInfo) {
        var infoTemplate = new InfoTemplate();
        infoTemplate.setTitle("Park Name: ${PARK}");
        var templateString = "<b>${NAME}</b><br/>" +
            "<b>Park Website: </b>${PARK_URL:convertLink}<br/>" +
            "<b>Park Map: </b>${PARK_MAP:convertLink}<br/><br/>" +
            "${I_BIKE:checkAvailable}" +
            "${I_WALK:checkAvailable}" +
            "${I_SWIMP:checkAvailable}" +
            "${I_SWIML:checkAvailable}" +
            "${I_DOGWALK:checkAvailable}" +
            "${I_FISH:checkAvailable}" +
            "${I_INTERP:checkAvailable}" +
            "${I_HORSE:checkAvailable}" +
            "${I_PICNIC:checkAvailable}" +
            "${I_RESTRM:checkAvailable}" +
            "${I_PLAYGRD:checkAvailable}" +
            "${I_BOAT:checkAvailable}" +
            "${I_GOLF:checkAvailable}" +
            "${I_ARCHERY:checkAvailable}" +
            "${I_GCAMP:checkAvailable}" +
            "${I_BPCAMP:checkAvailable}" +
            "${I_FCAMP:checkAvailable}";
        infoTemplate.setContent(templateString);
        checkAvailable = function (value, key, data) {
          var boolTest = value.toLowerCase().indexOf('_no_') > 0 ? false : true;
          var retRslt = "";
          if(boolTest){
            retRslt = "<img src='http://gislap183/ParkIcons/" + value + "'/> ";
          }
          return retRslt;
        };
        convertLink = function (value, key, data) {
          var retRslt = "", linkAlias = "";
          switch (key){
            case 'PARK_URL':{
              linkAlias = "More Info";
              break;
            }
            case 'PARK_MAP':{
              linkAlias = "Print Park Map";
              break;
            }
          }
          retRslt = "<a href='" + value + "' target='_blank'>" + linkAlias + "</a>";
          return retRslt;
        };
        LayerInfo.layerObject.setInfoTemplate(infoTemplate);
      },

      _obtainMapLayers: function() {
        // summary:
        //    obtain basemap layers and operational layers if the map is not webmap.
        var basemapLayers = [],
          operLayers = [];
        // emulate a webmapItemInfo.
        var retObj = {
          itemData: {
            baseMap: {
              baseMapLayers: []
            },
            operationalLayers: []
          }
        };

        array.forEach(this.map.graphicsLayerIds, function(layerId) {
          var layer = this.map.getLayer(layerId);
          if (layer.isOperationalLayer) {
            operLayers.push({
              layerObject: layer,
              title: layer.label || layer.title || layer.name || layer.id || " ",
              id: layer.id || " "
            });
          }
        }, this);
        array.forEach(this.map.layerIds, function(layerId) {
          var layer = this.map.getLayer(layerId);
          if (layer.isOperationalLayer) {
            operLayers.push({
              layerObject: layer,
              title: layer.label || layer.title || layer.name || layer.id || " ",
              id: layer.id || " "
            });
          } else {
            basemapLayers.push({
              layerObject: layer,
              id: layer.id || " "
            });
          }
        }, this);

        retObj.itemData.baseMap.baseMapLayers = basemapLayers;
        retObj.itemData.operationalLayers = operLayers;
        return retObj;
      },

Code to add to _publishMapEvent function is on line 19:

      _publishMapEvent: function(map) {
        //add this property for debug purpose
        window._viewerMap = map;
        if (this.loading) {
          this.loading.destroy();
        }

        console.timeEnd('Load Map');
        if (this.map) {
          this.map = map;
          this.resetInfoWindow(true);
          console.log('map changed.');
          topic.publish('mapChanged', this.map);
        } else {
          this.map = map;
          this.resetInfoWindow(true);
          topic.publish('mapLoaded', this.map);
        }
        this._getParksLayer();
      },

View solution in original post

0 Kudos
16 Replies
RobertScheitlin__GISP
MVP Emeritus

Meg,

   Is the service that feeds this popup public?

Is it a field in the data that is null or not that defines if that particular service is available?

0 Kudos
MegPeterson
New Contributor III

Hi Robert -

The service is not public. The data table looks like this though and there are no Null values.

The icons shown in the popup above reference these fields.

Icons are displayed based on the gif image value in each field, referencing them in the assest\images folder in flex or via a virtual directory. i_bile_35.gif displays a white icon for the activity is available; i_no_bike_35.gif displays a grey icon that the activity is not available.

There are also corresponding fields with Y / N values. Ideally I'd like the popup to only reflect the Y values but display the icon images.

Is there a way in the WAB to develop the mapclick popup (infowindow?), or should it be set in the web map? I'm felt I was just getting a handle on Flex and am now treading water in WAB.  Thanks.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Meg,

   Is this going to be a one app deal or are you going to want to make it reusable in more than one app? If it is a one app deal then I can help provide code that you would add the mapManager.js to set the infoWidow content using click event for that particular layer. If it will be something that will need to be added to multiple apps the development of a custom non panel widget.

It would greatly help if you could provide a a sample set of data for dev and testing purposes.

0 Kudos
MegPeterson
New Contributor III

It's a one app deal (for now!). I'll send you a sample set of the data tomorrow when I'm back in the office.

Thank you++

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Meg,

  OK, I have completed the code additions for the MapManager.js for adding the custom infoWindow for your parks layer:

There are three new functions and one line of code to add to an existing function in MapManager.js.

New functions to add:

      _getParksLayer: function() {
        require(["jimu/LayerInfos/LayerInfos"], lang.hitch(this, function(LayerInfos){
          if (this.map.itemId) {
            LayerInfos.getInstance(this.map, this.map.itemInfo)
            .then(lang.hitch(this, function(operLayerInfos) {
              this.operLayerInfos = operLayerInfos;
              array.forEach(this.operLayerInfos.getLayerInfoArray(), function(layerInfo) {
                console.info(layerInfo);
                if(layerInfo.title === 'ParksFinder'){
                  this._setupParksPopup(layerInfo);
                }
              }, this);
            }));
          } else {
            var itemInfo = this._obtainMapLayers();
            LayerInfos.getInstance(this.map, itemInfo)
            .then(lang.hitch(this, function(operLayerInfos) {
              this.operLayerInfos = operLayerInfos;
              array.forEach(this.operLayerInfos.getLayerInfoArray(), function(layerInfo) {
                console.info(layerInfo);
                if(layerInfo.title === 'ParksFinder'){
                  this._setupParksPopup(layerInfo);
                }
              }, this);
            }));
          }
        }));
      },

      _setupParksPopup: function(LayerInfo) {
        var infoTemplate = new InfoTemplate();
        infoTemplate.setTitle("Park Name: ${PARK}");
        var templateString = "<b>${NAME}</b><br/>" +
            "<b>Park Website: </b>${PARK_URL:convertLink}<br/>" +
            "<b>Park Map: </b>${PARK_MAP:convertLink}<br/><br/>" +
            "${I_BIKE:checkAvailable}" +
            "${I_WALK:checkAvailable}" +
            "${I_SWIMP:checkAvailable}" +
            "${I_SWIML:checkAvailable}" +
            "${I_DOGWALK:checkAvailable}" +
            "${I_FISH:checkAvailable}" +
            "${I_INTERP:checkAvailable}" +
            "${I_HORSE:checkAvailable}" +
            "${I_PICNIC:checkAvailable}" +
            "${I_RESTRM:checkAvailable}" +
            "${I_PLAYGRD:checkAvailable}" +
            "${I_BOAT:checkAvailable}" +
            "${I_GOLF:checkAvailable}" +
            "${I_ARCHERY:checkAvailable}" +
            "${I_GCAMP:checkAvailable}" +
            "${I_BPCAMP:checkAvailable}" +
            "${I_FCAMP:checkAvailable}";
        infoTemplate.setContent(templateString);
        checkAvailable = function (value, key, data) {
          var boolTest = value.toLowerCase().indexOf('_no_') > 0 ? false : true;
          var retRslt = "";
          if(boolTest){
            retRslt = "<img src='http://gislap183/ParkIcons/" + value + "'/> ";
          }
          return retRslt;
        };
        convertLink = function (value, key, data) {
          var retRslt = "", linkAlias = "";
          switch (key){
            case 'PARK_URL':{
              linkAlias = "More Info";
              break;
            }
            case 'PARK_MAP':{
              linkAlias = "Print Park Map";
              break;
            }
          }
          retRslt = "<a href='" + value + "' target='_blank'>" + linkAlias + "</a>";
          return retRslt;
        };
        LayerInfo.layerObject.setInfoTemplate(infoTemplate);
      },

      _obtainMapLayers: function() {
        // summary:
        //    obtain basemap layers and operational layers if the map is not webmap.
        var basemapLayers = [],
          operLayers = [];
        // emulate a webmapItemInfo.
        var retObj = {
          itemData: {
            baseMap: {
              baseMapLayers: []
            },
            operationalLayers: []
          }
        };

        array.forEach(this.map.graphicsLayerIds, function(layerId) {
          var layer = this.map.getLayer(layerId);
          if (layer.isOperationalLayer) {
            operLayers.push({
              layerObject: layer,
              title: layer.label || layer.title || layer.name || layer.id || " ",
              id: layer.id || " "
            });
          }
        }, this);
        array.forEach(this.map.layerIds, function(layerId) {
          var layer = this.map.getLayer(layerId);
          if (layer.isOperationalLayer) {
            operLayers.push({
              layerObject: layer,
              title: layer.label || layer.title || layer.name || layer.id || " ",
              id: layer.id || " "
            });
          } else {
            basemapLayers.push({
              layerObject: layer,
              id: layer.id || " "
            });
          }
        }, this);

        retObj.itemData.baseMap.baseMapLayers = basemapLayers;
        retObj.itemData.operationalLayers = operLayers;
        return retObj;
      },

Code to add to _publishMapEvent function is on line 19:

      _publishMapEvent: function(map) {
        //add this property for debug purpose
        window._viewerMap = map;
        if (this.loading) {
          this.loading.destroy();
        }

        console.timeEnd('Load Map');
        if (this.map) {
          this.map = map;
          this.resetInfoWindow(true);
          console.log('map changed.');
          topic.publish('mapChanged', this.map);
        } else {
          this.map = map;
          this.resetInfoWindow(true);
          topic.publish('mapLoaded', this.map);
        }
        this._getParksLayer();
      },
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Meg,

  OK, I have completed the code additions for the MapManager.js for adding the custom infoWindow for your parks layer:

There are three new functions and one line of code to add to an existing function in MapManager.js.

New functions to add:

      _getParksLayer: function() {
        require(["jimu/LayerInfos/LayerInfos"], lang.hitch(this, function(LayerInfos){
          if (this.map.itemId) {
            LayerInfos.getInstance(this.map, this.map.itemInfo)
            .then(lang.hitch(this, function(operLayerInfos) {
              this.operLayerInfos = operLayerInfos;
              array.forEach(this.operLayerInfos.getLayerInfoArray(), function(layerInfo) {
                console.info(layerInfo);
                if(layerInfo.title === 'ParksFinder'){
                  this._setupParksPopup(layerInfo);
                }
              }, this);
            }));
          } else {
            var itemInfo = this._obtainMapLayers();
            LayerInfos.getInstance(this.map, itemInfo)
            .then(lang.hitch(this, function(operLayerInfos) {
              this.operLayerInfos = operLayerInfos;
              array.forEach(this.operLayerInfos.getLayerInfoArray(), function(layerInfo) {
                console.info(layerInfo);
                if(layerInfo.title === 'ParksFinder'){
                  this._setupParksPopup(layerInfo);
                }
              }, this);
            }));
          }
        }));
      },

      _setupParksPopup: function(LayerInfo) {
        var infoTemplate = new InfoTemplate();
        infoTemplate.setTitle("Park Name: ${PARK}");
        var templateString = "<b>${NAME}</b><br/>" +
            "<b>Park Website: </b>${PARK_URL:convertLink}<br/>" +
            "<b>Park Map: </b>${PARK_MAP:convertLink}<br/><br/>" +
            "${I_BIKE:checkAvailable}" +
            "${I_WALK:checkAvailable}" +
            "${I_SWIMP:checkAvailable}" +
            "${I_SWIML:checkAvailable}" +
            "${I_DOGWALK:checkAvailable}" +
            "${I_FISH:checkAvailable}" +
            "${I_INTERP:checkAvailable}" +
            "${I_HORSE:checkAvailable}" +
            "${I_PICNIC:checkAvailable}" +
            "${I_RESTRM:checkAvailable}" +
            "${I_PLAYGRD:checkAvailable}" +
            "${I_BOAT:checkAvailable}" +
            "${I_GOLF:checkAvailable}" +
            "${I_ARCHERY:checkAvailable}" +
            "${I_GCAMP:checkAvailable}" +
            "${I_BPCAMP:checkAvailable}" +
            "${I_FCAMP:checkAvailable}";
        infoTemplate.setContent(templateString);
        checkAvailable = function (value, key, data) {
          var boolTest = value.toLowerCase().indexOf('_no_') > 0 ? false : true;
          var retRslt = "";
          if(boolTest){
            retRslt = "<img src='http://gislap183/ParkIcons/" + value + "'/> ";
          }
          return retRslt;
        };
        convertLink = function (value, key, data) {
          var retRslt = "", linkAlias = "";
          switch (key){
            case 'PARK_URL':{
              linkAlias = "More Info";
              break;
            }
            case 'PARK_MAP':{
              linkAlias = "Print Park Map";
              break;
            }
          }
          retRslt = "<a href='" + value + "' target='_blank'>" + linkAlias + "</a>";
          return retRslt;
        };
        LayerInfo.layerObject.setInfoTemplate(infoTemplate);
      },

      _obtainMapLayers: function() {
        // summary:
        //    obtain basemap layers and operational layers if the map is not webmap.
        var basemapLayers = [],
          operLayers = [];
        // emulate a webmapItemInfo.
        var retObj = {
          itemData: {
            baseMap: {
              baseMapLayers: []
            },
            operationalLayers: []
          }
        };

        array.forEach(this.map.graphicsLayerIds, function(layerId) {
          var layer = this.map.getLayer(layerId);
          if (layer.isOperationalLayer) {
            operLayers.push({
              layerObject: layer,
              title: layer.label || layer.title || layer.name || layer.id || " ",
              id: layer.id || " "
            });
          }
        }, this);
        array.forEach(this.map.layerIds, function(layerId) {
          var layer = this.map.getLayer(layerId);
          if (layer.isOperationalLayer) {
            operLayers.push({
              layerObject: layer,
              title: layer.label || layer.title || layer.name || layer.id || " ",
              id: layer.id || " "
            });
          } else {
            basemapLayers.push({
              layerObject: layer,
              id: layer.id || " "
            });
          }
        }, this);

        retObj.itemData.baseMap.baseMapLayers = basemapLayers;
        retObj.itemData.operationalLayers = operLayers;
        return retObj;
      },

Code to add to _publishMapEvent function is on line 19:

      _publishMapEvent: function(map) {
        //add this property for debug purpose
        window._viewerMap = map;
        if (this.loading) {
          this.loading.destroy();
        }

        console.timeEnd('Load Map');
        if (this.map) {
          this.map = map;
          this.resetInfoWindow(true);
          console.log('map changed.');
          topic.publish('mapChanged', this.map);
        } else {
          this.map = map;
          this.resetInfoWindow(true);
          topic.publish('mapLoaded', this.map);
        }
        this._getParksLayer();
      },
RobertScheitlin__GISP
MVP Emeritus

Example screenshot:

Preview.jpg

0 Kudos
MegPeterson
New Contributor III

Robert - You are invaluable! I'm hoping to load this before taking off today. If not, I'll check in on Monday. A million thanks for your time - I really can't say that enough.

0 Kudos
RickeyFight
MVP Regular Contributor

Meg,

If you get this working can you post a link.

I have the esri solutions parks viewer and am thinking about moving it over to WAB.

Thank you