I've been tasked with adding print functionality to our website. Specifically, we need to have a toolbar button that can be used to print the map - just the map - none of the other stuff on the page. I'm kinda new to web programming and arcGis and Javascript, so I'm not sure what to do. I found the following sample code, but I don't know if it's still valid (sometimes stuff goes stale).
https://developers.arcgis.com/javascript/jssamples/widget_print.html
In addition, I'm not sure how to alter the code to point to our maps instead of the 'sample' map in the code. Any assistance would be appreciated.
Hi Dave,
That sample is still relevant. Can you provide some more background on your map? For example, how was it created, i.e. JavaScript API, ArcGIS Online? Can you post the URL or code for the map?
This is a part of the app that I am not familiar with, so I may include too much (or not enough) code to answer your question. Our development framework is Asp.net 4.5 using the mvc model
<script id="MapConfig" type="text/javascript" > //global map pointer var map; //get the default basemap //note that this can be overridden by the projection //[standard basemaps are not compatible with projected coordinate systems] require(["esri/map", "esri/layers/FeatureLayer", "esri/geometry/Extent", "esri/SpatialReference", "dojo/domReady!"], function (Map, FeatureLayer, Extent, SpatialReference) { //TODO: get the default extent for this feature var defaultZoom = null; defaultZoom = new Extent(-120, 0, 90, 40, new SpatialReference({ wkid: 4326 }));; @if (Model.TheLayer.Project.BaseMap == null) { @:map = createMap(defaultZoom, "topo", "locatorMap"); } else { @:map = createMap(defaultZoom, "@Model.TheLayer.Project.BaseMap.MapCode", "locatorMap"); } //add the project layers loadProjectLayers(map); loadOutputLayers(map); //request the feature extent as our default zoom var requestText = "/api/@Model.TheLayer.MapLayerSource.LayerType.ControllerName/GetGraphic" + "?MapFeatureId=@Model.TheFeature.Id.ToString()" + "&MapLayerId=@Model.TheLayer.LayerId.ToString()" ; require(["dojo/request/xhr"], dojo.hitch(this, function (xhr) { new xhr(requestText, { handleAs: "json" }).then( function (data) { //TODO: determine if we load geographic or projected data var geometryParser = new geometryWktParser(); //parse the specified shape var srid = '@Model.TheLayer.MapLayerSource.Dataset.MapProjection.ToString()'; var shape = geometryParser.loadShapeGeographic(data.WellKnownText, srid); var projectedShape = esri.geometry.geographicToWebMercator(shape); //apply to the map map.setExtent(projectedShape.getExtent().expand(5)); }) })); }) function createMap(extent, baseMap, domHost) { //use the default dom host, if none specified if (!domHost) { domHost = "map";} //construct an esri map component var theMap; require(["esri/map"], function (Map) { theMap = new Map(domHost, { basemap: baseMap, extent: extent, sliderStyle: "small", sliderPosition: "top-right" }) }); return theMap; } </script>
Hmmm... I just tried 'View Live Sample' on the code page, and the page that is supposed to be running the sample is having problems on my system. It looks fine, but when you click the 'Print" button, nothing is sent to the printer - no printer dialog pops up or anything. Sometimes the 'print' button changes to a 'Printout' hyperlink, which navigates to another page with an image of the map. Is that how it's supposed to print?
Here is an example that still has the scalebar and date and map, but nothing else (also you can see a live example at Print a Map Just a click on the hammer icon and then the print icon and it will bring up a live print example):
<!DOCTYPE html> <html> <head> <title>Print a Map</title> <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="http://js.arcgis.com/3.11/dijit/themes/soria/soria.css"> <link rel="stylesheet" href="http://js.arcgis.com/3.11/esri/css/esri.css"> <style> html, body, #mapDiv { padding:0; margin:0; height:100%; width:100%; position:absolute; z-index:0; } /* Printer CSS Begin */ h3 { margin: 0 0 5px 0; border-bottom: 1px solid #444; padding: 0 0 5px 0; text-align: center; } .shadow { -moz-box-shadow: 0 0 5px #888; -webkit-box-shadow: 0 0 5px #888; box-shadow: 0 0 5px #888; } #feedback { background: #fff; border: 2px solid #666; border-radius: 5px; bottom: 20px; color: #666; font-family: arial; height: auto; left: 20px; margin: 5px; padding: 10px; position: absolute; width: 300px; z-index: 40; visibility:hidden; } #feedback a { border-bottom: 1px solid #888; color: #666; text-decoration: none; } #feedback a:hover, #feedback a:active, #feedback a:visited { border: none; color: #666; text-decoration: none; } #note { padding: 0 0 10px 0; } #info, #information { padding: 10px 0 0 0; } /* Printer CSS End */ #showTools { height:20px; width:20px; position:absolute; top:200px; left:20px; z-index:50; padding:5px 6px 5px 6px; background-color:#f9f8f8; border-radius:5px; visibility:visible; } #hideTools { height:20px; width:20px; position:absolute; top:200px; left:20px; z-index:50; padding:5px 6px 5px 6px; background-color:#f9f8f8; border-radius:5px; visibility:hidden; } #printer { height:20px; width:20px; position:absolute; top:240px; left:20px; z-index:50; padding:5px 6px 5px 6px; background-color:#f9f8f8; border-radius:5px; visibility:hidden; } </style> <script src="http://js.arcgis.com/3.11/"></script> <script> var app = {}; require(["esri/map", "esri/config", "esri/dijit/Print", "esri/geometry/Extent", "esri/layers/ArcGISDynamicMapServiceLayer", "esri/layers/ArcGISTiledMapServiceLayer", "esri/layers/FeatureLayer", "esri/tasks/GeometryService", "esri/tasks/PrintTemplate", "dojo/_base/array", "dojo/dom", "dojo/on", "dojo/parser", "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dojo/domReady!"], function (Map, esriConfig, Print, Extent, ArcGISDynamicMapServiceLayer, ArcGISTiledMapServiceLayer, FeatureLayer, GeometryService, PrintTemplate, arrayUtils, dom, on, parser ) { parser.parse(); /* The proxy comes before all references to web services */ /* Files required for security are proxy.config, web.config and proxy.ashx - set security in Manager to Private, available to selected users and select Allow access to all users who are logged in (Roles are not required) /* The proxy section is defined on the ESRI sample. I have included it as part of the documentation reads that the measuring will not work. I thought that might be important. */ // Proxy Definition Begin //identify proxy page to use if the toJson payload to the geometry service is greater than 2000 characters. //If this null or not available the project and lengths operation will not work. // Otherwise it will do a http post to the proxy. esriConfig.defaults.io.proxyUrl = "proxy.ashx"; esriConfig.defaults.io.alwaysUseProxy = false; // Proxy Definition End // set custom extent var initialExtent = new Extent({ "xmin": 777229.03, "ymin": 1133467.92, "xmax": 848340.14, "ymax": 1185634.58, "spatialReference": { "wkid": 3435 } }); // create map and set slider style to small var map = new Map("mapDiv", { showAttribution: false, sliderStyle: "small", extent: initialExtent, logo:false }); // add imagery var tiled = new ArcGISTiledMapServiceLayer("http://maps.decaturil.gov/arcgis/rest/services/Aerial_2014_Tiled/MapServer"); map.addLayer(tiled); // set operational layers var operationalLayer = new ArcGISDynamicMapServiceLayer("http://maps.decaturil.gov/arcgis/rest/services/Public/InternetVector/MapServer", { "opacity": 0.5 }); // add operational layers map.addLayer(operationalLayer); // add point feature layer var pointFeatureLayer = new FeatureLayer("http://maps.decaturil.gov/arcgis/rest/services/Test/FeatureServer/0"); map.addLayer(pointFeatureLayer); // declare geometry service esriConfig.defaults.geometryService = new GeometryService("http://maps.decaturil.gov/arcgis/rest/services/Utilities/Geometry/GeometryServer"); // begin print widget app.printUrl = "http://maps.decaturil.gov/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%20Web%20Map%2..."; createPrintDijit("Print Map"); function createPrintDijit(printTitle) { var layoutTemplate, templateNames, mapOnlyIndex, templates; // create an array of objects that will be used to create print templates var layouts = [{ name: "Letter ANSI A Landscape", label: "Landscape (PDF)", format: "pdf", options: { legendLayers: [] // empty array means no legend //scalebarUnit: "Miles", //titleText: printTitle + ", Landscape PDF" } }, { name: "Letter ANSI A Portrait", label: "Portrait (Image)", format: "jpg", options: { legendLayers: [] //scalebarUnit: "Miles", //titleText: printTitle + ", Portrait JPG" } }]; // create print templates var templates = arrayUtils.map(layouts, function (lo) { var t = new PrintTemplate(); t.layout = lo.name; t.label = lo.label; t.format = lo.format; t.layoutOptions = lo.options; return t; }); app.printer = new Print({ map: map, templates: templates, url: app.printUrl }, dom.byId("print_button")); app.printer.startup(); } // end of print widget // Hides print widget on(dom.byId("closePrint"), "click", function () { document.getElementById("feedback").style.visibility = 'hidden'; }); // Shows tools on(dom.byId("showTools"), "click", function () { document.getElementById("showToolsButton").style.visibility = 'hidden'; document.getElementById("hideToolsButton").style.visibility = 'visible'; document.getElementById("printer").style.visibility = 'visible'; }); // Hide tools on(dom.byId("hideTools"), "click", function () { document.getElementById("showToolsButton").style.visibility = 'visible'; document.getElementById("hideToolsButton").style.visibility = 'hidden'; document.getElementById("printer").style.visibility = 'hidden'; document.getElementById("feedback").style.visibility = 'hidden'; }); // Show print widget on(dom.byId("showPrintWidget"), "click", function () { document.getElementById("feedback").style.visibility = 'visible'; }); } ); </script> </head> <body class="soria"> <div id="mapDiv"> <div id="showTools"> <input type="image" id="showToolsButton" src="images/hammer.png" alt="Show Tools" title="Show Tools" /> </div> <div id="hideTools"> <input type="image" id="hideToolsButton" src="images/close.ico" alt="Hide Tools" title="Hide Tools" /> </div> <div id="printer"> <input type="image" id="showPrintWidget" src="images/print.ico" alt="Print" title="Print" /> </div> <div id="feedback"> <h3> City of Decatur Print Service </h3> <div id="information"> <div id="note"> Note: Select the format that you would like to print your map from the dropdown below. </div> <!-- used for the print dijit --> <div id="print_button"></div> <div id="info"> This print service is to be used for City business only. <input type="image" id="closePrint" src="images/close.ico" alt="Close" title="Close" /> </div> </div> </div> </div> </body> </html>
Thanks so much for your response, Chris. I should have posted something sooner saying that my dev lead and I chose to go with a simple css media=print solution to this for now. However, I'll keep this code for the future in case I need it.