Earlier today a reader asked about driving directions and CFMAP. At lunch I worked on a quick proof of concept. Please note that this could be done better, cleaner, etc, but it works, and is kinda cool, so hopefully it is enough to get people started.
First, I began by looking at the reference guide for directions under Google Maps. It begins with the creation of a directions object. Once you have that, you can then load a query and have it auto-populate the results. And.... well that's it! You can tweak things up quite a bit as the docs show, but here is a quick example you can play with:
<html> <head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
$(document).ready(function() { $("#doDirections").click(function() {
var youraddy = $.trim($("#youraddress").val())
if(youraddy == '') return
console.log('Directions from '+youraddy)
var mapOb = ColdFusion.Map.getMapObject("themap")
var dir = new GDirections(mapOb, document.getElementById('result'))
<cfoutput>
dir.load("from: "+youraddy +" to: #theAddress#")
</cfoutput>
console.log('done')
})
})
</script>
<style>
#result {
width:500px;
height: 500px;
overflow: auto; }
</style>
</head> <body> <cfmap name="themap" centeraddress="#theAddress#" width="400" height="400" zoomlevel="9">
<p>
<form>
Your Address <input type="text" name="youraddress" id="youraddress" value="San Francisco, CA"><br/>
<input type="button" id="doDirections" value="Get Directions">
</form>
<p> <div id="result"></div> </body>
</html>
<cfset theAddress = "Lafayette, LA">
I'm going to jump around a bit here so please forgive me. (I find that the way I write CFML does not lead itself well to actually teaching or writing about it well!) The very first line hard coded an address. This would be the store or other location you want to display to your users. At the bottom of the script you can see where I use this within the CFMAP tag. Below it I've created a simple form. I hard coded in San Francisco to save myself some typing.
Now if we hop back to the top you can see my jQuery code. I've bound to the button click action. I get the address and ensure something is there. Once I have it then I get the map object (that line of code should be moved up and out of this event handler, I shouldn't be regrabbing it for every click). I then make a new instance of the GDirections object. I give it my map and a pointer to my div that will be used for the results. (jQuery provides a way to do that of course but I forgot and was in a rush!) Next I do the load operation. This takes a string of the form:
from: somelocation to: somelocation
For my demo, the to is hard coded and the from is based on your input. And that's it. The result will get dumped into my div. If I wanted to I could extract out individual bits of it but for now it works fine as is. You can demo this here: http://www.coldfusionjedi.com/demos/jan182010/test3.cfm
One quick note - I warned folks this is a proof of concept so it shouldn't be used without more testing, but I want to point out one serious mistake that should be corrected. The jQuery document.ready event I use here can and probably will fire before the map is loaded. I should have used ColdFusion's ajaxLoad function to register the setup call. That's a 2 second fix but I wanted to make sure folks remembered that.
Archived Comments
Ray,
Cool find to get the directions.
I played around a bit with the ajaxOnLoad and ExtJS. Your right that the ajaxOnLoad will wait till the document is really ready since that is dependent on ExtJS (as is every CF ajax feature) I thought I would try and do it with ExtJS instead of jQuery.
Its pretty similar all in:
Ext.onReady(function(){
Ext.get('doDirections').on( 'click', function() {
youraddy=Ext.get('youraddress').getValue();
if(youraddy == '') return
console.log('Directions from '+youraddy)
var mapOb = ColdFusion.Map.getMapObject("themap")
var dir = new GDirections(mapOb, document.getElementById('result'))
<cfoutput>
dir.load("from: "+youraddy +" to: #theAddress#")
</cfoutput>
console.log('done')
});
});
Wow, that's so .... not jQuery. ;)
Heh ;)
Hi Ray, this demo doesn't work for me in Opera 10.10 Pressing the button doesn't deliver any directions at all... Maybe it's a US-only demo? I typed in Utrecht, the Netherlands and nothing happened ;-)
Does it work in Firefor or Chrome? Does it work if you use the default address?
Doesn't work in Opera 10.10, FF 3.5.7 or IE7 on XP... In Safari and Chrome I get results from the default address.
In IE7 I get the following error: Line 31, Char 3, 'console' is undefined.
FF gives me a ton of CSS-errors in ext-all.css that ships with the CF AJAX-scripts though..., and the error all the way at the bottom that console is not defined. Hence no results there either
Oh shoot - jsut remove the console.log lines. I always forget that in. It requires Firebug in FF, or Safari/Chrome.
OK, so I need to remove the console lines to make it work in any browser..., and CF9 of course ;-)
Darn, we just moved to CF8 last year, don't think they'll move to CF9 any time soon...
Maybe Railo 3.2 or higher (the version coming after Barry) will have this in it?
I can't speak to Railo, but you can obviously use Google Maps in CF8. You just need to do it manually. If folks want a CF based demo of that, just ask.
Hey Ray, did you ever make a CF8 Demo of this?
No, my thinking was to do a blog post on how to do maps in CF without using CFMap. Basically a simple tutorial that is CF based.
Thanks Ray,
if you have time, I would be interested in a tutorial for this.
I've got it on my list. If you check the Google docs - it really isn't that hard - but obvious it isn't ColdFusion specific.
Has Google changed something with the API? The button in the demo doesn't do anything for me with Firefox.
Worked for me. Do you have Firebug installed? If not, it won't work. I make use of console.log messages in my demos. Or you can try Chrome/Safari wich has console built in.
Ah, yep. It worked when I turned on Firebug. However, my users won't have it...is there a way to do it without Firebug?
The console.log messages are just for the demo. They are debug messages. You can remove them.
Thanks so much for this resource - it is going to add value to our new site and I did not have to spent the time trying to learn how to do it.
I notice that you have used ".click(function()" to generate the directions. I am new to all of this but want to be able to display directions when the page loads and / or when a link in a markerWindowContent is selected.
Any guidance in this would be greatly appreciated!
You can run code on page load, in jQuery anyway, within:
$(document).ready()
You can see I have that already. So basically, the .click handler would be removed - the meat of it would be kept though so it just plain runs.
Thanks for your time Raymond - I gave it a bash (well to the best of my jQuery ability!) below is what I tried, (which does not work) pleascould you show me what you mean?
<script>
$(document).ready(function() {
var youraddy = $.trim($("#searchaddress").val())
if(youraddy == '') return
console.log('Directions from '+youraddy)
var mapOb = ColdFusion.Map.getMapObject("themap")
var dir = new GDirections(mapOb, document.getElementById('result'))
<cfoutput>
dir.load("from: "+youraddy +" to: #theAddress#")
</cfoutput>
console.log('done')
})
</script>
Ah sorry - brain fart on my part. The code requires a search address, so having it run _immediately_ doesn't make sense. It has to run when you have a value for the address. Unless you want to use Geolocation and get the user's address automatically.
Currently the users address on my site is being stored in a session so I have that data when the page loads.. I just cant get your code to show the directions without the doDirections being clicked - hope you can help me out! (the geolocation would be funky too! just not sure if it is accurate enough where I am in Africa)
My code assumes the address value comes from a form field. If you have it in the session, then you would want to output it dynamically when you generate the page. You can use the toScript function to generate a valid JS variable from CF.
That make sense?
Thanks for you time... yeah it does make sense - thank you. I am working away like crazy trying to finish other elements of the site right now - but will come back and look at this in more detail when I have the rest of it working - thanks again!
Hi ray, i tried ur same example within cfwindow, it is not working, i tried the same in separate window, it works.
i also added one alert after 1 click the btn to show me the directions but it does not fire that alert too, any idea
Well, how is it not working? You didn't say.
It is not firing the onclick event i just added alert after the $("#doDirections").click
but the alert did not fired up, i even included the jquery code, but no sure, i can shar the online link too, if needed, let me know
Thanks
I guess share the online link so we can view source. Please remember how your event handlers work in jQuery. If you do
$("something").click
Then jQuery looks in the DOM _right_ then. If it can't find it, it does nothing.
If your cfwindow is pointing it's content to another file, then it's possible that is your issue. You can use jQuery's on method to bind in such a way that it would work post page DOM loaded (if that makes sense).
We are now getting into a level of tech support where I may have to push back on you a bit and ask about a consulting agreement. ;)
Have a look @
http://tinyurl.com/774vzp6
Omg I hate you for making me look at food. Ok, going back...
You need to move your script logic inside your main file, clone.cfm, or within a JS file included. Your code is not working because when cfwindow loads the remote content, it is ignoring your script block.
Hi Ray, Even after the moving the code to the main page, this still does not work. you can view the same link, updated now.
also, Explian me your this point, DOm already gets loaded,
If your cfwindow is pointing it's content to another file, then it's possible that is your issue. You can use jQuery's on method to bind in such a way that it would work post page DOM loaded (if that makes sense).
cfwindow fetches content of another file drive.cfm
Yeah, you want to switch to using .on instead of .click.
$("#doDirections").click(function() {
should be
$("#doDirections").on("click",function() {
i don't know why is not working for me.
Please give a short explaination for it.
I am in very trouble
I can't really help you unless you provide more information. Can you describe where it is failing? What browser - or all browsers? Is it online where I can see?