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.
Solved! Go to Solution.
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>      <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>      <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>
Hi @MatthewDriscoll. For printing tables, yes, we do have this ability with print():
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:
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.
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>      <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>      <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>