csergent08

Extended Print Task and Making Desktop jQuery Work on Mobile

Blog Post created by csergent08 Champion on Jan 14, 2015

Before I say anything, links are provided for the complete code at the end of this post. I have been dealing with the print task for years. I even created my own when I was still developing in the Web ADF in 2010. You can check it out if your nostalgic. I'm not so much. I took a look at Esri's example here, but didn't quite like it as I didn't want it always covering my map. I like having screen real estate, so I just added a button to hide the print widget as shown below.

printOriginal.png

But this only provided me with two options. I decided that I wanted to extend the print widget so that you had options like entering your own title, deciding what format you wanted to print in and a selection of landscape and portrait as well as not showing the print task when the app started, centering it, and making it draggable. Right away I had issues and needed help. I had problems right away as you can see here. And I continued to have other issues, but rather than continue to show you the posts of my questions, I will show you how to do a print task here to look like the following.

printerSelection.png

As usual, this will be done in three parts, but just a little different as we are using jQuery as well this time. And we are going to add some buttons to the app. To do all of this, the first thing we are going to do is add jQuery to our application. If you would like to use jQuery, you can download jQuery here. You can take a look at my projects on github to see where to place everything or use my projects.  And I have added quite a few images but they are in just two images folder. If you have matched up my new files if your following along, all we have to do now is add the code. If you are just following along, that will be even easier.

Step 1

Add the HTML, but I am going to break this step up so you you can see what is happening. All code will be written in order. First you add a reference to your jQuery stylesheets in the header after the other stylesheets.

<!-- jQuery Styles -->
<link href="css/custom-theme/jquery-ui-1.10.3.custom.min.css" rel="stylesheet" type="text/css" />

 

Now we will skip past code that we have already written from previous posts and we will go straight to our new code. We need to first add our new buttons.

<!-- Show Tools Begin -->
            <div id="showTools">
                <input type="image" id="showToolsButton" src="images/hammer.png" alt="Show Tools" title="Show Tools" />
            </div>
            <!-- Show Tools End -->


            <!-- Hide Tools Begin -->
            <div id="hideTools">
                <input type="image" id="hideToolsButton" src="images/close.ico" alt="Hide Tools" title="Hide Tools" />
            </div>
            <!-- Hide Tools End -->


            <!-- Show Printer Begin -->
            <div id="showPrinter">
                <input type="image" id="showPrintWidget" src="images/print.ico" alt="Print" />
            </div>
            <!-- Show Printer End -->

 

So now we have the buttons that will show and hide our print widget. Now we need to add the HTML to display the print widget.

<!-- Print Form Begin -->
            <form id="frmPrint" action="" onsubmit="return false;">
                <!-- Printer Begin -->
                <div id="printer">
                    <h3>City of Decatur Print Service</h3>
                    <!-- Information Begin -->
                    <div id="information">
                        <div id="note">Note: Select the format that you would like to print your map from the dropdowns below.</div>
                        <!-- Content for print dijit Begin -->
                        <label id="lblPrintTitle">Enter a print title</label>
                        <br />
                        <input type="text" id="printTitleId" name="printTitle" value="Street Light Inventory" />
                        <br />
                        <br />
                        <!-- Print Layout Begin -->
                        <select name="printLayout" id="printLayoutId">
                          <option value="A3 Landscape">A3 Landscape</option>
                          <option value="A3 Portrait">A3 Portrait</option>
                          <option value="A4 Landscape">A4 Landscape</option>
                          <option value="A4 Portrait">A4 Portrait</option>
                          <option value="Letter ANSI A Landscape" selected>Letter ANSI A Landscape</option>
                          <option value="Letter ANSI A Portrait">Letter ANSI A Portrait</option>
                          <option value="Tabloid ANSI B Landscape">Tabloid ANSI B Landscape</option>
                          <option value="Tabloid ANSI B Portrait">Tabloid ANSI B Portrait</option>
                        </select>
                        <!-- Print Layout End -->


                        <!-- Print Format Begin -->
                        <select name="printFormat" id="printFormatId">
                          <option value="pdf" selected>PDF</option>
                          <option value="png32">PNG32</option>
                          <option value="png8">PNG8</option>
                          <option value="jpg">JPG</option>
                          <option value="gif">GIF</option>
                          <option value="eps">EPS</option>
                          <option value="svg">SVG</option>
                        </select>
                        <!-- Print Format End -->
                        <br />
                        <br />
                        <button type="button" id="btnPrintReady">Print</button>
                        <a href="#" id="printResult" target="_blank" style="display:none;">Get Printout</a>
                        <!-- Info Begin -->
                        <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>
                        <!-- Info End -->    
                        <!-- Content for print dijit End -->
                    </div>
                    <!-- Information End -->
                </div>
                <!-- Printer End -->
            </form>
            <!-- Print Form End -->

Finally I will reference jQuery. If your are wondering what jquery touch-punch is. That's what allows us to use jQuery desktop on mobile devices so we can drag objects with our fingers and interact with them. So now we have the print widget interface. You can clearly see where different divs begin and end. I find this easier to maintain my code.

Step 2

Add the JavaScript. One thing I like to do to provide intellisense for jQuery is to reference my jQuery files like so:

/// <reference path="jquery-1.9.1.js" />
/// <reference path="jquery.ui.touch-punch.js" />
/// <reference path="jquery-ui-1.10.3.custom.min.js" />

 

Now we need to add the new references that we need to run the print task.

"esri/tasks/PrintTask",          // printer
         "esri/tasks/PrintParameters",    // printer
         "esri/tasks/PrintTemplate",      // printer
         "dojo/_base/array",  

Don't forget about the related variables following the function statement.

 

// begin print Task
             app.printUrl = "http://maps.decaturil.gov/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%20Web%20Map%20Task";


             function createPrintTask(printTitle) {
                 var template = new PrintTemplate();
                 template.layout = document.getElementById("printLayoutId").value; // Assigns the layout
                 template.format = document.getElementById("printFormatId").value; // Assigns the format to printout to
                 template.layoutOptions = {
                     legendLayers: [], // empty array means no legend
                     scalebarUnit: "Miles",
                     titleText: printTitle // title to display
                 };


                 var params = new PrintParameters();
                 params.map = map;
                 params.template = template;


                 var printTask = new PrintTask(app.printUrl);
                 var printObj = {
                     printTask: printTask,
                     params: params
                 }
                 return printObj;
             }




             // Activates printer
             on(dom.byId("btnPrintReady"), "click", function () {
                 document.getElementById("btnPrintReady").innerHTML = "Printing..."
                 document.getElementById("btnPrintReady").disabled = true; // Button disable while printing
                 var printObj = createPrintTask(document.getElementById("printTitleId").value); // Gets titles displayed
                 var printTask = printObj.printTask;
                 printTask.execute(printObj.params, function (evt) {
                     document.getElementById("btnPrintReady").style.display = 'none';
                     document.getElementById("printResult").href = evt.url;
                     document.getElementById("printResult").style.display = 'block';
                     on(dom.byId("printResult"), "click", function () {
                         document.getElementById("btnPrintReady").innerHTML = "Print";
                         document.getElementById("btnPrintReady").style.display = 'block';
                         document.getElementById("btnPrintReady").disabled = false; // Button enabled to produce map print
                         document.getElementById("printResult").style.display = 'none';
                     });
                 }, function (evt) {
                     document.getElementById("btnPrintReady").disabled = false;
                     document.getElementById("btnPrintReady").innerHTML = "Print";
                 });
             });
             // end of print task

This creates and runs our print task. Now I still want to be able to show or hide tools, show or hide the print widget and be able to drag the print widget, so we do the following.

// Hides print widget
             on(dom.byId("closePrint"), "click", function () {
                 document.getElementById("printer").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("showPrinter").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("showPrinter").style.visibility = 'hidden';
                 document.getElementById("printer").style.visibility = 'hidden';
             });


             // Allow print widget to move with mouse or finger
             jQuery(function () {
                 jQuery("#printer").draggable({ containment: "window" });
             });


             // Show print widget
             on(dom.byId("showPrintWidget"), "click", function () {
                 document.getElementById("printer").style.visibility = 'visible';
             });

 

Only one thing left to do.

Step 3

Add style. This may vary depending on the template that you want to use. This CSS will be for GIS Mobile which has the most functionality. I set my CSS to also center the Print Widget when it displays. And it does not show up initially providing more screen real estate if necessary. Here is the CSS to do that.

 

/* 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;
    }
    #printer {
      background: #fff;
      border: 2px solid #666;
      border-radius: 5px;
      bottom: 20px;
      color: #666;
      font-family: arial;
      height: 300px;
      top:30%;
      left: 30%;
      margin: 5px;
      padding: 10px;
      position: absolute;
      width: 300px;
      z-index: 40;
      visibility: hidden;
    }
    #printer a {
      /*border-bottom: 1px solid #888;*/
      color: #666;
      text-decoration: none;
    }
    #printer a:hover,
    #printer a:active,
    #printer a:visited {
      border: none;
      color: #666;
      text-decoration: none;
    }
    #note {
      padding: 0 0 10px 0;
    }
    #info,
    #information {
      padding: 10px 0 0 0;
    }
   
    #showPrinter {
      height: 30px;
      width: 30px;
      position: absolute;
      top: 260px;
      left: 20px;
      z-index: 50;
      padding: 5px 6px 5px 6px;
      background-color: #f9f8f8;
      border-radius: 5px;
      visibility: hidden;
    }
    /* Printer CSS End */
    
    /* Style tool buttons on hover */
     #showTools:hover, #hideTools:hover, #showPrinter:hover, #editor:hover
     {
         background:#eee;
     }
   
    #showTools {
      height: 30px;
      width: 30px;
      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: 30px;
      position: absolute;
      top: 200px;
      left: 20px;
      z-index: 50;
      padding: 5px 6px 5px 6px;
      background-color: #f9f8f8;
      border-radius: 5px;
      visibility: hidden;
    }

 

That completes the print task. This is just an excerpt, but you can go online and get the complete code for the templates. Grab the Esri based template the web based template, or the mobile based template. From here the templates will be separating. I have been building three to serve a purpose. The next post on code, we will add the ability to geocode an address to our templates. The templates aren't done yet. Once these templates are complete, we will have foundation to build from.

Outcomes