Rails: Customizing an infowindow using gmaps4rails - ruby-on-rails

I have been following the gmaps4rails tutorials on github but am not understanding how to customize the infowindow. I have a database that is collecting internship data including locations, names, companies, and descriptions. The markers are appearing on the correct places on the map, however I can only get the infowindow to display the name or the description or the company when I need it to display all of them.
I am new to rails, and do not totally understand what I need to be updating to allow all of these attributes to appear in the infowindow. I am attaching my code below:
Internship model:
class Internship < ApplicationRecord
geocoded_by :address
after_validation :geocode
end
Internship View:
<script src="//maps.google.com/maps/api/js?key=AIzaSyBj4qLUeW291Z5WvVOwzseQONRBGCnA8ds"></script>
<script src="//cdn.rawgit.com/mahnunchik/markerclustererplus/master/dist/markerclusterer.min.js"></script>
<script src='//cdn.rawgit.com/printercu/google-maps-utility-library-v3-read-only/master/infobox/src/infobox_packed.js' type='text/javascript'></script> <!-- only if you need custom infoboxes -->
<div style='width: 800px;'>
<div id="map" style='width: 1100px; height: 600px'></div>
</div>
<script type="text/javascript">
handler = Gmaps.build('Google');
handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
markers = handler.addMarkers(<%=raw #hash.to_json %>);
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
});
</script>
Internship Controller:
def index
#internships = Internship.all
#hash = Gmaps4rails.build_markers(#internships) do |internship, marker|
marker.lat internship.latitude
marker.lng internship.longitude
marker.infowindow internship.description
end
end
Any help I can get is greatly appreciated!

I needed to add an array to the controller that holds all the values from the database and then passes the array into the infowindow:
def index
#internships = Internship.all
#internship_properties = Array.new
#internships.each do |internship|
#internship_properties.push(internship)
end
#hash = Gmaps4rails.build_markers(#internship_properties) do |internship_prop, marker|
concat_info_window = "#{internship_prop.name}, #{internship_prop.address}, #{internship_prop.company}, #{internship_prop.title}, #{internship_prop.date}, #{internship_prop.description}"
marker.lat internship_prop.latitude
marker.lng internship_prop.longitude
marker.infowindow concat_info_window
end
end

Related

How to show current location on Google-Maps-for-Rails

I have the gem 'gmaps4rails' installed and currently the setup is to show the location:
<div style='width: 800px;'>
<div id="map" style='width: 800px; height: 400px;'></div>
</div>
<script>
handler = Gmaps.build('Google');
handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
markers = handler.addMarkers(<%=raw #hash.to_json %>);
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
handler.getMap().setZoom(16);
});
</script>
I would like to show the current location on the map as well. Any ideas on how to implement that?
Append current user location hash into your array of location hash and Rest will be handled by Gmap4Rails
def show
#las = La.find(params[:id])
#hash = Gmaps4rails.build_markers(#las) do |la, marker|
marker.lat la.latitude
marker.lng la.longitude
end
append_cur_location
end
def append_cur_location
#hash << { :lat=>action[0], :lng=>action[1]}
end
def action
#lat_lng = cookies[:lat_lng].split("|")
end
Extras: If you want separate image for current user location.use below
{ :lat=>12.9698, :lng=>77.7499, :picture=>{:url=>user_image_path,
:width=>32, :height=>32} }

gmaps4rails enable clustering

How can I enable clustering so instead of showing markers it is clustered? For example: https://www.police.uk/metropolitan/00BK17N/crime/
users_controller
class UsersController < ApplicationController
def index
#users = User.all
#hash = Gmaps4rails.build_markers(#users) do |user, marker|
marker.lat user.latitude
marker.lng user.longitude
marker.infowindow user.description
end
end
end
index.html.erb
<div id="map-container">
<div id="map-canvas"></div>
</div>
<script>
$(document).ready(function(){
handler = Gmaps.build('Google');
handler.buildMap({ provider: {}, internal: {id: 'map-canvas'}}, function(){
markers = handler.addMarkers(<%=raw #hash.to_json %>)
handler.bounds.extendWith(markers);
handler.fitMapToBounds(markers);
if(navigator.geolocation)
navigator.geolocation.getCurrentPosition;
});
});
</script>
Appreciate your help guys
Did you try this?
https://github.com/apneadiving/Google-Maps-for-Rails/wiki/Markers#displaying-your-markers
Simply passing do_clustering => true should enable it. It's false by default.
Example:
<%= gmaps("markers" => { "data" => #markers, "options" => { "do_clustering" => true } }) %>

Google Maps for Rails - update markers with AJAX

I am working on a web app and I use Ruby on Rails. Our index is made of a map and of a search field. You can search a location and the map updates its markers.
I would like to use Ajax to avoid refreshing the page. So I added remote: true to the form, a respond_to in the controller and a new search.js.erb. My search.js.erb renders a partial _googlemap.erb which contains the script to initialize the map.
Here is my problem. As the map already exists, it's like if I wanted to create the same object twice, which of course doesn't work and is awfull. I'd like to update only markers in the map with new ones. But I can't find a way to do it.
I saw the former version of Gmaps4rails integrated a way to do it ( Gmaps.map.replaceMarkers(your_markers_json_array); ) but it doesn't seem to work now. When I use it, I got this error: "TypeError: Gmaps.map is undefined". I tried with "handler.replaceMarkers();" but this time I have "TypeError: handler.replaceMarkers is not a function".
I am new to Javascript and to Rails, but I want to improve my knowledge and I really need to go on with the rest of this web app. I have been looking for a solution everywhere on the internet but in vain.
Live website here
Please, could someone tell me how I could do that and what I am doing wrong?
MANY thanks in advance,
CĂ©line
zones_controller.rb
def search
respond_to do |format|
format.html.none do
search_params = params[:zone][:search]
coordinates = Geocoder.coordinates(search_params).join(",")
#zones = Zone.search(
"", { "aroundLatLng" => coordinates,
"aroundRadius" => 500000 #Searches around 500 km
})
if coordinates.nil?
#zones = Zone.search(params[:search])
elsif #zones.empty?
#zones = Zone.all
flash[:error] = "No zone could be found. Please try again."
end
build_map(#zones)
end
format.js
end
end
def build_map(array)
#hash = Gmaps4rails.build_markers(array) do |zone, marker|
marker.lat zone.latitude
marker.lng zone.longitude
marker.json({ title: zone.description, id: zone.id })
marker.infowindow render_to_string(:partial => "/zones/map_box", locals: { zone: zone })
end
end
search.html.erb
<div id="map" style='width: 100%; height: 700px;'>
</div>
<!-- Beginning Google maps -->
<script type="text/javascript" id="map_script">
$(document).ready(function() {
<%= render 'googlemap', hash: #hash %>
}); // Document ready
</script>
_googlemap.erb
handler = Gmaps.build('Google');
handler.buildMap({ provider: {
disableDefaultUI: true,
mapTypeId: google.maps.MapTypeId.TERRAIN
}, internal: {id: 'map'}
}, function(){
markers_json = <%= raw hash.to_json %>;
markers = _.map(markers_json, function(marker_json){
marker = handler.addMarker(marker_json);
handler.getMap().setZoom(4);
_.extend(marker, marker_json);
marker.infowindow = new google.maps.InfoWindow({
content: marker.infowindow
});
return marker;
});
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
});
search.js.erb
$('#map_script').replaceWith("<%= render 'googlemap', hash: #hash %>");
Why don't you just update the map with the new markers? Meaning, instead of re-rendering the whole map after each search, just update the markers on the existing map by removing all markers and adding the new ones.
I haven't verified the method, but I guess it should work and be more efficient:
Create a app/assets/javascript/map.js file. You can store your map-related functions there. Create a function to update your map's markers in this file:
map.js
(function() {
/* __markers will hold a reference to all markers currently shown
on the map, as GMaps4Rails won't do it for you.
This won't pollute the global window object because we're nested
in a "self-executed" anonymous function */
var __markers;
function updateMarkers(map, markersData)
{
// Remove current markers
map.removeMarkers(__markers);
// Add each marker to the map according to received data
__markers = _.map(markersData, function(markerJSON) {
marker = map.addMarker(markerJSON);
map.getMap().setZoom(4); // Not sure this should be in this iterator!
_.extend(marker, markerJSON);
marker.infowindow = new google.maps.InfoWindow({
content: marker.infowindow
});
return marker;
});
map.bounds.extendWith(__markers);
map.fitMapToBounds();
};
// "Publish" our method on window. You should probably have your own namespace
window.updateMarkers = updateMarkers;
})();
This function can be used to initialize your map and to update it. As you will not (if my answer satisfies you) render the map twice, you can delete _google_map.erb and put its content back into search.html.erb, but using the function we've just created:
search.html.erb
<div id="map" style='width: 100%; height: 700px;'>
</div>
<!-- Beginning Google maps -->
<script type="text/javascript" id="map_script">
$(document).ready(function() {
mapHandler = Gmaps.build('Google');
mapHandler.buildMap({ provider: {
disableDefaultUI: true,
mapTypeId: google.maps.MapTypeId.TERRAIN
}, internal: {id: 'map'}
}, function(){
var markersData = <%= raw #hash.to_json %>;
updateMarkers(mapHandler, markersData);
});
}); // Document ready
</script>
Please don't forget the var keyword when declaring variables, otherwise they will end up being globals, and that's bad ^^
Note that I have deliberately left mapHandler as a global variable: you will need access to your handler to update markers later when someone uses the search. This is probably not an ideal thing to do, but this question is not about refactoring your code so let's keep it this way.
So now my solution brings you a map that initializes with the given markers on page load. In other words, nothing has changed!
However you're now allowed to reuse this updateMarkers function to change the markers displayed on your map. That's what you search.js.erb script should do:
search.js.erb
(function() {
var markersData = <%= raw #hash.to_json %>;
updateMarkers(mapHandler, markersData);
})();
That's it! Hopefully it'll take you to the next step of your project :)
I tried the same thing but instead of updating the marker you should include the map in the partial/placeholder and then update it ...
for example, this is the view which is displaying the map...i will update this view/placeholder with latest map and markers
<div id="map_users_index">
<div id="map" class="map" style="height:relative;">
</div>
in users_controller.rb
##take index action or any other action
def index
##do your stuff and get more users
respond_to do |format|
format.html
format.js
end
end
in index.js.erb
##update the placeholder/partial with new map with new markers
$("#map_users_index").html("<%= escape_javascript(render(:partial => 'index')) %>");
I HAVE MY OWN WORKING CODE...HERE

gmaps4rails gem: to_gmaps4rails method undefined

I'm trying to dynamically update the markers on a google map using gmaps4rails (i.e. with an AJAX call back). I'm finding the documentation for gmaps4rails very scattered and unclear.
I've successfully been able to display markers on a map using the build_markers method (as per the video tutorial v2).
My controller code:
# GET /telemetry_recordings
def index
#telemetry_recordings = TelemetryRecording.all
#hash = Gmaps4rails.build_markers(#telemetry_recordings) do |telemetry_recording, marker|
marker.lat telemetry_recording.latitude
marker.lng telemetry_recording.longitude
marker.title telemetry_recording.delivery_unit.driver.full_name
marker.infowindow telemetry_recording.delivery_unit.driver.full_name
end
end
My view code:
<script type="text/javascript">
handler = Gmaps.build('Google');
handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
markers = handler.addMarkers(<%=raw #hash.to_json %>);
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
});
</script>
Now, to implement a dynamic update, I've added the following script to my view:
<script type="text/javascript">
jQuery(function($) {
$('body').on('click', '#replace_markers', function(){
$.getJSON("/telemetry_recordings", function(data){
Gmaps.map.replaceMarkers(data);
});
});
});
</script>
As well as a button:
<button id="replace_markers">Refresh</button>
And, I've added the following code to my controller:
respond_to :json, :html
# GET /telemetry_recordings
def index
#json = TelemetryRecording.all.to_gmaps4rails
respond_with #json
end
Note: TelemetryRecording class has 3 attributes: latitude (float), longitude (float) and location_time (DateTime)
This results in the following error:
undefined method `to_gmaps4rails' for #<TelemetryRecording::ActiveRecord_Relation:0x55dee78>
As per the documentation, I've installed the gmaps4rails gem, added //= require underscore and
//= require gmaps/google to my application.js file, and included the following scripts in my view:
<script src="//google-maps-utility-library-v3.googlecode.com/svn/tags/markerclustererplus/2.0.14/src/markerclusterer_packed.js" type="text/javascript"></script>
<script src="//maps.google.com/maps/api/js?v=3.13&sensor=false&libraries=geometry" type="text/javascript"></script>
Am I using to_gmaps4rails correctly here? (my understanding is that it converts an object with latitude/longitude attributes to an array of markers, e.g. [{"lat":"x", "lng":"y"}, {"lat":"x", "lng":"y"}]. Why is it undefined?
You're using code from v1.x and 2.x.
to_gmaps4rails has been removed from the code base. So your first shot was ok:
def index
#hash = Gmaps4rails.build_markers(TelemetryRecording.all) do |telemetry_recording, marker|
marker.lat telemetry_recording.latitude
marker.lng telemetry_recording.longitude
marker.title telemetry_recording.delivery_unit.driver.full_name
marker.infowindow telemetry_recording.delivery_unit.driver.full_name
end
respond_with #hash
end
and in the js
<script type="text/javascript">
handler = Gmaps.build('Google');
handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
var markers = handler.addMarkers(<%=raw #hash.to_json %>);
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
$('body').on('click', '#replace_markers', function(){
$.getJSON("/telemetry_recordings", function(newMarkers){
handler.removeMarkers(markers); // to remove previous markers
markers = handler.addMarkers(newMarkers);
});
});
});
});
</script>

gmaps4rails v2 Sidebar - Can't figure out how to

I can't figure out how to display the sidebar for google map on my rails app.
It's been a while and i can't find any sources on that subject. The v2 of the gem changed a lot and i'm not skilled enaught.
This is my code:
view:
<div style='width: 800px;'>
<div id="map" style='width: 800px; height: 400px;'></div>
</div>
<div id='markers_list'></div>
<script type="text/javascript">
$(document).ready(function(){
var raw_markers = <%=raw #hash.to_json %>;
var gmaps_markers;
function createSidebarLi(property_json) {
return ("<li><a>" + property.titre + " - " + property.address + "<\/a></li>");
};
function bindLiToMarker($li, marker){
$li.click(function(){
marker.panTo(); //to pan to the marker
google.maps.event.trigger(marker.getServiceObject(), "click"); // to open infowindow
});
};
function createSidebar(){
for (var i=0;i<raw_markers.length;i++){
var $li = $( createSidebarLi(raw_markers[i]) );
$li.appendTo($('#markers_list'));
bindLiToMarker($li, gmaps_markers[i]);
}
};
handler = Gmaps.build('Google', {markers: { maxRandomDistance: 1} });
handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
markers = handler.addMarkers(raw_markers);
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
createSidebar();
});
});
google.maps.event.addListener(marker, 'mouseout', function(){
infowindow.open(marker.get('map'), marker);
});
</script>
controller:
def index
#properties = Property.all
#hash = Gmaps4rails.build_markers(#properties) do |property, marker|
marker.lat property.latitude
marker.lng property.longitude
marker.infowindow property.titre
end
end
Can somebody help me ?
You made several mistakes, variable names etc...
I made you a working plunkr here.
If you need documentation, check here.
To pass additional info in the json:
#hash = Gmaps4rails.build_markers(#properties) do |property, marker|
marker.lat property.latitude
marker.lng property.longitude
marker.infowindow property.titre
marker.json({ titre: property.marker, address: property. address})
end

Resources