Search code examples
ruby-on-railsgoogle-mapsgmaps4rails

Drag and update location - how to do this?


I'm trying to follow the information on your wiki, stackExchange, etc to make this work. The idea is to create a new location for the user. The app displays a map, put a marker on the 0,0 location and then the user drag this marker to any place and the form is updated with the new lat and log. Seems trivial and there's doc in the wiki, but I could not make it work.

I'm using gem version 2.1.2 and Rails 4.1. I had success showing maps, markers, etc, but I cannot make the callback and others functions to work. I'm using this doc to try: https://github.com/apneadiving/Google-Maps-for-Rails/wiki/Javascript-goodies#drop-a-marker-and-update-fields-attribute-in-a-form

Follow my view code:

handler = Gmaps.build('Google');
handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
  markers = handler.addMarkers(
    [
      {
        "lat": 0,
        "lng": 0,
        draggable: true
      }
    ]
  );

  handler.bounds.extendWith(markers);
  handler.fitMapToBounds();

  // Callback function
  var markersArray = [];
  var marker = handler.getMap().markers[0];
  if (marker) {
    // Move existing marker when editing a previously stored location
    google.maps.event.addListener(marker.serviceObject, 'dragend', function() {
      updateFormLocation(this.getPosition());
    });
  }

  // On click, clear markers, place a new one, update coordinates in the form
  google.maps.event.addListener(handler.getMap().serviceObject, 'click', function(event) {
    clearOverlays();
    placeMarker(event.latLng);
    updateFormLocation(event.latLng);
  });
});

// Other functions
// Update form attributes with given coordinates
function updateFormLocation(latLng) {
  $('#centre_latitude').val(latLng.lat());
  $('#centre_longitude').val(latLng.lng());
  $('#centre_gmaps_zoom').val(handler.getMap().serviceObject.getZoom());
}
// Add a marker with an open infowindow
function placeMarker(latLng) {
  var marker = new google.maps.Marker({
    position: latLng, 
    map: handler.getMap().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(handler.getMap().serviceObject, marker);
  // Listen to drag & drop
  google.maps.event.addListener(marker, 'dragend', function() {
    updateFormLocation(this.getPosition());
  });
}
// Removes the overlays from the map, including the ones loaded with the map itself
function clearOverlays() {
  for (var i = 0; i < markersArray.length; i++ ) {
    markersArray[i].setMap(null);
  }
  markersArray.length = 0;

  for (var i = 0; i < handler.getMap().markers.length; i++ ) {
    handler.getMap().clearMarker(handler.getMap().markers[i]);
  }
}

Then I get an error:

TypeError: undefined is not an object (evaluating 'handler.getMap().markers[0]')

Also, the marker is not draggable...

Is there any complete example of how to do this?

Thanks all!


Solution

  • There are many errors in your code. Hard to explain one by one.

    Here is a solution suggestion.

    Basically when you use

    handler.getMap()
    

    its already a google maps object, so dont do:

    handler.getMap().serviceObject