A reader asked:
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
function init() {
map = ColdFusion.Map.getMapObject('mainMap')
}
</script>
</head>
<body>
<h2>Bird Spotting Form</h2>
<cfmap name="mainMap" centeraddress="Lafayette, LA" showcentermarker="false" zoomlevel="13">
<p>
Click on the map to record where you saw a bird.
</p>
<form id="mainForm">
<input type="submit" value="Send Report" id="submitButton" style="display:none">
</form>
</body>
</html>
<cfset ajaxOnLoad("init")>
I've got a simple map centered on my home town. I put a form at the bottom which is empty for now. The last line, ajaxOnLoad, simple tells ColdFusion what JavaScript I need to run when the page is done loaded. Right now my init() function simply grabs the Google Map object.
I then did a quick Google (is it weird to use Google to search for Google docs?) on map events and came across a pretty nice set of documentation. As powerful as Google's APIs are, I'm not always quite as pleased with their docs or ease of use. In this case, it looks like all we need to do is add a simple event listener. This event listener will be called with either an overlay object or a longitude/latitude pair:
GEvent.addListener(map, "click", function(overlay,latlng) {
})
For my demo I decided that each click would simply take the longitude and latitude and add them as text fields to a form. I whipped up the following JavaScript:
<script>
var counter;
function init() {
counter = 0
map = ColdFusion.Map.getMapObject('mainMap')
GEvent.addListener(map, "click", function(overlay,latlng) {
if(latlng) {
counter++;
var s = '<b>Report '+counter+'</b>: '
s += '<input type="text" name="siteport_' + counter + '" value="'+latlng+'" size="50"><br/>'
$("#submitButton").before(s)
$("#submitButton").show()
}
})
}
</script>
For the most part this should be pretty trivial. I keep a counter so I can have unique numbers for each sighting. I used a text field with a dynamic name and value... and that's it. Here is a quick screen shot:

You can play with a demo here. Right now it isn't very exciting. We should probably add markers, and make the form a bit more complex. For example, most users probably don't need to see the actual latitude/longitude, but they probably want to enter data ("The bird was awesome, man. It had wings. And it flew. Cool."). In my next entry I'll add these features to the form.
Archived Comments
Waiting for more goodness with part two. Wondering if there is a way to measure the distance between each lat/long pair and then add a pointer to the map with a line connecting them?
I kinda forgot about this one. I'll definitely do a part 2 though. You can also do lines. I don't think lines make sense in this example, but I wanted to show that as well (err, what I mean is, it doesn't make sense for the 'Bird Watching' demo).
Very cool - I've only played around with Google maps and I am also impressed with how easy they make a lot of stuff.
I have a question, assume that we have placement markers throughout the cfmap. When we zoom out or in it will load more markers or less based on the location.
For Example.)
Marker one location is in NY, marker two is in Louisiana, and marker three is in California, While NY is only in few it will only show NY, but if CALI comes in view it will show the marker in Cali, as well if it was two show Louisiana in view.
Are you asking if that is possible? The answer is absolutely yes. Google has support for something called a Marker Manager. It is built to better handle large sets of markers and one of the specific features is support for 'show these markers at zoom x'
I'm rereading your comment and I think that may not _exactly_ match what you mean. Obviously if you set a marker to show at a 'low' zoom, then you would only see the CA one if you were zoomed in low enough. You can also notice when the view port changes. You could say, "If I'm in a range of these long/lat, I'm over CA so show marker X." Not sure how efficient it would be.
Hi Ray,
How would you adapt the js here to simply populate 1 existing input field and update it each time? I know its probably trivial but I cant figure it out...
thanks man.
Mike
Instead of adding a new field, you would append to the old field like so (assume old field has id of 'simple')
$("#simple").append(latln)
Append should append to the value.... but double check that. If it doesn't, just do
$("#simple").val($("#simple").val() + "," +latlng)
Actually that second one is better as it adds the comma to keep it separate.
Actually (grin), that's bad since the lat and lng are separated with a comma. You REALLY don't want to use one field. But if you insist, use another delimiter like a @ sign. Or consider a textarea and use line breaks.
Hi ray, What if we want to calculate the difference between the two locations and hightlight the one to use which is the shortest route.
is this possible
You need to look at Google's Directions API. It supports finding routes, finding quickest, etc. I've blogged on this before, and of course, Google has a bunch of docs on it. It's a rather nice service actually.
Thanks Ray,
This is damn useful, very simple. I even manage to retrieve address with little GClientGeocoder()tweak.
<script>
var counter;
function init() {
counter = 0;
var geocoder = null;
geocoder = new GClientGeocoder();
map = ColdFusion.Map.getMapObject('mainMap')
GEvent.addListener(map, "click", function(overlay,latlng) {
if(latlng) {
geocoder.getLocations(latlng, function(addresses) {
if(addresses.Status.code != 200) {
alert("reverse geocoder failed to find an address for " + latlng.toUrlValue());
}
else {
address = addresses.Placemark[0];
var myHtml = address.address;
document.getElementById("myaddress").innerHTML = myHtml;
}
});
}
})
}</script>
<span id="myaddress"></span>
Slick - thanks for sharing that.