Skip navigation
All People > csergent08 > Chris Sergent Lost in GIS
1 2 Previous Next

Chris Sergent Lost in GIS

26 posts
csergent08

Women Developers in GIS

Posted by csergent08 Champion Aug 21, 2015

As I start this topic off, I realize that I can not relate to what it is to be a GIS developer as a woman, but I can relate what it is like to deal with barriers to knowledge and goals in life. I have also seen instances where women have been overlooked for opportunities exclusively based on sex. Unfortunately, the people that do it don't have to say that is the reason; there is always something else they could come up with.

 

First, let me tell you a little bit about myself and why this is important to me. I used to work for the State of Illinois and during that time I was limited to software, support and conferences. Basically I could not go anywhere to grow in knowledge. Once I left the State, eliminating barriers to others in the growth of their professional careers and knowledge sharing became important to me. For this reason I worked hard on getting a DevMeetup to Decatur, Illinois and we had one. I am now working on getting people interested in having a smaller DevSummit in what I call flyover country, so more people have access to this very valuable resource. Now these things are important to me because I remember the guy that did not have access to all of these resources before and that brings me to the topic at hand.

 

While attending a DevMeetup in San Diego, California, a woman said, of course, no women. Their were a few. But the developers were mainly men. During last years DevSummit while talking a twitter, it was noticed that there was a lack of women. But at this point, my question is why are there so few.

 

For the women that read this; what barriers do you work through in getting into this field? Have you been well received? What questions am I not asking that you know the answer to that could help myself and others in the field of GIS developer?

 

I have seen women that I consider successful developers in GIS. One is Kelly Hutchins  and the other is Amy Niessen. Kelly is an engineer for the ArcGIS API for JavaScript at Esri and presents at the Esri User Conference as well as the Esri DevSummit. Amy is a Developer Team Coordinator for the EDN team at Esri. Amy is at the Esri User Conference, Esri DevSummit and Esri DevMeetups. If you are are developer, you will meet her if you are at one of these events as she is very dedicated to the developer community as is her team.

 

If you are a woman seeking to meet woman professionals in GIS, I encourage to seek either Kelly or Amy out. They are very approachable and I am sure they would answer any questions that you have.

 

Now for me, I would like to see more women volunteering for presentations at DevMeetups at Esri events. I think it would be an opportunity to encourage other women to do the same.

 

I realize, my thoughts are from the perspective of a man, but I would like to hear what you have to say. And if you have any tips on professional groups for Women in GIS, please share so anyone reading this post will have access to knowledge resources.

 

If there are barriers that I or men in general can do, to help eliminate them, I would like to know, because that is exactly what I like to do, is to eliminate barriers so that everyone has an opportunity to succeed equally, with whatever resources I have.

 

With that, I think the more diversity that  we have in the field of GIS Development, the more issues we can solve together. So, I'm glad you are here.

csergent08

Life and Code

Posted by csergent08 Champion Apr 10, 2015

For me a blog is sometimes a good way to think out loud or share knowledge. Right now I'm thinking out loud. I am a runner, a mild weight lifter, a developer and a diabetic. Last year I was dealing with plantar fasciitis after recovering from inflammation of my IT band. My plantar fasciitis became so severe that it limited my running and eventually I fractured my cuboid. Don't know what that is? Neither did I, but it's a larger bone on the outside of your foot behind the little toe. I also now know there are 26 bones in your foot. After this healed I find out I still have plantar fasciitis, but not in one foot, but both feet and a possible torn rotator cuff and my IT band seemed to be flaring up, and some weight gain. So, I am dealing with four injuries and added weight, which does not help injuries at all. There is only one thing to do, stop working out or modify what I do. I chose to modify what I do. I work on strengthening my rotator cuff, go to physical therapy for my plantar fasciitis, as well as do other stretching and exercises that help with it, warm up on a stationary bike, do dynamic stretching before I run and use a foam roller to painfully massage my IT band and other muscles. Sometimes you just have to change your thinking to get things done. Everything seems to be working, but very slowly,

 

As with life, coding is sometimes quite similar. You need to understand, I did not come from a geography background, and if I went into more detail, all the following was still development. My first GIS actually was Windows Paint. Yep, I manually created my color scheme one click at a time with only one undo available. Over time I went from ArcView 3.x, to ArcView 8.1 and then got briefly into ArcGIS Engine. Finally, I ended up in Web Development using the Web ADF, which I did not like. Next, it was the option of Silverlight, Flex and the JavaScript API. If you were at the DevSummit in 2012, you might have thought that everything was going to go Flex. But after checking out the three API's I felt JavaScript would be the way to go. But even that has changed on me a couple of times. The way we use Dojo is not the way it was used when Dojo came out and soon there will be a JavaScript API 4.0, another way of writing code for the JavaScript API. I hope it's simpler and less code and samples with more comments. That is usually where samples lose me, when you have to figure out what someone else was thinking.

 

At least with the current Esri JS API I got a template working for editing, address searching, a custom print task and other features, but when tested in the field, the editor was deemed to be too small for touch, so I am now working on another new area that I am unfamiliar with, responsive web design. I have a sample of mostly what I want to do, but I am having difficulty with it. I will be posting it today after I take another look at it. But as I said earlier, sometimes you have to modify what you do. So far, what I have learned from responsive web design is, that's the way all apps should be, not sometimes. I am on a learning path that will help me better understand this concept and I am building my own personal responsive website as well, very clunky right now. But it has a cool name; gisdev.net  I thought with the editor widget I could just inspect all of the elements and make the editor widget larger, but I also thought that it probably has a lot of elements and may not be a good idea. The alternative for me to attempt to modify an Esri example to get my work done while learning the new concept of responsive web design so that I can later make a custom application the way that I want with minimal code and ample documentation.

 

The sample is good. But it's a responsive app which is new to me, and has left me a little frustrated a few times trying to figure out how to convert it. In the end at least I will have more knowledge. I do like that, but sometimes you just have to vent your frustrations of incomprehension while you're in the learning process until you get to that a-ha! moment.

Each night before my wife and I go to bed, we have a routine of telling each other what happened during the day. We tell each other the best thing about the day, and the worst thing about the day and then one thing that we appreciate about the other. Reflecting on this, I thought this could benefit teams working together during a project or at a project's end. What were the positives that you saw during the project? What were some of the negatives? What was something that each member of the team did that you appreciated? For me, the last one is key. This provides the opportunity for everyone to be appreciated and acknowledged for their contribution that was made during the project. This has been a beneficial routine for my wife and I, but applying this to recognition in a project environment was just a thought I had. What do you think?

csergent08

Congratulations Esri!

Posted by csergent08 Champion Apr 2, 2015

As a government employee for 15 years, I have worked with a lot of vendors and know the value of customer service. In this article Jack and Laura Dangermond are being honored. The article talks about how the company has succeeded through changing technology, but for me that's not the only reason they have succeeded. Esri staff and Esri customer service has been and is the best that I interact with. From developer meetups to training to conferences, I have not met an Esri employee that is not willing to help out with my needs in GIS development. Even Jack Dangermond is very interested in the community. I have sent him a total of two e-mails since I started working at my current job. He responded to both indirectly. One was complimenting his staff and that individual let me know that Jack spoke to that individual and appreciated it. I've spoken to Jack on more than one occasion and he is very interested in what I have had to say. Do I think I'm special? No, he treats everyone like that. He is approachable, interested and values feedback and he and his staff demonstrate this everyday. So, I just want to say congratulations to Jack and Laura Dangermond and all of Esri staff and thank you for a product that helps me love the field that I work in.

csergent08

Teamwork and Collaboration

Posted by csergent08 Champion Mar 23, 2015

Back in the 90's while still in college, as many do, I participated in student activities. Always the pessimist, I ran for Vice President of the Student Senate. I felt if I'm going to lose I would like to at least say I ran for something big. It didn't turn out as I had expected; I won. So, I became very active and the Student Senate became very important for me. Not a lot was getting done, which I found frustrating. I wanted more done and I only wanted people in the Student Senate that wanted to make it better. Because of this I started asking others to recruit students to the vacant positions, but I wanted those positions to be important to the student as well. I wanted quality over quantity. Some thought that I took this student activity too seriously, but my thought was that there were students that voted for us and had expectations and I was going to do my best as their representative. By the end of the year we filled all of our Student Senate seats and I ran for President and won again. For me, that year would have the great impact for me as a professional. I went on a team building exercise with the rest of the Student Senate and found I liked the impact of what we could do by working together as a team and collaborating our ideas to accomplish goals. So, this is where I part from my college days to my coding days.

 

For me, GeoNet has been a place for teamwork and collaboration. If you knew me, you could see that in everything I do. I created a web developer group on LinkedIn, a running group on Facebook and GeoNet and I attend conferences and meetups wherever whenever I can as well as contribute in each. For me it's about one thing, supporting one another in our endeavors. I still don't understand how many developers work on very similar projects and don't try working together more. I have appreciated the help on GeoNet from people like Robert Scheitlin, GISP and Kelly Hutchins and Tim Witt and there are others. As they help me, I try to help others as well. Sometimes it's a guess; you never know what might spark an idea. Sometimes I have to research from my side and have come up with the answers a few times and glad I have been able to contribute some of my knowledge back to the community.

 

Even with the help and the interaction on here, I do wish there was more of a desire for members here, or in the developer community in general to work together to come up with new ideas, write better and more efficient code. But until or if that happens, we will continue to see what developers can do instead of what they could have done, by working together.

csergent08

The Running DevS

Posted by csergent08 Champion Mar 17, 2015

There are a lot of ways to connect with other developers that program with Esri software, such as meetups and conferences, but sometimes we can get so busy at events that we forget to connect with one another. I'm diabetic so I have a need to workout which I do, and eat right, which comes and goes. I was hoping to go to the DevSummit this year and thought it would be fun to go running with others. I had someone to run with originally, but that fell through. But that's okay, you've always got to have a backup plan. So, I created a group called The Running DevS with the acronym of TRDS, just to add a little levity to it. If the off chance that I could not find anyone to run with I also contacted a running store in Palm Springs. Their staff offered to show me some trails while out there as well, which is good, as I tend to get lost on trails when I run them on my own. As luck had it, the DevSummit came and I could not get approval to go, so no running in Palm Springs this year. But like I said, you've got to have a backup plan. Although the DevSummit did not get approved, I have been approved to attend the Esri UC in San Diego. There is still an issue with this. I am currently injured. That would have actually ruined a trail run in Palm Springs too now that I think about it. Last year through running, I ended up with plantar fasciitis in my right foot, received some good advice, and treated it with rest, limited running, and different stretches. But unfortunately during a trail run, I suffered a stress fracture of my cuboid; same foot. That healed and now I am dealing with peroneal tendonitis, again in the same foot. However, my goal is still to do some running at the user conference if I can heal in time. With everything that has happened to my foot, not to mention a possible torn rotator cuff in my left arm, I still will not give up.

 

As for the group of The Running DevS. I thought creating the group would facilitate an opportunity for developers that are also runners to have a chance to talk running, code, and ideas in developing GIS apps. But more than anything, it would provide runners that have a common job a chance to get to know one another while doing something that we all have in common.

 

If you plan on attending the Esri UC, I encourage you to join my group and even if I am not at a future event, my hope for this group is that The Running DevS will still be able to get together for a run.

 

If you would like to be part of The Running DevS, join my group here: The Running DevS  How fast you are and your abilities do not matter. Let's just have fun. Hope to run with you soon.

From time to time I see somebody post a question or ask during a thread on how to format their posted code. There are actually quite a few posts that tell you how to do it, but I decided to post this one for those of you that learn visually. It's a very short video, but it will provide you with a visual demo on how to format your code. Enjoy.

 

For the mobile and desktop web apps I create, I like to provide the user with a way to contact me in the event that they run into trouble in the application. More often than not, a user sends an e-mail and puts no subject in it, which might make it appear vague as to what application they are talking about, so my e-mail links not only include "to", but also the "subject",  typed in for the user, which displays the application name and a brief message in the "body" that instructs the user to describe the issue they are having. I place it in a dojo pane at the bottom right of the page. To create this pane with this type of content, just add the HTML here and don't forget to require the dojo title pane in you AMD application.

<!-- Mail Pane Begin -->
            <div id="mailPane" data-dojo-type="dijit/TitlePane"
                               data-dojo-props="title:'Ask For Assistance',closeable:false,open:false">
                <!-- Send Mail Begin -->
                <div id="send Mail">
                    <p>Contact <a href="mailto:email@someone.com?subject=GIS Mobile App&body=Please Provide some information on your issue.">Contact me for help.</a>
                                if you need assistance or need to report an issue.</p>
                </div>
                <!-- Send Mail End -->
            </div>
            <!-- Mail Pane End -->

And this CSS will place the pane at the bottom right hand corner of your web page.

 

/* Mail Pane Style */
    #mailPane
    {
        width:240px;
        position:absolute;
        right:0%;
        bottom:0%;
        background-color:White;
        border-color:Black;
        width:auto;
        z-index:50;
    }
    .soria  .dijitTitlePaneTitle {
        background: #fff;
        font-weight:600;
        border: none;
        border-bottom:solid 1px #29201A;
        border-top:solid 1px #29201A;
    }
           
    .soria .dijitTitlePaneTitleHover
    {
        background:#eee;
    }
           
    .soria .dijitTitlePaneTitleActive
    {
        background:#808775;
    }
           
    .soria .dijitTitlePaneContentOuter
    {
        border-right: none;
        border-bottom: none;
        border-left: none;
    }

 

There is no JavaScript required and this completes the mobile template. You can get a full working copy here. You can also try a live demo here. The user name is field and the password is test.

Today we are going to continue on and create the editor widget. If you would like to see what the code looks like before it's added, you can get it here. With the editor widget, you can allow staff to go out and enter data remotely on a mobile device using geolocation which is implemented in this application and the information immediately updates to the server. For me, the only downside to the editor widget is that you can only edit spatial data. I was hoping you would be able to edit data in non-spatial database tables as well. The new DataAdapterFeatureLayer widget, which you can read about under what's new in version 3.12 allows you to read data that has no spatial information, but does not allow you to edit the data. I still have hope for that in a future release. But with that, let's add the editor widget to our application. If you want to add it to yours, you can pretty much follow what I did here. The one nuance is that I have a "geocode an address" in my template app and the infoWindows conflict with the editor widget. The good news is that I have a work around built into my application that avoids this conflict. If you have infoWindows conflicting in your app, this may give you some ideas on how to create your own work around for your issue. But, let's add the editor widget to the mobile template.

 

First, I like to create a button to show the editor widget, because there are times the user may want to hide it while working on the map. I just provide a button to bring it back, so after the showPrinter button we add this code:

 

 

<!-- Show Editor Begin -->
            <div id="editor">
                <input type="image" id="showEditorWidget" src="images/edit.ico" alt="Editor" title="Editor" />
            </div>
            <!-- Show Editor End -->

 

Now it's time to create the editor panel. I have added a close button on the editor so it can be hidden as stated above. You can actually place this code anywhere on your page as we will use CSS to place it where we want it.

<!-- Editor Pane Begin -->
            <div id="templatePickerPane">
                <!-- Editor Header Begin -->
                <div id="panelHeader">
                  <p>Default Editor<input type="image"
                                          id="closeEditor"
                                          src="images/close.ico"
                                          alt="Close Editor"
                                          title="Close Editor" />
                 </p>
                </div>
                <!-- Editor Header End -->
                
                <!-- Edito Begin -->
                <div id="editorDiv">
           
                </div>
                <!-- Editor End -->
          </div>
          <!-- Editor Pane End -->

 

Now it's time to style our editor. I like to put it about half way down the screen and against the right side. For placement and other styling, we add the following code:

/* Editor style begin */
           
    #templatePickerPane {
        width: 250px;
        height:260px;
        overflow: hidden;
        z-index:50;
        top:50%;  /* Half way down the screen */
        right:0%;/* Against the right side of the screen */
        position:absolute;
    }
           
    #panelHeader
    {
        background-color: #92A661;
        border-bottom: solid 1px #92A860;
        color: #FFF;
        font-size: 18px;
        height: 50px;
        line-height: 22px;
        margin: 0;
        overflow: hidden;
        padding: 10px 10px 10px 10px;
               
    }
           
                       
    #editorDiv
    {
        background-color:White;
        padding:10px;
    }


             
        .esriEditor .templatePicker
    {
        padding-bottom: 5px;
        padding-top: 5px;
        height: 120px;
        border-radius: 0px 0px 4px 4px;
        border: solid 1px #92A661;
    }


        .dj_ie .infowindow .window .top .right .user .content, .dj_ie .simpleInfoWindow .content
    {
        position: relative;
    }
           
   
           
           
    #closeEditor
    {
        position:absolute;
        right:5%;
    }
    
    
   
           
    #editor
    {
        height:30px;
        width:30px;
        position:absolute;
        top:320px;
        left:20px;
        z-index:50;
        padding: 5px 6px 6px 6px;
        background-color:#f9f8f8;
        border-radius:5px;
        visibility:hidden;
    }
    
    
     /* Editor Style End */
     
     /* Style tool buttons on hover */
     #showTools:hover, #hideTools:hover, #printer:hover, #editor:hover
     {
         background:#eee;
     }

 

Moving on to JavaScript, we need to add our declarations. I have included all declarations and variables that you need up to this point in this excerpt:

var map;
var editorWidget = null;
var featureLayerInfos;
var graphic;
var currLocation;
var watchId;
var pt;
var app = {};
// Get references to modules to be used
require(["esri/map",                                // mapSection
         "esri/config",                             // The default values for all JS API configuration options. 


         "esri/Color",  // measurementDiv


         "esri/dijit/editing/Editor",           // Editor
         "esri/dijit/Geocoder",                     // search
         "esri/dijit/HomeButton",                   // homeButton
         "esri/dijit/LocateButton",                 // locateButton
         "esri/dijit/Measurement", // measurementDiv
         "esri/dijit/OverviewMap", // Overview Map
         "esri/dijit/Scalebar",  // Scalebar


         "esri/geometry/Extent", // The minimum and maximum X- and Y- coordinates of a bounding box. Used to set custom extent
         "esri/geometry/Point",
         "esri/geometry/screenUtils", // search


         "esri/graphic", // search


         "esri/IdentityManager", // editor


         "esri/layers/ArcGISDynamicMapServiceLayer",
         "esri/layers/ArcGISTiledMapServiceLayer",
         "esri/layers/LayerDrawingOptions", // measurementDiv
         "esri/layers/FeatureLayer",


         "esri/renderers/SimpleRenderer", // measurementDiv


         "esri/SnappingManager", // measurementDiv    -add snapping capability


         "esri/sniff", // measurementDiv


         "esri/SpatialReference",  // editor


         "esri/symbols/SimpleFillSymbol", // measurementDiv
         "esri/symbols/SimpleLineSymbol", // measurementDiv
         "esri/symbols/SimpleMarkerSymbol", // search


         "esri/tasks/GeometryService",    // Represents a geometry service resource exposed by the ArcGIS Server REST API.
         "esri/tasks/PrintTask",          // printer
         "esri/tasks/PrintParameters",    // printer
         "esri/tasks/PrintTemplate",      // printer
         "esri/tasks/ProjectParameters",  // editor


         "esri/toolbars/draw",


         "dojo/_base/array",
         "dojo/_base/Color",                    // search
         "dojo/dom",                            // It is used for code like - dom.byId("someNode")
         "dojo/dom-construct",                  // search
         "dojo/keys",
         "dojo/on",                             // This module is used based on an even such as on("click")
         "dojo/parser",                         // The Dojo Parser is an optional module.
         "dojo/query",                      // search
         "dojo/i18n!esri/nls/jsapi",
         "dojo/dnd/Moveable",


         "dijit/layout/BorderContainer",
         "dijit/layout/ContentPane",
         "dijit/TitlePane",
         "dijit/form/CheckBox",
         "dojo/domReady!"],    // An AMD loaded plugin that will wait until the DOM has finished loading before returning.


// Set variables to be used with references (write variables and references in the same order and be careful of typos on your references)
         function (Map, esriConfig, Color,
                   Editor, Geocoder, HomeButton,
                   LocateButton, Measurement,
                   OverviewMap, Scalebar, Extent,
                   Point, screenUtils, Graphic,
                   IdentityManager, ArcGISDynamicMapServiceLayer, ArcGISTiledMapServiceLayer,
                   LayerDrawingOptions, FeatureLayer, SimpleRenderer,
                   SnappingManager, has, SpatialReference,
                   SimpleFillSymbol, SimpleLineSymbol, SimpleMarkerSymbol,
                   GeometryService, PrintTask, PrintParameters,
                   PrintTemplate, ProjectParameters, Draw,
                   arrayUtils, Color, dom,
                   domConstruct, keys, on,
                   parser, query, i18n,
                   Moveable) {

I like to only have three variables per line for readability. After the mapSection, update the code. In my first line, its says whenever the feature layer has been added initEditing fires, meaning I can edit right away.

 

Add the starts editing after creating the mapSection

// Starts initEditing after the feature layer(s) have been added
             map.on("layers-add-result", initEditing);

 

So that means we need to add a feature layer. Add a point feature layer. Set the layer in MODE_ONDEMAND as I only want the features that would be visible in my current extent to load and then I add all fields. With that we can load the layer.

 // add point feature layer for editing
             var pointFeatureLayer = new FeatureLayer("http://maps.decaturil.gov/arcgis/rest/services/testSecure/FeatureServer/0", {
                 mode: FeatureLayer.MODE_ONDEMAND,
                 outFields: ["*"]
             });
             map.addLayers([pointFeatureLayer]);

 

In this block, once the feature layers has been added as your recall, the initEditing event fires. Here we define the editor widget size and then fire the createEditor function. In the createEdtior function, we have added the editor widget's toolbar and also set the max undo to 20. You may notice the destroyEditor function. We're not calling that yet, but it's very important.

 

// Editor Widget Begin 
             // settings for the editor widget
             function initEditing(event) {
                 // sizes the edit window
                 map.infoWindow.resize(400, 300);
                 featureLayerInfos = arrayUtils.map(event.layers, function (layer) {
                     return {
                         "featureLayer": layer.layer
                     };
                 });


                 createEditor();
                 var options = {
                     snapKey: keys.copyKey
                 };
                 map.enableSnapping(options);
             }




             function createEditor() {
                 if (editorWidget) {
                     return;
                 }
                 var settings = {
                     map: map,
                     layerInfos: featureLayerInfos,
                     toolbarVisible: true,
                     enableUndoRedo: true,
                     maxUndoOperations: 20
                 };
                 var params = {
                     settings: settings
                 };
                 editorWidget = new Editor(params, domConstruct.create("div"));
                 domConstruct.place(editorWidget.domNode, "editorDiv");


                 editorWidget.startup();






             }


             function destroyEditor() {
                 if (editorWidget) {
                     editorWidget.destroy();
                     editorWidget = null;
                 }
             }
             // Editor widget ends

 

Here is where the conflict arises. The editor and the showLocation event both produce infoWindows and this is a conflict, so you may get the wrong infoWindow when you run one of the tools. What do you do? We refer to that function, destroyEditor and get rid of the editor when we run the showLocation and then createEditor. This removes the conflict from the application. This was driving me nuts. Thankfully Kelly Hutchins was able to figure this creative solution out for me.

 

 

function showLocation(evt) {
                 map.graphics.clear();
                 var point = evt.result.feature.geometry;
                 var symbol = new SimpleMarkerSymbol()
                                .setStyle("square")
                                .setColor([255, 0, 0, 0.5]);
                 var graphic = new Graphic(point, symbol);
                 map.graphics.add(graphic);


                 map.infoWindow.setTitle("Search Result");
                 map.infoWindow.setContent(evt.result.name);
                 map.infoWindow.show(evt.result.feature.geometry);
                 map.infoWindow.on('hide', function () {
                     map.graphics.remove(graphic);
                     destroyEditor();
                     createEditor();
                 });

 

 

The next two lines just allow the user to control over whether the editor is visible or not at any given time.

document.getElementById("editor").style.visibility = 'visible';

 

Hide tools add this line:

document.getElementById("editor").style.visibility = 'hidden';

 

And the last thing I like to add to my widgets is to make them draggable. The jQuery function allows you to drag the editor pane possibly out of the way of where you might want to edit. And even though this is not  jQuery mobile, you can still use it on mobile devices as I use jqueryPunch to make my jQuery code work on mobile devices.

 

// Hide editor
             on(dom.byId("closeEditor"), "click", function () {
                 document.getElementById("templatePickerPane").style.visibility = 'hidden';
             });




             // Show Editor
             on(dom.byId("showEditorWidget"), "click", function () {
                 document.getElementById("templatePickerPane").style.visibility = 'visible';


             });




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

 

There is just one last item to add to make this mobile template complete, which allowing your users to contact you while in the field, but if you want the fully functioning code up to this point, grab it from here anytime.

Today we will add our widget to the floating sidebar we created in my last post. It's just going to be a short copy and paste. So let's begin. The first widget we will add will be a twitter feed for the City of Decatur. You can copy and paste this right below the decaturTwitter div in the original app:

<a class="twitter-timeline" href="https://twitter.com/AccessDecatur"
                           data-widget-id="557285604892110849" 
                           width="360" 
                           height="350">Tweets by @AccessDecatur</a>
                        <script>
                            !function (d, s, id) {
                                var js, fjs = d.getElementsByTagName(s)[0], p = /^http:/.test(d.location) ? 'http' : 'https';
                                if (!d.getElementById(id)) {
                                    js = d.createElement(s); js.id = id;
                                    js.src = p + "://platform.twitter.com/widgets.js";
                                    fjs.parentNode.insertBefore(js, fjs);
                                }
                            } (document, "script", "twitter-wjs");
                        </script>

Just a side note; I noticed some of these feeds require you to refresh your browser from time to time to display. The twitter feed will display like so:

sidebarTwitter.png

The next widget we will add will be the City of Decatur's Facebook feed. The first thing we need is the Facebook SDK. So you want to copy and paste this code before the body of your web page or in your external JavaScript file:

(function (d, s, id) {
                var js, fjs = d.getElementsByTagName(s)[0];
                if (d.getElementById(id)) return;
                js = d.createElement(s); js.id = id;
                js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.0";
                fjs.parentNode.insertBefore(js, fjs);
            } (document, 'script', 'facebook-jssdk'));

 

Now that you have the Facebook SDK, you can add the Facebook page  widget right after the decaturFacebook div as follows:

<div id="decaturFacebook">
                        <div class="fb-like-box"
                             data-href="https://www.facebook.com/pages/City-of-Decatur/319956320318"
                             data-width="335" 
                             data-height="350" 
                             data-colorscheme="light" 
                             data-show-faces="true"
                             data-header="true" 
                             data-stream="true" 
                             data-show-border="false">
                             </div>
                        <div id="fb-root">
                        
                        </div>

 

The embedded Facebook widget will look like this:

sidebarFacebook.png

Now we add the LinkedIn widget. There is no control on sizing this widget, which can be frustrating if you want it smaller or larger. Copy and paste this code after the companyProfile id div.

<div id="companyProfile">
                        <script src="//platform.linkedin.com/in.js"
                                type="text/javascript">
                        </script>
                        <script type="IN/CompanyProfile"
                                data-id="5311"
                                data-format="inline"
                                data-width="250">
                        </script>
                    </div>

 

The embedded widget will like like this:

sidebarLinkedIn.png

And finally we can add the YouTube widget. Just copy and paste the following code after the div youTubeChannel:

<div id="static_video">
                        
                        </div>
                        <script type="text/javascript">
                            function showLatestVid(response) {
                                if (response.data && response.data.items) {
                                    var items = response.data.items;
                                    if (items.length > 0) {
                                        var item = items[0];
                                        var videoid = "http://www.youtube.com/embed/" + item.id;
                                        console.log("Latest ID: '" + videoid + "'");
                                        var video = "<iframe width='300' height='225' src='" + videoid + "' frameborder='0' allowfullscreen></iframe>";
                                        jQuery('#static_video').html(video);
                                    }
                                }
                            }
                        </script>
                        <script type="text/javascript" 
                                src="https://gdata.youtube.com/feeds/api/users/DecaturCrimes/uploads?max-results=1&orderby=published&v=2&alt=jsonc&callback=showLatestVid">
                        </script>

This displays the most recent video from a YouTube channel. This channel is crimes around Decatur taken from freelance video.

sidebarYouTube.png

If you would like to save some screen space, you can completely collapse the widget like this:

sidebarCollapsed.png

Or you could add a hide button. With this, you can add all of these widgets in a sidebar or anywhere in your application that you like. If you want to see the complete app, download the code here.

In this post we are going to create a draggable floating sidebar that will display social networking widgets. The sidebar will be collapsible and draggable. The four widgets that we will display on our site are Twitter, Facebook, LinkedIn, and YouTube. So we will start with a basic map application:

<!DOCTYPE html>
<html>
    <head>
        <title>Widgets</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.12/dijit/themes/soria/soria.css">
        <link rel="stylesheet" href="http://js.arcgis.com/3.12/esri/css/esri.css">


        <link rel="SHORTCUT ICON" href="images/widget.png" />

        <link rel="apple-touch-icon" href="images/iWidget.png" />

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


        <style>
            html, body, #mapSection
            {
                padding:0;
                margin:0;
                height:100%;
                width:100%;
            }
            
            
            
            .fb-like-box
            {
                background-color:Black;
            }
            
   
        </style>
        <script src="http://js.arcgis.com/3.12/"></script>


        <!-- jQuery Library -->
        <script src="js/jquery-1.9.1.js" type="text/javascript"></script>
        <script src="js/jquery-ui-1.10.3.custom.min.js" type="text/javascript"></script>
        <!-- Enables jquery mouse events to work as touch events on mobile devices: https://github.com/copernicus365/jquery-ui-touch-punch/blob/master/jquery.ui.touch-punch.js -->
        <script src="js/jquery.ui.touch-punch.js" type="text/javascript"></script>


        <script>
            var map;
            require(["esri/map", "esri/config",
                     "esri/geometry/Extent",
                     "esri/layers/ArcGISDynamicMapServiceLayer",
                     "esri/layers/ArcGISTiledMapServiceLayer",
                     "esri/layers/FeatureLayer",
                     "esri/tasks/GeometryService",
                     "dojo/dom",
                     "dojo/on",
                     "dojo/parser",
                     "dojo/domReady!"], function (Map, esriConfig, Extent, ArcGISDynamicMapServiceLayer, ArcGISTiledMapServiceLayer, FeatureLayer, GeometryService, 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
                         map = new Map("mapSection", {
                             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");


                     }
            );
        </script>
    </head>
    <body class="soria">

        <!-- Map Section Begin -->
        <section id="mapSection">
        
        </section>
        <!-- Map Section End -->

    </body>
</html>

If you want to follow along, you just need the jQuery files. You can get the files that I am using in this post if you scroll down to the bottom and click on get the code. Just copy the folders, js, images, and css to the same folder as your application. You can get rid of the code for proxy too. You won't need it here. Now we are ready to start creating our sidebar.

 

To begin, let's create a top section, middle for content and bottom. Here is the skeleton sidebar:

<!-- Sidebar Begin -->
        <aside id="sideBar">
            <!-- Sidebar Top Begin -->
            <div id="sideBarTop">
            
            </div>                
            <!-- Sidebar Top End -->


            <!-- Sidebar Top Fill Begin -->
            <div id="sideBarTopFill">
            
            </div>
            <!-- Sidebar Top Fill End -->


            <!-- Sidebar Title Begin -->
            <div id="sideBarTitle">
                <p>Social Networks</p>
                <!-- Sidebar Content Begin -->
                <div id="sideBarContent">
                
                </div>
                <!-- Sidebar Content End -->
            </div>
            <!-- Sidebar Title End -->


            <!-- Sidebar Bottom Fill Begin -->
            <div id="sideBarBottomFill">
            
            </div>
            <!-- Sidebar Bottom Fill End -->


            <!-- Sidebar Bottom Begin -->
            <div id="sideBarBottom">
            
            </div>
            <!-- Sidebar Bottom End -->
        </aside>
        <!-- Sidebar End -->

Now all of our content will be inside the sidebar content. Now, before we add content, let's add a little style. You just need to place this in your head section or your external CSS file:

 #sideBar
            {
                display:block; /* Only for IE8 or less */
                position:absolute;
                width:376px;
                height:auto;
                background-color:transparent;
                border-color:transparent;
                padding:0px;
                left:50px;
                top:50px;
                z-index:200
            }




            #sideBarContent
            {
                width:374px;
                padding:0px
            }
   


            #sideBarTopFill, #sideBarBottomFill
            {
                height:15px;
                background-color:#E1EBFB
            }


            #sideBarTop
            {
                background-color:#E1EBFB;
                height:5px;
                border-top-left-radius:5px;
                border-top-right-radius:5px
            }


            #sideBarBottom
            {
                background-color:#E1EBFB;
                height:5px;
                border-bottom-left-radius:5px;
                border-bottom-right-radius:5px
            }

 

Now it's time to add the content section. So right after the div sideBarContent, we write the following:

<h3>Twitter</h3>
                    <!-- Decatur Twitter Begins -->
                    <div id="decaturTwitter">
                        Tweets
                    </div>
                    <!-- Decatur Twitter Ends -->


                    <h3>Facebook</h3>
                    <!-- Decatur Facebook Begins -->
                    <div id="decaturFacebook">
                        Posts
                    </div>
                    <!-- Decatur Facebook Ends -->


                    <h3>LinkedIn</h3>
                    <!-- Company Profile Begin -->
                    <div id="companyProfile">
                        Jobs
                    </div>
                    <!-- Company Profile End -->


                    <h3>YouTube</h3>
                    <!-- YouTube Channel Begin -->
                    <div id="youTubeChannnel">
                        Video
                    </div>
                    <!-- YouTube Channel End -->

                 

  Now we have the containers for our four widgets. Before we add the widgets, let's make the sidebar draggable and collapsible. I also will set the default so that twitter is open when the app runs. Add this code before the body or inside your external JavaScript file.

<script type="text/javascript">
             /* Enables Sidebar to be draggable */
             jQuery(function () {
                 jQuery("#sideBar").draggable();
             });




             /* The accordion allows sections to expand/collapse which show or hide each section */
             jQuery(function () {
                 jQuery("#sideBarTitle").accordion({
                     collapsible: true,
                     heightStyle: "content"
                 });
             });




             /* Setting an active panel - http://api.jqueryui.com/accordion/#option-active */
             jQuery(function () {
                 jQuery("#sideBarContent").accordion({
                     heightStyle: "content"
                 });
                 jQuery("#sideBarContent").accordion("option", "active", 0);
             });


        </script> 

 

With that, here is what we have built so far:

sidebar.png

In my next post, we will populate each section with a widget directly to specific pages for each site. If you would like to continue to follow along, you can get the code here.

Sometimes you have to back away from GIS and just focus on the web. That's what I am doing in this post. I am going to walk you through how to add an icon to your browser tab for your website and then how to add an icon to either your iPad or your Android tablet. First you need an icon. A lot of times you have to modify an icon and remove white background. Let me show you how to do that with GIMP and then resize your image for display on a tab as it does here on geonet. Consider that you may not want to remove which background like I did in this video but may want to change the color of an icon as the area where I removed the white will be replaced with black. If you are okay with that, then just follow the video.

 

 

 

Just like I did in the video, follow the same steps, only make your next icon 114px X 114px for your iPad or Android device. The next thing that you want to do is to add these new images to your website. I like to place mine in an images folder.

 

The first line of code will display your icon on the browser tab. Place the following code inside of the head section of your web page with the name of your image in place of widget.png. Make sure it's the image that you created that is 32px X 32px

 

<link rel="SHORTCUT ICON" href="images/widget.png" />

 

With that line of code, you now will have your icon displaying on browser tabs. Now we need a line of code so that a user can add your custom icon to their device which will look like an app icon. Just replace iWidget.png with the name of your image. Again it's the one that has a size of 114px X 114px. And now place this line of code in the head section of your web page:

 

<link rel="apple-touch-icon" href="images/iWidget.png" />

 

With this, once a user navigates to your site with their iPad or Android device, all they have to do is to click Add to Home Screen and your custom icon will display along with all the rest of the icons for apps.

That's right, we're talking about a geocoder. This is where our three templates split up and take on a unique purpose of their own. Let's get right to it. Adding the HTML is super easy. Here is all you have to add.

<div id="search"></div>

 

Now let's add a little style and place it a little to the right of our buttons, but at the top of the screen by adding CSS.

#search 
            {
                display:block;
                position:absolute;
                z-index:3;
                top:20px;
                left:75px;
            }

 

Now we add the following items for our search in our require statement. Some items are already added from earlier posts. Don't forget your variables in the following function.

"esri/dijit/Geocoder",                     // search
"esri/symbols/SimpleMarkerSymbol", // search
"dojo/_base/Color",                    // search
"dojo/dom-construct",                  // search
"dojo/query",                      // search

 

And finally we can add the code that finds the address for us.

          // begin geocoder
                         var geocoder = new Geocoder({
                            arcgisGeocoder:false,
                            geocoders: [{
                            url:"http://maps.decaturil.gov/arcgis/rest/services/Public/WebAddressLocator/GeocodeServer",
                            name: "Web Address Locator",
                            placeholder: "Find address",
                            outFields:"*"
                            }],
                            map:map,
                            autoComplete:true,
                            zoomScale: 600
                            }, dom.byId("search"));
                            geocoder.startup();

                        geocoder.on("select",showLocation);

                        function showLocation(evt) {
                           map.graphics.clear();
                           var point = evt.result.feature.geometry;
                           var symbol = new SimpleMarkerSymbol()
                                .setStyle("square")
                                .setColor([255,0,0,0.5]);
                           var graphic = new Graphic(point, symbol);
                           map.graphics.add(graphic);


                           map.infoWindow.setTitle("Search Result");
                           map.infoWindow.setContent(evt.result.name);
                           map.infoWindow.show(evt.result.feature.geometry);
                           map.infoWindow.on('hide',function(){
                            map.graphics.remove(graphic);
                            });
                        }
                        // end geocoder

Okay, I know I say I have been combining samples, but this one has one line that's slightly different. When I close the pop-up once an address is found, instead of writing map.graphics.clear which clears all graphics on the map, I write map.graphics.remove(graphic) so the app only removes the defined graphic and not all graphics. This could be helpful if you are measuring or drawing on a map.

 

Now this geocoder is for finding an address that is in the City of Decatur, we will need a slight modification for our Esri based template.

 

To do this, we just need to change our first block of JavaScript after begin geocoder to this:

// begin geocoder
             var geocoder = new Geocoder({
                 map: map,
                 autoComplete: true,
                 zoomScale: 600
             }, dom.byId("search"));
             geocoder.startup();

 

And now we have two geocoding services for our templates. The first is for the City I work for an the second allows me to search addresses that are outside city limits. This second one also still includes the pop-up for the address found.

 

This completes our Esri based template, which will be used for projects that go outside city limits, now we can finish up the mobile and web app templates in my upcoming posts.

 

For the complete code of each application, you can get the code for the Esri based template, get the code for the web template or get the code for the mobile template.

csergent08

Star Wars or Star Trek?

Posted by csergent08 Champion Jan 14, 2015

I have always had the opinion that if you are a programmer and really love programming, that you are probably a fan of Star Wars or Star Trek. If you don't like Star Wars, this post may seem a bit confusing. For myself, I am a fan of Star Wars, but I do watch Star Trek movies as well. I'm just not into them as much. Recently I watched the original Star Wars from 1977 as I plan on watching one Star Wars per month this year in the following order:

Episode IV - January

Episode V - February

Episode II - March

Episode III - April

Episode VI - May

Episode I - June

Episode II - July

Episode III - August

Episode IV - September

Episode V - October

Episode VI - November

Episode VII - December

 

The first time is to use episodes II and III as flashbacks before concluding in episode VI. The second set is to watch the entire series in chronological order. I do wish there were an interquel. This is what I call a trilogy between the new trilogies and the original trilogies. I would like to see an episode just called Vader. It would show what Anakin was dealing with as he struggled to become the Dark Lord of the Sith that made him famous. In the next one, would be called Rebels Rising, where the Rebellion had just begun and answer that question I had when Darth Vader said, "there will be nothing to stop us this time". Of course that answer could come in the last episode of the trilogy which I would call Death Star which would lead up to the rebels starting the process of the stealing the plans for the Death Star. Just fun things to think about while I wait for Episode VII to come out on December 18, 2015.

 

So, Star Wars or Star Trek?

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.