I’m working on a Rails app with a Google Map and markers. The map works fine on the index page. I’m showing info for the last 5 markers in a sidebar using a partial called _timeline
.
When I click an item in the sidebar, I want to center the map on that marker. Right now, it reloads the whole map, which isn’t what I want.
Here’s what I’ve got:
# index.html.erb
<div class="row">
<% @recent_posts.each do |post| %>
<%= render partial: "posts/summary", locals: { post: post } %>
<% end %>
</div>
<script>
var mapHandler = Gmaps.build('Google');
mapHandler.buildMap({
provider: { disableDefaultUI: true },
internal: { id: 'map' }
}, function(){
var pins = mapHandler.addMarkers(<%=raw @map_data.to_json %>);
mapHandler.bounds.extendWith(pins);
mapHandler.fitMapToBounds();
});
</script>
In the posts/summary
partial:
$('#post_<%= post.id %>').click(function() {
var newCenter = new google.maps.LatLng(<%= post.lat %>, <%= post.lng %>);
var newMap = new google.maps.Map(document.getElementById('map'));
newMap.setZoom(13);
newMap.setCenter(newCenter);
newMap.setMapTypeId(google.maps.MapTypeId.ROADMAP);
});
How can I use the mapHandler
from the index in my partial to just recenter the existing map?
hey luke, i think ur prob is u’re creating a new map instance in the partial. instead, try accessing the existing mapHandler like this:
$('#post_<%= post.id %>').click(function() {
var newCenter = new google.maps.LatLng(<%= post.lat %>, <%= post.lng %>);
mapHandler.getMap().setCenter(newCenter);
mapHandler.getMap().setZoom(13);
});
this shud center the existing map without reloading. lmk if it works!
I’ve encountered a similar issue before. The key is to make the mapHandler globally accessible. Try modifying your index.html.erb script like this:
window.mapHandler = Gmaps.build('Google');
window.mapHandler.buildMap({
// ... rest of your existing code
});
Then in your partial, you can directly use the global mapHandler:
$('#post_<%= post.id %>').click(function() {
var newCenter = new google.maps.LatLng(<%= post.lat %>, <%= post.lng %>);
window.mapHandler.getMap().setCenter(newCenter);
window.mapHandler.getMap().setZoom(13);
});
This approach should allow you to manipulate the existing map without reloading. It’s more efficient and provides a smoother user experience.
I’ve dealt with this exact problem in a project I worked on. The solution that worked for me was to use a custom event system. Here’s what I did:
In your index.html.erb, after initializing the map, add an event listener:
$(document).on('centerMap', function(e, lat, lng) {
var newCenter = new google.maps.LatLng(lat, lng);
mapHandler.getMap().setCenter(newCenter);
mapHandler.getMap().setZoom(13);
});
Then in your partial, trigger the event instead of trying to manipulate the map directly:
$('#post_<%= post.id %>').click(function() {
$(document).trigger('centerMap', [<%= post.lat %>, <%= post.lng %>]);
});
This approach keeps your map logic centralized and avoids scope issues. It’s also more flexible if you need to add more map interactions later.