customize print button of print dijit

8797
13
04-16-2013 10:55 AM
KellyEmmons1
New Contributor
I am using the sample code to create a print dijit.  I needed to change the word 'Print' on the button to a printer icon, which I have done using jquery.  But once the button is clicked, the word 'Printing' still appears and then it undoes my printer icon and goes back to the word 'Print'.  How can I customize this button during and after the printing process in addition to beforehand?  Below is the jquery I added to the createPrintDijit function.

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",
  "format": "pdf",
  "options": {
   "legendLayers": [], // empty array means no legend
   "scalebarUnit": "Miles",
   "titleText": "The Title"
   }
    }
];
       
   // create the print templates, could also use dojo.map
    var templates = [];
    dojo.forEach(layouts, function(lo) {
     var t = new esri.tasks.PrintTemplate();
      t.layout = lo.name;
       t.label = lo.label;
       t.format = lo.format;
       t.layoutOptions = lo.options
       templates.push(t);
   });

  app.printer = new esri.dijit.Print({
     "map": map,
  "templates": templates,
  url: app.printUrl,
        }, dojo.byId("printButton"));
  
app.printer.startup();

// fix the print button
$('#dijit_form_Button_0').css('display', 'inline-block');
$('#dijit_form_Button_0').css('width', '24');
$('#dijit_form_Button_0').css('height', '24');
 
var img = $('<img class="inline" src="/images/printer_icon.png" height="24" width="24" />');
$("#dijit_form_Button_0").prepend(img);
$("#dijit_form_Button_0_label").text('');
}
0 Kudos
13 Replies
SteveCole
Frequent Contributor
Random suggestion but how about adding your button "fix" code into a dojo.connect for your print button's onClick event?
0 Kudos
KellyEmmons1
New Contributor
Well, I don't really have a click event or dojo. connect.  All I have in addition to the function I posted is this div in my HTML.  (I just used the example on the javascript API site).

<div id="printButton" style="z-index:998; position:absolute; right:5px; top:5px;"></div>

??
0 Kudos
KellyEmmons1
New Contributor
Below is the code we used to customize the print button with an icon, rather than the word print.  The dojo.connect idea was the right direction:

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",
  "format": "pdf",
  "options": {
   "legendLayers": [], // empty array means no legend
   "scalebarUnit": "Miles",
   "titleText": "Broadband"
   }
    }
 
];
       
   // create the print templates, could also use dojo.map
    var templates = [];
    dojo.forEach(layouts, function(lo) {
     var t = new esri.tasks.PrintTemplate();
      t.layout = lo.name;
       t.label = lo.label;
       t.format = lo.format;
       t.layoutOptions = lo.options
       templates.push(t);
   });

  app.printer = new esri.dijit.Print({
     "map": map,
  "templates": templates,
  url: app.printUrl,
        }, dojo.byId("printButton"));
  
app.printer.startup();

// the code we added to the ESRI example

app.printer._printText = '';
app.printer._printingText = '';
app.printer._printoutText = '';

$(".esriPrintButton").css('display', 'inline-block');
$(".esriPrintButton").css('width', '24');
$(".esriPrintButton").css('height', '24');
 
var img = $('<img class="inline" src="../images/printer_icon.png" height="24" width="24" />');
$(".esriPrintButton").children(".dijitButtonNode").children(".dijitButtonContents").prepend(img);
$(".esriPrintButton").children(".dijitButtonNode").children(".dijitButtonContents").children(".dijitButtonText").text('');


dojo.connect(app.printer,'_createPrintButton',function(value)
{
  $(".esriPrintButton").css('display', 'inline-block');
  $(".esriPrintButton").css('width', '24');
  $(".esriPrintButton").css('height', '24');
  
  var img = $('<img class="inline" src="../images/printer_icon.png" height="24" width="24" />');
  $(".esriPrintButton").children(".dijitButtonNode").children(".dijitButtonContents").prepend(img);
  $(".esriPrintButton").children(".dijitButtonNode").children(".dijitButtonContents").children(".dijitButtonText").text('');
  $(".esriPrintButton").children(".dijitButtonNode").children(".dijitButtonContents").children(".dijitButtonText").hide();

});


}

The HTML is just:
<div id="printButton" style="z-index:998; position:absolute; right:5px; top:5px;"></div>
0 Kudos
KevinMacLeod1
Occasional Contributor III

Hi Kelly,

This does not work in my application.  Is it possible class names or something else changed since 2013?

I'm using API v. 3.10.    I don't follow the app.object pattern I just named my object "printer" for the new Printer constructor.  I updated your example appropriately in that case, and to use my own png icon.   I even added the z-index as you have in html just to be consistent.  What happens is this:  First, the Print button appears just as it always did.  The word Print is there.  My png icon is not. When I click the Print button, for a moment it shrinks to ~10px wide, there is no text.  Nothing. So it's very skinny. (This is when it would normally say "printing").  Then when it's done, it just disappears. The "Printout" link text never shows up. Thoughts?   I'll keep working on this. Conceptually I see what your example is doing.  In theory it should be fine, unless something in the API changed. And we have jQuery object scoped into our main JS file with the map object. We are also using bootstrap 3 and storing the tools in the navbar although I don't think that should cause the issue. Basically I'm just wondering if anyone has done this, this year with a recent version of the API.  I'll keep working on it, looking at it with the F12 dev tools etc.  If I figure it out I'll post back.

Thanks.

update: so far I tried this on ESRI sandbox and JSFiddle.  I borrowed ESRI's sample for referencing jquery, grabbed a 48x48 px printer png icon on the Internet and put it on this JS Fiddle.  Still not working, it exhibits the behavior described above in Sandbox, and button doesn't even show up at first on Fiddle.  Happens with API versions going back to 3.1.  I am beginning to think it's a code issue and not a matter of API version.

Edit fiddle - JSFiddle

0 Kudos
KellyHutchins
Esri Frequent Contributor

Looks like you need to set a valid proxy url. To do this you'll need to setup the Esri/resource-proxy · GitHub‌ then specify the location of your proxy at approximately line 75 in your app code.

0 Kudos
KevinMacLeod1
Occasional Contributor III

Perhaps on Fiddle.  But, left that in for esri Sandbox which I guess allows you to use ESRI's proxy... I just put it into Fiddle for convenience.  But on the ESRI sandbox,   the same thing happens: print button has "Print" text, you click it, then nothing in it, then it disappears. Same for my local code, which I had already set up a proxy for, so print could work.  (IIS / .Net Proxy)  I'll keep testing..

0 Kudos
KellyHutchins
Esri Frequent Contributor

So I read the original post more closely and it looks like you want to change the print text on the widget. The best way to do this is to modify the strings used by the api.  Details on how to access the current strings are here:

Default API Strings | Guide | ArcGIS API for JavaScript

And here are the strings associated with the print widget. After requiring the jsapi resources in your app you can modify them as follows.

        esriBundle.widgets.print.NLS_print = "My Print";

        esriBundle.widgets.print.NLS_printing = "MY Printing";

        esriBundle.widgets.print.NLS_printout= "My Printout";

KellyHutchins
Esri Frequent Contributor

And here's the javascript:

<!doctype html>

<html>

  <head>

    <meta charset="utf-8">

    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">

    <title></title>

    <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/dojo/dijit/themes/tundra/tundra.css">

    <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/esri/css/esri.css">

  

   <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/redmond/jquery.ui.all.css">

     <script src="http://www.google.com/jsapi?key=ABQIAAAAg58_FLn5bynKiZewfpUCeBTyCV9A2YBg0isNV8i_fASKoO0TiRRYqDCtRVNL..."></script>

  

    <style>

      html, body { height: 100%; width: 100%; margin: 0; padding: 0; }

      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;

      }

      #map{ margin: 0; padding: 0; }

      #feedback {

        background: #fff;

        color: #000;

        position: absolute;

        font-family: arial;

        height: auto;

        right: 20px;

        margin: 5px;

        padding: 10px;

        top: 20px;

        width: 300px;

        z-index: 40;

      }

      #feedback a {

        border-bottom: 1px solid #888;

        color: #444;

        text-decoration: none;

      }

      #feedback a:hover, #feedback a:active, #feedback a:visited {

        border: none;

        color: #444;

        text-decoration: none;

      }

      #note { font-size: 80%; font-weight: 700; padding: 0 0 10px 0; }

      #info { padding: 10px 0 0 0; }

    </style>

    <script src="http://js.arcgis.com/3.10/"></script>

    <script>

      var app = {};

      require([

        "esri/map", "esri/layers/FeatureLayer",

        "esri/dijit/Print", "esri/tasks/PrintTemplate",

        "esri/request", "esri/config", "dojo/i18n!esri/nls/jsapi",

        "dojo/_base/array", "dojo/dom", "dojo/parser",

        "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dojo/domReady!"

      ], function(

        Map, FeatureLayer,

        Print, PrintTemplate,

        esriRequest, esriConfig,esriBundle,

        arrayUtils, dom, parser

      ) {

        parser.parse();

dojo.connect(map, "onLoad", function() {

console.log("Map onLoad event");

$(document).ready(jQueryReady);

});

        app.printUrl = "http://sampleserver6.arcgisonline.com/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%2...";

        esriConfig.defaults.io.proxyUrl = "http://localhost/~kell3008/resource_proxy/proxy.php";

       

        esriBundle.widgets.print.NLS_print = "My Print";

        esriBundle.widgets.print.NLS_printing = "MY Printing";

        esriBundle.widgets.print.NLS_printout= "My Printout";

        app.map = new esri.Map("map", {

          basemap: "hybrid",

          center: [-117.447, 33.906],

          zoom: 17,

          slider: false

        });

        // add graphics for pools with permits

        var permitUrl = "http://sampleserver6.arcgisonline.com/arcgis/rest/services/PoolPermits/MapServer/1";

        var poolFeatureLayer = new FeatureLayer(permitUrl, {

          "mode": FeatureLayer.MODE_SNAPSHOT

        });

        app.map.addLayer(poolFeatureLayer);

        // get print templates from the export web map task

        var printInfo = esriRequest({

          "url": app.printUrl,

          "content": { "f": "json" }

        });

        printInfo.then(handlePrintInfo, handleError);

        function handlePrintInfo(resp) {

          var layoutTemplate, templateNames, mapOnlyIndex, templates;

          layoutTemplate = arrayUtils.filter(resp.parameters, function(param, idx) {

            return param.name === "Layout_Template";

          });

         

          if ( layoutTemplate.length == 0 ) {

            console.log("print service parameters name for templates must be \"Layout_Template\"");

            return;

          }

          templateNames = layoutTemplate[0].choiceList;

          // remove the MAP_ONLY template then add it to the end of the list of templates

          mapOnlyIndex = arrayUtils.indexOf(templateNames, "MAP_ONLY");

          if ( mapOnlyIndex > -1 ) {

            var mapOnly = templateNames.splice(mapOnlyIndex, mapOnlyIndex + 1)[0];

            templateNames.push(mapOnly);

          }

         

          // create a print template for each choice

          templates = arrayUtils.map(templateNames, function(ch) {

            var plate = new PrintTemplate();

            plate.layout = plate.label = ch;

            plate.format = "PDF";

            plate.layoutOptions = {

              "authorText": "Made by:  Esri's JS API Team",

              "copyrightText": "<copyright info here>",

              "legendLayers": [],

              "titleText": "Pool Permits",

              "scalebarUnit": "Miles"

            };

            return plate;

          });

          // create the print dijit

          app.printer = new Print({

            "map": app.map,

            "templates": templates,

            url: app.printUrl

          }, dom.byId("print_button"));

          app.printer.startup();

     

         

        }

        function handleError(err) {

          console.log("Something broke: ", err);

        }

      });

    </script>

  </head>

  <body class="tundra">

    <div data-dojo-type="dijit/layout/BorderContainer"

         data-dojo-props="design:'headline',gutters:false"

         style="width: 100%; height: 100%; margin: 0;">

      <div id="map"

           data-dojo-type="dijit/layout/ContentPane"

           data-dojo-props="region:'center'">

        <div id="feedback" class="shadow">

          <h3>

            Print Templates Created from Info Returned by the Print Service using

            <a href="https://developers.arcgis.com/javascript/jsapi/esri.request-amd.html">esri.request</a>

          </h3>

          <div id="info">

            <div id="note">

              Note:  This sample uses an ArcGIS Server version 10.1 export web map task.

            </div>

           

            <!-- that will be used for the print dijit -->

            <div id="print_button"></div>

            <div id="info">

              <a href="https://developers.arcgis.com/javascript/jsapi/printtemplate.html">Print templates</a> are generated

              from the Export Web Map Task's <a href="http://sampleserver6.arcgisonline.com/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%2...">Layout_Template parameter</a>. This info is retrieved from the service

              using <a href="https://developers.arcgis.com/javascript/jsapi/esri.request-amd.html">esri.request</a>.

            </div>

          </div>

        </div>

      </div>

    </div>

  </body>

</html>

0 Kudos
KevinMacLeod1
Occasional Contributor III

Hi Kelly,

Thank you for the reply.

Ideally I want a button with the Printer icon and no text anywhere. After a user selects the Print page size/orientation in the dropdown, or just clicks the main button, it opens a new window with the print.  Nice and clean.  (new window event attached to releasing the click of the menu selection). No "Printout" link text.  Hm.  I will read your comment and hopefully construct such a feature. So far, modifying the strings of text works perfectly.  Thank you. That documentation is good.

However I copied your code to the ESRI sandbox.  I noted your change to your local proxy and different print task, so I reinserted the two print lines from the ESRI print sample:

        app.printUrl = "        var permitUrl = "http://sampleserver6.arcgisonline.com/arcgis/rest/services/PoolPermits/MapServer/1";

";

          esriConfig.defaults.io.proxyUrl = "/proxy";

  The Print button has its regular text and then disappears after being clicked.    When the code at this fiddle Edit fiddle - JSFiddle is pasted into the ESRI sandbox. I'll keep working on it...

For now to stick the icon "in" the button I might just put the button in a div along with the png file over it and position them with the absolute tag.  And set all three text strings to a few spaces with  .

0 Kudos