Skip to content
apneadiving edited this page May 1, 2012 · 20 revisions

Keep in mind the gem's conventions:

  • prior to v1.0.0, only one map could be created. It's properties were accessible through the Gmaps4Rails namespace

From v1.0.0:

  • One map object is instantiated per map displayed. All these objects are independant.

  • all javascript map objects are stored in the Gmaps object. To access these, simply type: Gmaps.the_map_id. By default, it's Gmaps.map

From v1.5.0:

Gmaps.map.map is deprecated in favor of Gmaps.map.serviceObject

JS Functions

Gmaps4rails allows you to update your map on the fly.

Check here the valid json format you should provide: https://github.com/apneadiving/Google-Maps-for-Rails/wiki/Control-what-I-display

Callback

If you want to create a callback called once the map and items are created, include the following code in your view within a content_for :scripts:

<script type="text/javascript" charset="utf-8">
Gmaps.map.callback = function() {
   //whatever you want here
}
</script>

Markers

If you want to replace the current markers with your new ones:

 Gmaps.map.replaceMarkers(your_markers_json_array); //this is a JS function

If you want to add markers to those already displayed (it doesn't check duplicates):

 Gmaps.map.addMarkers(your_markers_json_array);     //this is a JS function

Polylines

If you want to replace the current polylines with your new ones:

 Gmaps.map.replacePolylines(your_polylines_json_array); //this is a JS function

Others

Notice that you can use all javascript functions written in the js files directly. I hope the files have enough comments to make everything clear.

#Marker Dragging

Marker dragging is a recurrent question.

I can't see now how to code a clever and generic solution.

For now I suggest the following: adding this behavior thanks to the callback function.

I'd do as follows:

<%= gmaps("markers" => {"data" => @json, "options" => { "draggable" => true  } } ) %> 
<% content_for :scripts do %>
<script type="text/javascript" charset="utf-8">

Gmaps.map.HandleDragend = function(pos) {
  var geocoder = new google.maps.Geocoder();
  geocoder.geocode({
    latLng: pos
  }, function(responses) {
    if (responses && responses.length > 0) {
      alert(responses[0].formatted_address);
    } else {
    alert('Cannot determine address at this location.');
    }
  });
};

Gmaps.map.callback = function() {
  for (var i = 0; i <  this.markers.length; ++i) {
     google.maps.event.addListener(Gmaps.map.markers[i].serviceObject, 'dragend', function() { Gmaps.map.HandleDragend(this.getPosition()) });
  }
};        
</script>
<% end %>

Any remark is welcome.

Drop a marker and update fields attribute in a form

This is something to use in your new or edit views. Provided you're creating/editing a new "Location" instance, you will be able to drop a marker by clicking on the map and update coordinates and zoom level in your form. You can drag and drop the marker and your fields will get updated again, and if you click on the map while there's a marker it will get replaced.

The only things you should have to change are the fields id (e.g. 'location_attributes_latitude') for latitude, longitude and zoom, based on your model name (here: Location) and your attributes (here: latitude, longitude, gmaps_zoom). If you're not familiar with this, just inspect the html code of your page and you'll find what fields id are.

Include it below the <%= gmaps4rails(@json) %>.

    <% content_for :scripts do %>
	<script type="text/javascript" charset="utf-8">
		var markersArray = [];
		// On click, clear markers, place a new one, update coordinates in the form
		Gmaps.map.callback = function() {
			google.maps.event.addListener(Gmaps.map.serviceObject, 'click', function(event) {
			  clearOverlays();
			  placeMarker(event.latLng);
			  updateFormLocation(event.latLng);
			});
		};
		// Update form attributes with given coordinates
		function updateFormLocation(latLng) {
			$('#location_attributes_latitude').val(latLng.lat());
			$('#location_attributes_longitude').val(latLng.lng());
			$('#location_attributes_gmaps_zoom').val(Gmaps.map.serviceObject.getZoom());
		}
		// Add a marker with an open infowindow
		function placeMarker(latLng) {
			var marker = new google.maps.Marker({
			    position: latLng, 
			    map: Gmaps.map.serviceObject,
			    draggable: true
			});
			markersArray.push(marker);
			// Set and open infowindow
			var infowindow = new google.maps.InfoWindow({
			    content: '<div class="popup"><h2>Awesome!</h2><p>Drag me and adjust the zoom level.</p>'
			});
		  	infowindow.open(Gmaps.map.serviceObject,marker);
			// Listen to drag & drop
			google.maps.event.addListener(marker, 'dragend', function() {
				updateFormLocation(this.getPosition());
			});
		}
		// Removes the overlays from the map
		function clearOverlays() {
		  if (markersArray) {
		    for (var i = 0; i < markersArray.length; i++ ) {
		      markersArray[i].setMap(null);
		    }
		  }
		  markersArray.length = 0;
		}
	</script>
<% end %>

Some details about detect_location

If location of the user is detected, it will be stored in Gmaps.map.userLocation

If attempt to localize the user fails, you can set the behavior of your app by defining the following function Gmaps.map.geolocationFailure(bool).

Here is an example:

Gmaps.map.geolocationFailure= function(browser_support) {
  if (browser_support === true)
    { //User refused geolocation
    }
  else
    { //Geolocation not supported by the user's browser
    }
 }

Gists:

https://gist.github.com/1643990