I'm using gmap4rails v2
with rails 4.1
and instead of loading all of the infoboxes
at once, which is very inefficient, I would like to only load the contents for the info box of a particular marker
once that marker is clicked. I came up with the following to select the marker.
markers = handler.addMarkers(<%= raw(@hash.to_json) %>);
_.each(markers, function(marker){
google.maps.event.addListener(handler.getMap(), 'click', function(){
marker.infowindow();
});
});
But I'm not sure how I can send a query to my user table to get the needed attributes for example User.name
, User.photo
that will be used in the infobox
.
The full gmaps handler is here:
var handler = Gmaps.build('Google', { markers: { maxRandomDistance: null, clusterer: undefined } }),
maxZoom = 14;
handler.buildMap({
provider: {
mapTypeControl: false,
mapTypeId: google.maps.MapTypeId.ROADMAP,
streetViewControl: false,
doClustering: false,
minZoom: 5
},
internal: {id: 'big_map'}},
function(){
markers = handler.addMarkers(<%= raw(@hash.to_json) %>);
_.each(markers, function(marker){
google.maps.event.addListener(handler.getMap(), 'click', function(){
marker.infowindow();
});
});
handler.map.centerOn([$("#big_map").data("lat"),$("#big_map").data("lng")]);
handler.getMap().setZoom(15);
//handler.bounds.extendWith(markers);
//handler.fitMapToBounds();
});
controller which loads marker info:
return Gmaps4rails.build_markers(profiles) do |profile, marker|
marker.lat profile.latitude
marker.lng profile.longitude
marker.json({ :id => profile.profile_code })
# this is how I loaded all markers before: marker.infowindow render_to_string(partial: "info_window", locals: { profile: profile })
marker.picture({
url: view_context.image_path( "marker-#{ (profile == current_user.profile) ? 'green' : 'blue' }.png"),
width: 32,
height: 32
})
end
Is there any way I could send a partial to the infowindow()
function like I did in the original markers load as seen below? And if so how would I send the user.id
to the partial (in my case it's profile.profile_code
which I set each marker.id
to equal that I think.
UPDATE:
Ok I now realize I need to make a request to the server, which javascript can't do so I'm going to try to use ajax by using
markers = handler.addMarkers(<%= raw(@hash.to_json) %>);
_.each(markers, function(marker){
google.maps.event.addListener(handler.getMap(), 'click', function(){
var infowindow = marker.infowindow;
$.post('<%= load_info_box_url %>', {
}, function(data){
infowindow.html(data).name %>)
infowindow.open(Gmaps.map.map, marker);
});
});
});
followed by making a load_info_box route and then requesting the necessary data in a controller, sending back html to data!
@apneadiving had a great answer but I found it a bit hard implementing links, conditionals and styling into javascript templates so I ended up using the ajax approach.
javascript:
markers = handler.addMarkers(data.markers);
_.each(markers, function(json, index){
json.marker = markers[index];
google.maps.event.addListener(json.marker.getServiceObject(), 'click', function(){
var infowindow = json.marker.infowindow;
$.post('<%= load_infobox_url %>', {
marker_id: data.markers[index].id
}, function(data){
infowindow.setContent(data.html);
infowindow.open(map, google.maps.markers[index]);
});
});
});
routes
post '/load_infobox', to: 'requests#load_infobox', as: 'load_infobox'
controller action:
def load_infobox
profile = Profile.find_by(profile_code: params[:marker_id])
render json: { html: render_to_string(partial: "info_window", locals: { profile: profile }) }
end