Symfony and Google Maps
- February 29th, 2008
- Posted in Coding . Work
- Write comment
As many of you know in my “free” time I manage, direct, and write code for a small company called txtMovieClub.com. It’s a pretty neat idea where we notify our subscribers of up coming movie screenings via SMS messaging.
One of the aspects to the project involves using google maps. Now since the project is written in php and uses symfony (which is flippin’ awesome!) I checked out phoogle. I’ll say this… it’s a good start and I like where Justin was going with it. It’s sexy, it’s abstract, neat. Unfortunately it just didn’t meet the needs for the page I was working on.
I decided to take a different approach. I wanted the map to be AJAX driven. If I wanted to modify the location I didn’t want to have to reload the map, I just wanted the map to clear its markers and recenter.
First things first, add the important keying information for google’s API. In the template that I was working in, let’s say editSuccess.php I added the following:
<?php slot('gmapheader'); ?>
<script type="text/javascript" src="http://www.google.com/jsapi?key=ABCDEFGHIJK_ENTER_YOUR_KEY"></script>
<script type="text/javascript">
google.load("maps", "2.x");
var map;
// Call this function when the page has been loaded
function initialize()
{
map = new google.maps.Map2(document.getElementById("map"));
var mapControl = new GMapTypeControl();
map.addControl(mapControl);
map.addControl(new GSmallMapControl());
map.addControl(new GScaleControl());
map.setCenter( new google.maps.LatLng(33.581411, -111.893215), 14);
map.disableDragging();
}
google.setOnLoadCallback(initialize);
</script>
<?phpend_slot();?>
In the layout.php file of the app I added the following between <head> and </head>:
<?php if (has_slot('gmapheader')): ?>
<?php include_slot('gmapheader') ?>
<?php endif; ?>
When editSuccess.php gets loaded it will push all that javascript into the ‘gmapheader’ slot. Later, when layout.php finally gets compiled, it pulls in any content within ‘gmapheader’.
“So now what? Big whoop you’ve got a map.” Yes, but now I have a global ‘map’. Check out that javascript once more… map is declared as a global. This is really handy for me as I can now update that map using a remote_function call ala AJAX.
Here’s an example where I use a drop-down list of theaters that will update the markers on a list:
<?php echo object_select_tag($events,'getTheaterId',
array ('related_class' => 'Theaters',
'include_blank' => true,
'onchange' => remote_function( array('url' => 'events/map',
'with' => "'theater_id=' + value"))
)) ?>
The select tag will have a drop down list of theaters. When a new theater is selected the remote_function call makes a request to the events/map action.
A very basic events/map action would look like this:
public function executeMap()
{
$this->lat = 42.875036;
$this->lon = -78.877772;
}
In the respective view.yml file make sure that you’ve got something like:
mapSuccess:
has_layout: off
The code for updating the location on our map is in mapSuccess.php:
<?php $sf_context->getResponse()->setContentType('text/javascript')?>
map.clearOverlays();
map.addOverlay( new google.maps.Marker( new google.maps.LatLng(<?php echo $lat .','.
$lon; ?>)));
map.setCenter(new google.maps.LatLng(<?php echo $lat .','. $lon; ?>), 13);
Here the template will return javascript as its content type. The script itself wipes the map of overlays/markers, adds a new marker for the lat and lon determined in the action, finally setting the map’s center as the marker.
So that’s it in a nut shell. Eventually I’ll make this into a class and maybe post it here.
great!
javascript helper have remote_function, but JavascriptBase helper (the one included in symfony 1.2 that “replaces javascript”), it doensnt, … so i don’t know but if you canl help me to achieve the same effect without using that function?? (i think that function uses prototype i’m not sure
)
Great post! I found it very useful to add my google maps in my project. The post at http://www.symfoners.com/2010/07/07/versatile-googlemap-symfony-component/ has good tips too. Thanks!