Dale asks:
I want the user to be able to print a cfmap that is within a cfwindow. Is there a way to add a print button to a cfwindow or cfmap?
I had to dig a bit to find the answer, and of course as soon as I did, my buddy Todd Sharp pointed out multiple ways to make it better, but the answer is, yes, you can. Here is how I solved it.
I began by creating a simple application that allowed a user to enter an address and display a window containing the map. The front end code was pretty simple:
2
3 <html>
4 <head>
5 <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
6 <script>
7 $(document).ready(function() {
8
9 $("#getAddressBtn").click(function() {
10 try {
11 ColdFusion.Window.destroy('mapWindow')
12 } catch(e) {}
13 var address = $("#address").val()
14 ColdFusion.Window.create('mapWindow', 'Map', 'test2.cfm?address='+escape(address), {height:500,width:500,modal:false,closable:true, draggable:true,resizable:true,center:true,initshow:true })
15 })
16
17
18
19 })
20 </script>
21 </head>
22
23 <body>
24
25 <h2>Print Map Test</h2>
26
27 <form>
28 <input type="text" name="address" id="address" size="100" value="Lafayette, LA 70508"> <input type="button" id="getAddressBtn" value="Display Map"><br/>
29 </form>
As you can see, I've got a text field and a button. I use jQuery to listen for a button click and then simply create a new window pointing to a CFM file that will create my map. Note - I was surprised to see there is still no easy way to tell if a CFWINDOW object exists. Hence the try/catch around my destroy. Sure you can use JavaScript variables to remember if the window exists, but I was hoping for a simple exists() type check.
The code that serves up the map is rather simple:
2
3 <cfif len(trim(url.address))>
4
5 <cfoutput>Address: #url.address#</cfoutput>
6 <cfmap centeraddress="#url.address#" zoomlevel="13">
7
8 </cfif>
Who doesn't love how easy ColdFusion 9 makes it easy to work with maps?? Ok, so I first made sure this code worked fine. Once I did, I began my first attempt at printing. I did some Google searches about printing part of the page, and in almost all cases it involved some simple DOM manipulation behind the scenes. Luckily I was able to find a jQuery plugin called print. It was created by some guy called Ben Nadel, which frankly sounds like a made up name to me. But his code worked - and was darn easy. Just take a selector and run print() on it:
Booyah! Ok, so here is the question though. How do I find out the ID of the window that holds the map? You would think it would be the same as the window name, but it isn't. I did some digging into the Ext docs and found that if you get access to the window object itself (which ColdFusion gives you a hook to), you can run getEl(), which returns the Ext.Element for the window. That object contains an ID field for the DOM item.
I added a print button to my page and then wired up the code. First, here is the button I added:
And here is the JavaScript code:
2 //silently ignore if no win....
3 try {
4 var mywin = ColdFusion.Window.getWindowObject('mapWindow')
5 var realid = mywin.getEl().id;
6 $("#" + realid).print()
7 } catch(e) {}
8 })
As you can see, I make use of the Ext API to grab the real ID, which is then used with jQuery and passed to Ben's plugin. Worked like a charm!
But of course, Todd had to ruin it by making it simpler. First off, instead of using code to find the ID of my window, why not simply wrap the AJAX-loaded content with a div? Next - instead of a try/catch around my print operation, just run the darn code. Since the selector will return nothing if the window isn't there, it's harmless. Finally, Todd also suggested just putting the print button in the window. Duh. So here is the new version of the front end:
2
3 <html>
4 <head>
5 <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
6 <script type="text/javascript" src="/jquery/jquery.print.js"></script>
7 <script>
8 $(document).ready(function() {
9
10 $("#getAddressBtn").click(function() {
11 try {
12 ColdFusion.Window.destroy('mapWindow')
13 } catch(e) {}
14 var address = $("#address").val()
15 ColdFusion.Window.create('mapWindow', 'Map', 'test2.cfm?address='+escape(address), {height:500,width:500,modal:false,closable:true, draggable:true,resizable:true,center:true,initshow:true })
16 })
17
18 $("#printBtn").live("click",function() {
19 $("#print").print()
20 })
21
22 })
23 </script>
24 </head>
25
26 <body>
27
28 <h2>Print Map Test</h2>
29
30 <form>
31 <input type="text" name="address" id="address" size="100" value="Lafayette, LA 70508"> <input type="button" id="getAddressBtn" value="Display Map"><br/>
32 </form>
One small thing I want to point out. Because I'm going to move my button to AJAX-loaded content, I've switched from a simple click event listener to a live listener that monitors the click for the button. Finally, here is my map code. Note the new div, and also note that the print button is outside.
2
3 <cfif len(trim(url.address))>
4
5 <div id="print">
6 <cfoutput>Address: #url.address#</cfoutput>
7 <cfmap centeraddress="#url.address#" zoomlevel="13">
8 </div>
9
10 <input type="button" id="printBtn" value="Print Map">
11
12 </cfif>
Comment 1 written by Dale Severin on 8 December 2009, at 1:50 PM
Comment 2 written by Marko Simic on 8 December 2009, at 4:44 PM
Btw, to check if window is created you may look for <winname>_body element.
if (document.getElementById('mapWindow_body')){
//win exists, tho may be hidden
}
else{
//create it
}
Comment 3 written by rana on 8 December 2009, at 11:56 PM
Comment 4 written by Don Blaire on 9 December 2009, at 8:42 AM
$("#print").print is not a function
I substituted jqprint.0.3.js in the place of print.js.in the following and it worked fine:
<SCRIPT type=text/javascript src="jquery.jqprint.0.3.js"></SCRIPT>
<script>
$(document).ready(function() {
$("#getAddressBtn").click(function() {
try {
ColdFusion.Window.destroy('mapWindow')
} catch(e) {}
var address = $("#address").val()
ColdFusion.Window.create('mapWindow', 'Map', 'mapsExample2.cfm?address='+escape(address), {height:500,width:500,modal:false,closable:true, draggable:true,resizable:true,center:true,initshow:true })
})
$("#printBtn").live("click",function() {
$("#print").jqprint();
})
})
</script>
Comment 5 written by Raymond Camden on 9 December 2009, at 10:39 AM