Search code examples
javascriptreactjsarcgisesri

esri popupTemplate modify


How can i modify the popupTemplate in esri? is it possible for me to modify the popupTemplate according to my design?

I have a popupTemplate

    popupTemplate: {
      content: [{
        type: "fields",
        fieldInfos: [{
          fieldName: "Name"
        }, {
          fieldName: "Owner"
        }, {
          fieldName: "Length"
        }]
      }]
    }

this is the result

enter image description here

what i want design

enter image description here

resource https://totalapis.github.io/sample-code/popup-custom-action/index.html

Update, I am having trouble on my react , when i clicked the icon there is no popup template show

  useEffect(() => {
    if (mapDiv.current) {
      esriConfig.apiKey = process.env.ARCGIS_API;

      const map = new Map({
        basemap: 'arcgis-light-gray'
      });
      const view = new MapView({
        center: [123.5504, 12.3574], // Longitude, latitude
        container: mapDiv.current,
        map: map,
        zoom: 13, // Zoom level
      });
      view
        .when((r) => {})
        .then(() => {
          mapDiv.current = view;
          setMapView(view);
        });


        var list= [{
          type: "fields",
          fieldInfos: [{
            fieldName: "Name "
          }, {
            fieldName: "Owner"
          }, {
            fieldName: "Length"
          }]
        },
        {
          type: "text",
          text: "<div class=\"icontain\"></><a class=\"ic\"><i class=\"bi bi-star\"></i></a><a class=\"ic\"><i class=\"bi bi-geo-alt-fill\"></i></a></div>"
        }]
        var Stack= {
        content: list
        }
      var featureLayer = new FeatureLayer({
        url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/ArcGIS/rest/services/Beverly%20Hills%20Trees%20By%20Block/FeatureServer/0",
       popupTemplate: Stack,
        outFields: ["*"]
      });
      map.add(featureLayer);
    }

    
  }, []);

  const displayLocation = (locations) => {
    mapView.center = [
      locations.data[0].geoCode.longitude,
      locations.data[0].geoCode.latitude,
    ];


  locations.data.map((location) => {
      const point = new Graphic({
        geometry: {
          latitude: location.geoCode.latitude,
          longitude: location.geoCode.longitude,
          type: 'point',
        },
        symbol: LocationPin,
        
      });
      mapView.graphics.add(point);
    });
  };

  return <div className="mapDiv layers" ref={mapDiv}></div>;
}

Solution

  • Hello, a quick solution to modify the Popup template is to add another object with text and text type properties to the template array. the text value will be html code where we will create a div that will show the icons, these with their respective css classes. The most is CSS. Here is an example of the Popup template:

    popupTemplate: {[{
            type: "fields",
            fieldInfos: [{
              fieldName: "Name "
            }, {
              fieldName: "Owner"
            }, {
              fieldName: "Length"
            }]
          },
          {
                type: "text",
                text: "<div class=\"icontain\"></><a class=\"ic\"><i class=\"bi bi-star\"></i></a><a class=\"ic\"><i class=\"bi bi-geo-alt-fill\"></i></a></div>"
              }]
    }
    

    I put an example of this code in operation already with the css, for a better compression. Your remaining task is to play with CSS to make the icon div responsive. For a better visualization of the example, run it in full screen. Another detail is that the example takes time to load due to the multiple CDNs that it needs

    require([
          "esri/Map",
          "esri/views/MapView",
          "esri/layers/FeatureLayer",
          "dojo/domReady!"
        ], function(Map, MapView, FeatureLayer) {
    
          // Create the Map
          var map = new Map({
            basemap: "streets-navigation-vector"
          });
          
          var view = new MapView({
            container: "mapDiv",
            map: map,
            center: [-118.399400711028, 34.08713590709093],
            zoom: 16,
            // 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 list= [{
            type: "fields",
            fieldInfos: [{
              fieldName: "Name "
            }, {
              fieldName: "Owner"
            }, {
              fieldName: "Length"
            }]
          },
          {
                type: "text",
                text: "<div class=\"icontain\"></><a class=\"ic\"><i class=\"bi bi-star\"></i></a><a class=\"ic\"><i class=\"bi bi-geo-alt-fill\"></i></a></div>"
              }]
          
          var Stack= {
          content: list
        }
    
          var featureLayer = new FeatureLayer({
            url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/ArcGIS/rest/services/Beverly%20Hills%20Trees%20By%20Block/FeatureServer/0",
           popupTemplate: Stack,
            outFields: ["*"]
          });
          map.add(featureLayer);
        });
    html,
        body,
        #mapDiv {
          height: 100%;
          width: 100%;
          margin: 0;
          padding: 0;
        }
        
        .esri-popup__main-container{
          border: solid 1px gray;
          border-radius: 10px;
        }
        
        .icontain{
         position: absolute;
        top: 0;
        height: 100%;
        left: -17px;
        display: flex;
        flex-direction: column;
        /* margin-top: auto; */
        /* margin-bottom: auto; */
        /* align-items: center; */
        justify-content: center;
        }
        
        .ic{
          border: solid 1px gray;
        border-radius: 50%;
        width: 33px;
        height: 33px;
        display: flex;
        justify-content: center;
        align-items: center;
        background: white;
        margin-top: 4px;
        margin-bottom: 4px;
        }
    <!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"
      /><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css">
      <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></head>
    
    <body>
      <div id="mapDiv"></div>
    </body>
    
    </html>

    Update

    run this code in your environment. The popup should appear, you should only add the styles

    useEffect(() => {
        if (mapDiv.current) {
          esriConfig.apiKey = process.env.ARCGIS_API_KEY;
    
          const map = new Map({
            basemap: 'arcgis-light-gray', // Basemap layer service
            // portalItem:{
            //     id: "2d11c8164ce04843a38bfde68e00e6e7"
            // }
          });
          const view = new MapView({
            center: [123.5504, 12.3574], // Longitude, latitude
            container: mapDiv.current,
            map: map,
            zoom: 13, // Zoom level
          });
          view
            .when((r) => {})
            .then(() => {
              mapDiv.current = view;
              setMapView(view);
            });
        }
      }, []);
    
      const displayLocation = (locations) => {
        mapView.center = [
          locations.data[0].geoCode.longitude,
          locations.data[0].geoCode.latitude,
        ];
    
    
    
    
        locations.data.map((location) => {
          const point = new Graphic({
            geometry: {
              latitude: location.geoCode.latitude,
              longitude: location.geoCode.longitude,
              type: 'point',
            },
            symbol: LocationPin,
            popupTemplate: {
              title: "Sample",
          
              content: [{
                type: "fields",
                fieldInfos: [{
                  fieldName: "Name"
                }, {
                  fieldName: "Owner"
                }, {
                  fieldName: "Length"
                }]
              },{
                type: "text",
                text: "<div class=\"icontain\"></><a class=\"ic\"><i class=\"bi bi-star\"></i></a><a class=\"ic\"><i class=\"bi bi-geo-alt-fill\"></i></a></div>"
              }]
            }
          });
          mapView.graphics.add(point);
        });
      };
    

    update css for button close

    .esri-popup__header-buttons{
    position: absolute;
        top: 100px;
        margin: 0;
        left: -17px;
        padding: 0;
        background: white;
        border-radius: 50%;
        border: solid 1px;
        width: 32px;
        height: 32px;
        display: flex;
        justify-content: center;
        align-items: center;
    }
    
    .esri-popup__button {
         z-index: 10;
    }
    

    try with this class and styles, to customize the close button