Select to view content in your preferred language

If, Else Popups

671
2
Jump to solution
11-30-2022 07:44 AM
ITApplications
Occasional Contributor

Hi all

I'd like my map to display two different popups. 'If' I click on the feature layer it return the popup related to that layer, 'Else' if I click anywhere other than the feature it returns a different popup.

I currently have two separate maps , each with their own different type of popup.

 

1. On this map you only return a popup if you hit the feature (street line): this has a customContent template directly related to the feature layer. Clicking anywhere else nothing is returned.

const customContent = new CustomContent({
              outFields: ["*"],
              creator: (event) => {
              const location = view.popup.location;
              const locationContent = `X: ${location.x.toFixed(0)}<br>Y: ${location.y.toFixed(0)}<br>`;
              const name = `<font size='3px'><b>Street:</b> ${event.graphic.attributes["SITE_NAME"]}<br><b>Town:</b> ${event.graphic.attributes["TOWN_NAME"]}<br>`;
              const link = `<br><a href=\"https://east-riding-self.test.achieveservice.com/service/Dangerous_building_or_structure_issue?` +
 `street=${event.graphic.attributes["SITE_NAME"]}&town=${event.graphic.attributes["TOWN_NAME"]}&USRN=${event.graphic.attributes["SITE_CODE"]}&Easting=${location.x.toFixed(0)}&Northing=${location.y.toFixed(0)}"` +
			          ` rel="nofollow ugc" style="display: block; height: 60px; width: 242px; background: #CC5500; color: #ffffff; text-align: center; font-weight: bold; font-size: 140%; line-height: 60px; padding: 7px;  font-family: Arial; border-radius: 8px; text-decoration: none;">Report a traffic safety concern</a>`;
                
              return name + link;
              },
           });
            
            const template = new PopupTemplate({
                outFields: ["*"],
                content: [customContent],
            });
                
        const streetLayer = new FeatureLayer({
          url: "https://services6.arcgis.com/Qptn479QktK11k72/arcgis/rest/services/New_Achieve_Streets_layer/FeatureServer/0",
          outFields: ["*"],
          });
          
       streetLayer.maxScale=350;
       streetLayer.minScale=2500;
       streetLayer.popupTemplate = template;
          map.add(streetLayer);

 

2. On this map you can click anywhere and it returns the popup (it never interacts with the feature layer).

view.popup.autoOpenEnabled = false;
      view.on("click", (event) => {
      if (view.scale <= 2500) {
      const x = Math.round(event.mapPoint.x * 1) / 1;
      const y = Math.round(event.mapPoint.y * 1) / 1;
      
      view.popup.open({
      content: `<a href=\"https://east-riding-self.test.achieveservice.com/service/Fly_posting_or_illegal_signs?` + `Easting=${x}&Northing=${y}"` + `target="_blank" rel="nofollow ugc" style="display: block; height: 60px; width: 242px; background: #CC5500; color: #ffffff; text-align: center; font-weight: bold; font-size: 160%; line-height: 60px; padding: 6px;  font-family: Arial; border-radius: 7px; text-decoration: none;">Report fly-posting or an illegal sign</a>`,
    location: event.mapPoint
      });
      }
      });

 

I've tried putting the two sets of code onto the same map. However the '2' code (click anywhere) just seems to override everything and if I click on the feature (street layer) it just displays the 2nd popup.

I'm guessing I need a, 'If' you hit the feature display that popup, 'Else' display the click anywhere popup.

How do I go about this please? My attempts have failed. 

Thanks Ricky

0 Kudos
1 Solution

Accepted Solutions
JeffreyWilkerson
Frequent Contributor

If you had the features in the same map, you could search the View's onclick for any graphics related to one layer, and if they exist, only show the popup for that layer (by only gathering up the features for that layer). Then, if features weren't found for that layer, you could use those for that feature's popup (by only passing the features for that layer). 

This is how I'd approach it:

<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
    <title>Intro to FeatureLayer | Sample | ArcGIS API for JavaScript 4.25</title>

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

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

    <script>
      require([
        "esri/Map", 
        "esri/views/MapView", 
        "esri/layers/FeatureLayer",
        "esri/PopupTemplate"], (Map, MapView, FeatureLayer, PopupTemplate) => {
        const map = new Map({
          basemap: "hybrid"
        });

        const view = new MapView({
          container: "viewDiv",
          map: map,
          extent: {
            // autocasts as new Extent()
            xmin: -9177500,
            ymin: 4247200,
            xmax: -9176900,
            ymax: 4247600,
            spatialReference: 102100
          }
        });

        /********************
         * Add feature layer
         ********************/

        // Carbon storage of trees in Warren Wilson College.
        const treeLayer = new FeatureLayer({
          url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Landscape_Trees/FeatureServer/0",
          id: "treeLayer",
          popupTemplate: {
            title: "Trees Layer",
            content: [
              { type: "fields", // FieldsContentElement
                fieldInfos: [
                  { fieldName: "Tree_ID"},
                  { fieldName: "Collected"}
                ]
             }]
          }
        });
        
        const dTileLayer = new FeatureLayer({
          url: "https://services.arcgis.com/QCty4ZXRXx9qyVVL/arcgis/rest/services/Download_Tiles_Ashville_NC/FeatureServer/0",
          id: "dTileLayer",
          popupTemplate: {
            title: "Download Tiles Layer",
            content: [
              { type: "fields", // FieldsContentElement
                fieldInfos: [
                  { fieldName: "Name"},
                  { fieldName: "Path"}
                ]
             }]
          }
        });

        map.addMany([treeLayer, dTileLayer]);
        
        view.popup.autoOpenEnabled = false;
        
        
        view.on("immediate-click", (event) => {
          view.hitTest(event).then((response) => {
            let treeGraphics = response.results.filter(function (result) {
              return result.graphic.layer === treeLayer;
            });
            let dTileGraphics = response.results.filter(function (result) {
              return result.graphic.layer === dTileLayer;
            });
            
            var features2Use = [];
            if (treeGraphics.length > 0) {
              for (var i = 0; i < treeGraphics.length; i++) {
                features2Use.push(treeGraphics[i].graphic);
              }
            }
            else if (dTileGraphics.length > 0) {
              for (var i = 0; i < dTileGraphics.length; i++) {
                features2Use.push(dTileGraphics[i].graphic);
              }
            }
            view.popup.open({
             features: features2Use
            });
            
          });
        });
        
      });
    </script>
  </head>

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

View solution in original post

2 Replies
JeffreyWilkerson
Frequent Contributor

If you had the features in the same map, you could search the View's onclick for any graphics related to one layer, and if they exist, only show the popup for that layer (by only gathering up the features for that layer). Then, if features weren't found for that layer, you could use those for that feature's popup (by only passing the features for that layer). 

This is how I'd approach it:

<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
    <title>Intro to FeatureLayer | Sample | ArcGIS API for JavaScript 4.25</title>

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

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

    <script>
      require([
        "esri/Map", 
        "esri/views/MapView", 
        "esri/layers/FeatureLayer",
        "esri/PopupTemplate"], (Map, MapView, FeatureLayer, PopupTemplate) => {
        const map = new Map({
          basemap: "hybrid"
        });

        const view = new MapView({
          container: "viewDiv",
          map: map,
          extent: {
            // autocasts as new Extent()
            xmin: -9177500,
            ymin: 4247200,
            xmax: -9176900,
            ymax: 4247600,
            spatialReference: 102100
          }
        });

        /********************
         * Add feature layer
         ********************/

        // Carbon storage of trees in Warren Wilson College.
        const treeLayer = new FeatureLayer({
          url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Landscape_Trees/FeatureServer/0",
          id: "treeLayer",
          popupTemplate: {
            title: "Trees Layer",
            content: [
              { type: "fields", // FieldsContentElement
                fieldInfos: [
                  { fieldName: "Tree_ID"},
                  { fieldName: "Collected"}
                ]
             }]
          }
        });
        
        const dTileLayer = new FeatureLayer({
          url: "https://services.arcgis.com/QCty4ZXRXx9qyVVL/arcgis/rest/services/Download_Tiles_Ashville_NC/FeatureServer/0",
          id: "dTileLayer",
          popupTemplate: {
            title: "Download Tiles Layer",
            content: [
              { type: "fields", // FieldsContentElement
                fieldInfos: [
                  { fieldName: "Name"},
                  { fieldName: "Path"}
                ]
             }]
          }
        });

        map.addMany([treeLayer, dTileLayer]);
        
        view.popup.autoOpenEnabled = false;
        
        
        view.on("immediate-click", (event) => {
          view.hitTest(event).then((response) => {
            let treeGraphics = response.results.filter(function (result) {
              return result.graphic.layer === treeLayer;
            });
            let dTileGraphics = response.results.filter(function (result) {
              return result.graphic.layer === dTileLayer;
            });
            
            var features2Use = [];
            if (treeGraphics.length > 0) {
              for (var i = 0; i < treeGraphics.length; i++) {
                features2Use.push(treeGraphics[i].graphic);
              }
            }
            else if (dTileGraphics.length > 0) {
              for (var i = 0; i < dTileGraphics.length; i++) {
                features2Use.push(dTileGraphics[i].graphic);
              }
            }
            view.popup.open({
             features: features2Use
            });
            
          });
        });
        
      });
    </script>
  </head>

  <body>
    <div id="viewDiv"></div>
  </body>
</html>
ITApplications
Occasional Contributor

Hi Jeffrey

Thank you for your advice. I've taken a look at what you have advised and I've managed to adapt if for what I require.

I only have one feature layer on my map and I needed to return its defined popup if the feature was interacted with, else just return a generic popup (that was just recording the X/Y of where a user clicked).

This has worked for me.

 

 

view.popup.autoOpenEnabled = false;
      
      view.on("click", (event) => {
        if (view.scale <= 2500) {
          view.hitTest(event).then((response) => {
            let streetGraphics = response.results.filter(function (result) {
              return result.graphic.layer === streetLayer;
            });
      
            var features2Use = [];
            if (streetGraphics.length > 0) {
              for (var i = 0; i < streetGraphics.length; i++) {
                features2Use.push(streetGraphics[i].graphic);
              }
            }
             view.popup.open({
             features: features2Use
            });
            });
        }
        });
      
      
      view.on("click", (event) => {
      const x = Math.round(event.mapPoint.x * 1) / 1;
      const y = Math.round(event.mapPoint.y * 1) / 1;
      
      view.popup.open({
      content: `<a `Easting=${x}&Northing=${y}"` + `target="_blank" rel="nofollow ugc" style="display: block; height: 40px; width: 242px; background: #CC5500; color: #ffffff; text-align: center; font-weight: bold; font-size: 185%; line-height: 40px; padding: 6px;  font-family: Arial; border-radius: 7px; text-decoration: none;">Click anywhere popup</a>`,
    location: event.mapPoint
      });
      });

 

 



Thanks for your help and advice, Ricky

0 Kudos