Print Popup Feature Menu and Feature Tables

368
3
Jump to solution
01-04-2024 10:30 AM
MatthewDriscoll
MVP Alum

Is there a print option for  the popup feature menu?  Also is there a print option for feature table?  If anyone has done this I appreciate any tips you have.  

0 Kudos
1 Solution

Accepted Solutions
MatthewDriscoll
MVP Alum

Here is my solution to printing the popup feature menu.

 

https://codepen.io/mbdriscoll/pen/GReBgYd

 

 

<html lang="en">

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
  
  <title>Feature Layer Popup Test</title>

  <link rel="stylesheet" href="https://js.arcgis.com/4.28/esri/themes/dark/main.css" />
  <script src="https://js.arcgis.com/4.28/"></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/Basemap",
      "esri/layers/TileLayer",
    ], (Map,MapView,FeatureLayer,Basemap,TileLayer) => {


      const aerial2022 = new Basemap({
        baseLayers: [
        new TileLayer({
          url: "https://www.jfksgis.us/image/rest/services/Aerials/Aerials_2022_cache/MapServer",
          title: "Basemap"
        }),           
        ],
        title: "2022 Aerial",
        visible: true,        
      });

      const parcelLayer = new FeatureLayer({
        url: "https://www.jfksgis.us/server/rest/services/BaseLayers/JFKSBaseMapLayers/MapServer/3",
        title: 'Search Results',
        popupTemplate : createPopupTemplate(),
        listMode: "hide",
        outFields:["*"]
      });

      const theMap = new Map({
          basemap :  aerial2022,
          layers : [parcelLayer] 
      });

      const theView = new MapView({
          container : "viewDiv",
          map : theMap,
          center : [-95.3804157, 39.2315224],
          highlightOptions: {
            color: [64, 247, 244],
            fillOpacity: 0.2,         
          },
          popup: {
            visibleElements: {
              closeButton: true,
            },
            dockEnabled: true,
            dockOptions: {
              autoOpenEnabled: false,
              position: "bottom-right",
              breakpoint: false,
              buttonEnabled: false,          
            },
          },         
      });

      function createPopupTemplate(){
        const urlTax = "https://ks1418.cichosting.com/ttp/tax/Search/search_tax_results.aspx?";
        const urlRC = "https://www.jfksgis.us/prc/"
        var parInfo = 'https://www.jfksgis.us/JFKSParcelSearch/parcelInformation.html';
        var platy = "Replace($feature.Plat_HL, ' ', '%20')"
        return{
          title:
            "<b>Owner:</b> {PartyName_1} " + 
            "<br /><b>Address: </b> {PropertyAddress}" +
            "<br><b>Property Number: </b> {PropertyNumber}" +
            "<br><b>Appraisal:</b> ${RP_AprTot}", 
          outFields: ["*"],
          content:
            [
              {
                type: "fields",
                fieldInfos:[
                  {
                    fieldName: "QuickRefID",
                    label: "Quick Ref ID",
                  },
                  {
                    fieldName: "ACRES",
                    label: "Acres",
                    format:{
                      places: 2,
                    }
                  },                
                ]
              },
              {
                type: "text",
                text: "<a class='hyperlinkURL' target='_blank' href=" + parInfo + "?PropertyID={PropertyID}&PID={PID}&PropNum={PropertyNumber}>Parcel Information</a>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<a class='hyperlinkURL' target='_blank' href=" + urlTax + "PID={PID}>Tax Information</a>"
              },
              {
                type: "text",
                text: "<a class='hyperlinkURL2' target='_blank' href=https://{expression/platlinked}>View Plat</a>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<a class='hyperlinkURL' href=" + urlRC + "{PropertyNumber}.pdf>Property Record Card</a>", 
              },          
            ],      
            expressionInfos:[
              {
                name: "platlinked",
                expression: platy, 
              },
            ],
            fieldInfos:[{
              fieldName: "RP_AprTot",
              label: "Total Appraised Value",
              format: {
                places: 2,
                digitSeparator: true,
              }         
            },
          ],
        
        }     
      };

      function addButtonToContainer() {
        const isElementLoaded = async selector => {
          while (document.querySelector(selector) === null) {
            await new Promise(resolve => requestAnimationFrame(resolve));
          }
        };
      
        // Wait for the feature menu container to be fully loaded
        isElementLoaded('.esri-popup__main-container').then(() => {
          console.log("Feature menu container loaded");
          let myDiv = document.querySelector('.esri-popup__main-container');
          let button = document.createElement('button5');
          button.innerText = "Print";
          button.style.position = "absolute";
          button.style.top = "5px";
          button.style.right = "5px";
          button.style.zIndex = "9999"; // Set a high z-index value
          button.style.backgroundColor = "white";
          button.style.color = "black";
          button.style.fontWeight = "bold";
          button.style.padding = "3px 3px";
          button.style.cursor = "pointer";
          button.addEventListener("click", printDiv);
          myDiv.appendChild(button);
        });
      }

      function printDiv(){
        const isElementLoaded = async selector => {
          while (document.querySelector(selector) === null) {
            await new Promise(resolve => requestAnimationFrame(resolve));
          }
        }
        isElementLoaded('.esri-popup__main-container').then(() => {
          console.log("Feature menu loaded");

          var printContent = document.querySelector('.esri-popup__main-container').innerHTML;
          const modifiedContent = printContent.replace(/Back/g, '').replace(/Owner/g, '<br><br><br>Owner');
          printWindow = window.open('', '_blank');
          printWindow.document.write(modifiedContent);
          printWindow.document.close();
          // Wait for a short period before printing
          setTimeout(function() {
            printWindow.print();
          }, 100);
          
        })  
      };
      

      let query = parcelLayer.createQuery();
      query.where = "PartyName_1 LIKE '%driscoll%'";
      query.outFields = [ "*" ];

      parcelLayer.queryFeatures(query)
        .then(function(response) {
          // Open the popup with the queried features
          theView.openPopup({
            features: response.features,
            featureMenuOpen: true,
            featuresPerPage: 100,
          }),
          addButtonToContainer();          
        });

    });
  </script>
</head>

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

</html>

 

View solution in original post

0 Kudos
3 Replies
Noah-Sager
Esri Regular Contributor

Hi @MatthewDriscoll. For printing tables, yes, we do have this ability with print():

https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-PrintTemplate.html#i...

We expect to have this functionality available for the Print widget at a future release.

For more print options, there is a blog post about how to use HTML2Canvas to capture even more inputs into the print output:

https://community.esri.com/t5/arcgis-instant-apps-blog/screenshots-with-the-arcgis-api-for-javascrip...

 

 

0 Kudos
MatthewDriscoll
MVP Alum

Are there any examples.  When I use featureTable.print() I get the error that it is not a function.  The link shows how to print from the export/print widget.  I would like to print direct from the custom option newMenuItem to print the table.   

If I use a newMenuItem to open a new window to print the table using print(), it loses all the grids that make it a table.  

The HTML2DCanvas seems promising, I will work on testing that out.  

0 Kudos
MatthewDriscoll
MVP Alum

Here is my solution to printing the popup feature menu.

 

https://codepen.io/mbdriscoll/pen/GReBgYd

 

 

<html lang="en">

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
  
  <title>Feature Layer Popup Test</title>

  <link rel="stylesheet" href="https://js.arcgis.com/4.28/esri/themes/dark/main.css" />
  <script src="https://js.arcgis.com/4.28/"></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/Basemap",
      "esri/layers/TileLayer",
    ], (Map,MapView,FeatureLayer,Basemap,TileLayer) => {


      const aerial2022 = new Basemap({
        baseLayers: [
        new TileLayer({
          url: "https://www.jfksgis.us/image/rest/services/Aerials/Aerials_2022_cache/MapServer",
          title: "Basemap"
        }),           
        ],
        title: "2022 Aerial",
        visible: true,        
      });

      const parcelLayer = new FeatureLayer({
        url: "https://www.jfksgis.us/server/rest/services/BaseLayers/JFKSBaseMapLayers/MapServer/3",
        title: 'Search Results',
        popupTemplate : createPopupTemplate(),
        listMode: "hide",
        outFields:["*"]
      });

      const theMap = new Map({
          basemap :  aerial2022,
          layers : [parcelLayer] 
      });

      const theView = new MapView({
          container : "viewDiv",
          map : theMap,
          center : [-95.3804157, 39.2315224],
          highlightOptions: {
            color: [64, 247, 244],
            fillOpacity: 0.2,         
          },
          popup: {
            visibleElements: {
              closeButton: true,
            },
            dockEnabled: true,
            dockOptions: {
              autoOpenEnabled: false,
              position: "bottom-right",
              breakpoint: false,
              buttonEnabled: false,          
            },
          },         
      });

      function createPopupTemplate(){
        const urlTax = "https://ks1418.cichosting.com/ttp/tax/Search/search_tax_results.aspx?";
        const urlRC = "https://www.jfksgis.us/prc/"
        var parInfo = 'https://www.jfksgis.us/JFKSParcelSearch/parcelInformation.html';
        var platy = "Replace($feature.Plat_HL, ' ', '%20')"
        return{
          title:
            "<b>Owner:</b> {PartyName_1} " + 
            "<br /><b>Address: </b> {PropertyAddress}" +
            "<br><b>Property Number: </b> {PropertyNumber}" +
            "<br><b>Appraisal:</b> ${RP_AprTot}", 
          outFields: ["*"],
          content:
            [
              {
                type: "fields",
                fieldInfos:[
                  {
                    fieldName: "QuickRefID",
                    label: "Quick Ref ID",
                  },
                  {
                    fieldName: "ACRES",
                    label: "Acres",
                    format:{
                      places: 2,
                    }
                  },                
                ]
              },
              {
                type: "text",
                text: "<a class='hyperlinkURL' target='_blank' href=" + parInfo + "?PropertyID={PropertyID}&PID={PID}&PropNum={PropertyNumber}>Parcel Information</a>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<a class='hyperlinkURL' target='_blank' href=" + urlTax + "PID={PID}>Tax Information</a>"
              },
              {
                type: "text",
                text: "<a class='hyperlinkURL2' target='_blank' href=https://{expression/platlinked}>View Plat</a>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp<a class='hyperlinkURL' href=" + urlRC + "{PropertyNumber}.pdf>Property Record Card</a>", 
              },          
            ],      
            expressionInfos:[
              {
                name: "platlinked",
                expression: platy, 
              },
            ],
            fieldInfos:[{
              fieldName: "RP_AprTot",
              label: "Total Appraised Value",
              format: {
                places: 2,
                digitSeparator: true,
              }         
            },
          ],
        
        }     
      };

      function addButtonToContainer() {
        const isElementLoaded = async selector => {
          while (document.querySelector(selector) === null) {
            await new Promise(resolve => requestAnimationFrame(resolve));
          }
        };
      
        // Wait for the feature menu container to be fully loaded
        isElementLoaded('.esri-popup__main-container').then(() => {
          console.log("Feature menu container loaded");
          let myDiv = document.querySelector('.esri-popup__main-container');
          let button = document.createElement('button5');
          button.innerText = "Print";
          button.style.position = "absolute";
          button.style.top = "5px";
          button.style.right = "5px";
          button.style.zIndex = "9999"; // Set a high z-index value
          button.style.backgroundColor = "white";
          button.style.color = "black";
          button.style.fontWeight = "bold";
          button.style.padding = "3px 3px";
          button.style.cursor = "pointer";
          button.addEventListener("click", printDiv);
          myDiv.appendChild(button);
        });
      }

      function printDiv(){
        const isElementLoaded = async selector => {
          while (document.querySelector(selector) === null) {
            await new Promise(resolve => requestAnimationFrame(resolve));
          }
        }
        isElementLoaded('.esri-popup__main-container').then(() => {
          console.log("Feature menu loaded");

          var printContent = document.querySelector('.esri-popup__main-container').innerHTML;
          const modifiedContent = printContent.replace(/Back/g, '').replace(/Owner/g, '<br><br><br>Owner');
          printWindow = window.open('', '_blank');
          printWindow.document.write(modifiedContent);
          printWindow.document.close();
          // Wait for a short period before printing
          setTimeout(function() {
            printWindow.print();
          }, 100);
          
        })  
      };
      

      let query = parcelLayer.createQuery();
      query.where = "PartyName_1 LIKE '%driscoll%'";
      query.outFields = [ "*" ];

      parcelLayer.queryFeatures(query)
        .then(function(response) {
          // Open the popup with the queried features
          theView.openPopup({
            features: response.features,
            featureMenuOpen: true,
            featuresPerPage: 100,
          }),
          addButtonToContainer();          
        });

    });
  </script>
</head>

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

</html>

 

0 Kudos