Rails, gmaps4rails: Accessing javascript variable from within partial - ruby-on-rails

Users can post 'notices' and these are displayed in users/show.html.erb in their 'notice feed'. Each notice has a :latitude and a :longitude and an associated marker on a google map.
I'm trying to make the marker change colour when the user hovers over the notice in the feed. I've given the marker the same id as the notice with marker.json({ id: notice.id }). In the notice partial, each notice is uniquely identified by its id: <li id="notice-<%= notice.id %>">. The problem is accessing 'markers' from within the notice partial. I want to use the code markers[<%= notice.id %>] but how do I pass 'markers' from the show javascript to the partial javascript?
Alternatively, I could do it all inside the show javascript, but the problems remains: how would I access the notice id from within the show javascript?
Users_controller.rb:
def show
#notice = #character.notices.build
#notice_feed_items = current_user.notice_feed.paginate(page: params[:notices_page])
#hash = Gmaps4rails.build_markers(#notice_feed_items) do |notice, marker|
marker.lat notice.latitude
marker.lng notice.longitude
marker.infowindow notice.content
marker.json({ id: notice.id })
end
redirect_to root_url and return unless #user.activated
end
users/show/html.erb:
<% if #notice_feed_items.any? %>
<ol class="posts">
<%= render #notice_feed_items %>
</ol>
<%= will_paginate #notice_feed_items, param_name: 'notices_page' %>
<% end %>
<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();
map = handler.getMap();
var update_timeout = null;
google.maps.event.addListener(map, 'click', function(event){
update_timeout = setTimeout(function(){
placeMarker(event.latLng);
fillInForm(event.latLng);
document.getElementById("dropfield").focus();
}, 300);
});
google.maps.event.addListener(map, 'dblclick', function(event) {
clearTimeout(update_timeout);
});
});
function placeMarker(latLng) {
var marker = new google.maps.Marker({
position: latLng,
map: map,
draggable: false
});
}
function fillInForm(latLng) {
$('#notice_latitude').val(latLng.lat());
$('#notice_longitude').val(latLng.lng());
}
</script>
_notice.html.erb:
<li id="notice-<%= notice.id %>">
.
.
.
</li>
<script type="text/javascript">
document.getElementById("notice-<%= notice.id %>").onmouseover=function(){
markers[<%= notice.id %>].setIcon("markers/blue_MarkerA.png");
}
document.getElementById("notice-<%= notice.id %>").onmouseout=function(){
markers[<%= notice.id %>].setIcon("markers/yellow_MarkerA.png");
}
</script>
EDIT:
I'm trying to solve the problem by doing it all in show.html.erb with the following code, using grep:
<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();
map = handler.getMap();
var update_timeout = null;
google.maps.event.addListener(map, 'click', function(event){
update_timeout = setTimeout(function(){
placeMarker(event.latLng);
fillInForm(event.latLng);
document.getElementById("dropfield").focus();
}, 300);
});
google.maps.event.addListener(map, 'dblclick', function(event) {
clearTimeout(update_timeout);
});
});
function placeMarker(latLng) {
var marker = new google.maps.Marker({
position: latLng,
map: map,
draggable: false
});
}
function fillInForm(latLng) {
$('#notice_latitude').val(latLng.lat());
$('#notice_longitude').val(latLng.lng());
}
$("#notice_list li").on('mouseenter', function(){
var id = $(this).attr('id');
$.grep(markers, function(m){return m.id == id;})[0].setIcon("markers/blue_MarkerA.png");
}).on('mouseleave', function(){
var id=$(this).attr('id');
$.grep(markers, function(m){return m.id == id;})[0].setIcon("markers/yellow_MarkerA.png");
});
</script>
... but it isn't working. I think the problem is that trying to access the id of each marker in markers with m.id isn't working. I tried to get it to print out markers[0].id but nothing happened, it seems you can't access the marker id with markers[0].id?! (I checked markers.length wasn't zero. It wasn't - the map is full of markers).
So, how do you access the id of an element of markers if markers[0].id doesn't work??

marker haven't id attribute. To have a reference of each marker you could use the index of the markers array (adding markers one per one).
# pseudocode
<% #notice_feed_items.each do |item| %>
markers[<%= item.id %>] = handler.addMarker(<%=raw item.to_json %>);
<% end %>

Related

Markers does not appear when Infowindow with partial added

I am using Gmaps4rails gem. I could show markers without Infowindow, but after adding Infowindow in the controller, any markers do not appear. As the following, the Infowindow is rendered with partial.
What should I change the code? Thank you in advance.
clinics_controller.rb
#hash = Gmaps4rails.build_markers(#clinics) do |clinic, marker|
marker.lat clinic.latitude
marker.lng clinic.longitude
marker.json({:id => clinic.id})
marker.picture ({
"url" => "/images/red-dot.png",
"width" => 32,
"height" => 32
})
marker.infowindow render_to_string(partial: "map_infowindow", locals: {clinic: clinic})
end
_map_infowindow.html.erb
<h3><%= clinic.name %></h3>
Javascript
<script type="text/javascript" charset="utf-8">
handler = Gmaps.build('Google');
handler.buildMap({
provider: {
zoom: 15,
center: {lat: 35.765, lng: 139.62}
},
internal: {id: 'map'}},
function(){
markers = handler.addMarkers(<%= raw #hash.to_json %>);
}
);
</script>

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 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

Gmaps4rails how create markers list

My code:
Location model:
class Location < ActiveRecord::Base
attr_accessible :latitude, :longitude, :timestamp, :user_id, :user
validates :latitude, :longitude, :timestamp, :user, :presence => true
belongs_to :user
def gmaps4rails_sidebar
"<span>#{user}</span>"
end
end
Controller:
#locations = []
User.all.each do |user|
if user.role?('manager')
last_location = user.locations.last
if last_location
location = {}
location[:lat] = last_location.latitude
location[:lng] = last_location.longitude
location[:title] = last_location.timestamp
location[:infowindow] = "<b>#{t(:datetime)}:</b> #{last_location.created_at} <br /><b>#{t(:latitude)}:</b> #{last_location.latitude}<br /><b>#{t(:longitude)}:</b> #{last_location.longitude}<br /><b>#{t(:user)}:</b> #{user.username}"
#locations << location
end
end
end
View:
<%= javascript_include_tag 'locations' %>
<div class="map_container" style='width: 980px; height: 458px;'>
<div id="map" style='width: 980px; height: 458px;'></div>
</div>
<ul id="markers_list"> </ul>
<script type="text/javascript">
jQuery(document).ready(function() {
handler = Gmaps.build('Google', { markers: { maxRandomDistance: null } });
handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
markers = handler.addMarkers(<%=raw #locations.to_json %>);
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
handler.getMap().setZoom(12);
});
});
</script>
I want to display a list of markers. I read how it was done in the old version gem. But do not know how to do it in the new version. Prompt as gem in the new version you can list markers to a separate list?
I find example http://apneadiving.github.io/
<script type="text/javascript">
jQuery(document).ready(function() {
var locations_json = <%=raw #locations.to_json %>
handler = Gmaps.build('Google', { markers: { maxRandomDistance: null } });
handler.buildMap({ provider: {}, internal: {id: 'map'}, list_container: "markers_list"}, function(){
markers = handler.addMarkers(locations_json);
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
handler.getMap().setZoom(12);
_.each(locations_json, function(json, index){
json.marker = markers[index];
});
createSidebar(locations_json);
});
function createSidebarLi(json){
return ("<li><a>" + json.name + "</a></li>");
};
function bindLiToMarker($li, marker){
$li.on('click', function(){
handler.getMap().setZoom(14);
marker.setMap(handler.getMap());
marker.panTo();
google.maps.event.trigger(marker.getServiceObject(), 'click');
})
};
function createSidebar(json_array){
_.each(locations_json, function(json){
var $li = $( createSidebarLi(json) );
$li.appendTo('#markers_list');
bindLiToMarker($li, json.marker);
});
};
});
</script>

Resources