I am trying to follow the answer here to zoom out a bit (by default) when a single marker is displayed on the map. I have tried the code below, and have a working map generating, but changing setZoom has no effect. Also, I receive the following error from firebug (below code).
<%= gmaps("markers" => {"data" => #json, "options" => {"auto_zoom" => false} }) %>
<% content_for :scripts do %>
<script type="text/javascript" charset="utf-8">
function gmaps4rails_callback() {
if (Gmaps4Rails.markers.length == 1) {
//only one marker, choose the zoom level you expect
Gmaps4Rails.map.setZoom(5);
}
else{
//more than one marker, let's auto_zoom
Gmaps4Rails.map_options.auto_zoom = true;
Gmaps4Rails.adjust_map_to_bounds();
}
}
</script>
<% end %>
The only error says:
TypeError: Yc is not a function
[Break On This Error]
...=b}Rf[F].Fa=xk(7,Yc("f"));me[F].cb=xk(3,function(a){var b;if(b=a.ca[ec]()?j:a.ca...
Ok, the interface changed a lot since I posted the answer you quote.
<%= gmaps("markers" => {"data" => #json, "options" => {"auto_zoom" => false} }) %>
<% content_for :scripts do %>
<script type="text/javascript" charset="utf-8">
Gmaps.map.callback = function() {
if (Gmaps.map.markers.length == 1) {
//only one marker, choose the zoom level you expect
setTimeout(function() { Gmaps.map.serviceObject.setZoom(5);}, 50);
}
else{
//more than one marker, let's auto_zoom
Gmaps.map.map_options.auto_zoom = true;
Gmaps.map.adjustMapToBounds();
}
}
</script>
<% end %>
Related
I would like to use the gmaps4rails gem to display a map of items in a fancybox.
I followed carefully the remarks on the wiki concerning ajax call, i.e. scripts have to be included manually in the application layout, maps have to be loaded in a javascript (see gem wiki).
But I still not succeed completely to make the map displayed in the box.
On the other hand as I hard code coordinates in the javascript it works fine, the map is displayed in the fancybox and the markers appear.
Let me recap.
In my index view, I have a ajax call to the items index action:
<%= link_to "Show Map", items_path(:format => :js, :show_map => true), :remote => true, :class => 'fancybox' %>
In the controller, I populate the map data:
def index
#items=Item.all
if params[:show_map]
#map= #items.to_gmaps4rails
end
end
in the index.js.erb file, I put
<% if params[:show_map] %>
var content = "<%= escape_javascript( gmaps({:last_map => false})) %>";
$.fancybox({
'content': content,
'padding' : 20
});
Gmaps.map = new Gmaps4RailsGoogle();
Gmaps.load_map = function() {
Gmaps.map.initialize();
Gmaps.map.markers = <%= #map %>;
Gmaps.map.create_markers();
Gmaps.map.adjustMapToBounds();
Gmaps.map.callback();
};
Gmaps.loadMaps();
<% else %>
// blablabla
<% end %>
Where the markers are provided in the map object.
This does not work and instead of my map I got in the fancybox the code itself appearing.
Something like:
var content = "\n
\n
<\/div>\n<\/div>\n"; $.fancybox({ 'content': content, 'padding' : 20 }); Gmaps.map = new Gmaps4RailsGoogle(); Gmaps.load_map = function() {Gmaps.map.initialize();
//Gmaps.map.markers = [{"lat":50.294,"lng":5.857},{"lat":50.294,"lng":5.857},{"lat":50.548,"lng":4.918},{"lat":50.384,"lng":3.649},{"lat":50.384,"lng":3.649},{"lat":50.08,"lng":4.5760000000000005},{"lat":50.054,"lng":5.195}];
Gmaps.map.markers = [{"lat":50.8483059,"lng":4.351783999999999},{"lat":50.496,"lng":5.066},{"lat":50.11,"lng":5.003},{"lat":50.11,"lng":5.003},{"lat":50.162,"lng":5.871},{"lat":50.08,"lng":4.5760000000000005},{"lat":50.08,"lng":4.5760000000000005},{"lat":50.08,"lng":4.5760000000000005}];
Gmaps.map.create_markers(); Gmaps.map.adjustMapToBounds(); Gmaps.map.callback(); }; Gmaps.loadMaps();
When instead of the erb <%= #map %>, I hard code the markers, for instance:
Gmaps.map.markers = [{"lat":50.294,"lng":5.857},"lat":50.294,"lng":5.857},{"lat":50.548,"lng":4.918}];
It works!
Seems like I'm missing something in the json data type conversion. But I'm not expert to find what is going wrong.
Thanks for your help!
Just successfully tried:
Open
<div id="test" style="display:none;width:300px;">
<%= gmaps markers: { data: #json } , last_map: false %>
</div>
<script type="text/javascript">
$(".fancybox").fancybox({
openEffect : 'none',
closeEffect : 'none',
afterLoad : function() { Gmaps.loadMaps(); }
});
</script>
Ok, I've got what was not going well. Thanks to the following answer https://stackoverflow.com/a/12219016/1100674.
As I use the following syntax:
Gmaps.map.markers = <%= #map %>;
I get the json rendered as this:
Gmaps.map.markers = [{"lat":50.8483059,"lng":4.351783999999999},{"lat":50.11,"lng":5.003},{"lat":50.11,"lng":5.003},{"lat":50.08,"lng":4.5760000000000005},{"lat":50.08,"lng":4.5760000000000005},{"lat":50.08,"lng":4.5760000000000005},{"lat":50.413,"lng":4.371}];
Whereas I use the raw() method,
Gmaps.map.markers = <%= raw(#map) %>;
I get the correct format.
Gmaps.map.markers = [{"lat":50.8483059,"lng":4.351783999999999},{"lat":50.11,"lng":5.003},{"lat":50.11,"lng":5.003},{"lat":50.08,"lng":4.5760000000000005},{"lat":50.08,"lng":4.5760000000000005},{"lat":50.08,"lng":4.5760000000000005},{"lat":50.413,"lng":4.371}];
I have a page on my site that lets users respond to invites by either accepting or declining them.
Their response is stored in the database as the boolean 'accepted', and is used to apply the classes 'selected' or 'not_selected' (selected makes the text orange) to the 'attending' div or the 'not attending' div.
<% #going, #not_going = invite.accepted ? ['selected','not_selected'] : ['not_selected','selected'] %>
<%= link_to(outing_invite_accept_path( { :outing_id => invite.outing_id, :invite_id => invite.user_id } )) do %>
<div class="attending_div <%= #going %>">
attending
</div>
<%end %>
<%= link_to(outing_invite_decline_path( { :outing_id => invite.outing_id, :invite_id => invite.user_id } )) do %>
<div class="attending_div <%= #not_going %>">
not attending</div>
</div>
<% end %>
When either div is clicked, it's diverted to the appropriate controller actions:
def invite_accept
#outing = Outing.find(params[:outing_id])
#invite = OutingGuest.find_by_outing_id_and_user_id(params[:outing_id], params[:invite_id])
#invite.update_attribute(:accepted, true)
redirect_to({:action => "index"})
end
def invite_decline
#outing = Outing.find(params[:outing_id])
#invite = OutingGuest.find_by_outing_id_and_user_id(params[:outing_id], params[:invite_id])
#invite.update_attribute(:accepted, false)
redirect_to({:action => "index"})
end
And as right now, this code works just fine. But it requires the index page be refreshed for it to take effect.
I know it's possible to update the page without a refresh using a jQuery ajax call attached to a listener on the appropriate div, but I have no idea what such a call would look like, or where to start, really...
You want to use rail's link_to :remote => true.
See http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to
For dealing with callbacks you can bind to certain events that will trigger. For example:
<%= link_to "Click Me!", some_path, :class => 'ajax', :remote => true %>
<script>
jQuery(function($) {
$("a.ajax")
.bind("ajax:loading", console.log('loading'))
.bind("ajax:complete", console.log('complete'))
.bind("ajax:success", function(event, data, status, xhr) {
console.log(data);
})
.bind("ajax:failure", function(xhr, status, error) {
console.log(error);
});
});
</script>
This page is also a pretty good write up: http://www.simonecarletti.com/blog/2010/06/unobtrusive-javascript-in-rails-3/
Am I missing something obvious? Map keeps loading #oldjson which I set in the controller and won't be replaced when I set it in the view.
View code:
<% #json = Map.find_by_id('39').to_gmaps4rails %>
<%= gmaps("markers" => {"data" => #oldjson, "options" => { "draggable" => true } } ) %>
<script>
Gmaps.map.replaceMarkers(<%= #json %>);
</script>
Thanks.
I guess you"re facing a js error with this current code.
The reason is the following:
the js used and created by gmaps4rails is put within the yield :scripts
so your additionnal js here is called before the map is created
Solution:
<% #json = Map.find_by_id('39').to_gmaps4rails %>
<%= gmaps("markers" => {"data" => #oldjson, "options" => { "draggable" => true } } ) %>
<% content_for :scripts do %>
<script>
Gmaps.map.replaceMarkers(<%= #json %>);
</script>
<% end %>
I would like to add a marker with link in marker, so, when i click that marker, i will redirect to another page
Is anybody know to do it?
Thanks
I already added my code like this :
In controller:
#json = #businesses.results.to_gmaps4rails do |object|
"\"link\": \"#{root_url}\""
end
In view :
<%= gmaps4rails(#json) %>
<% content_for :scripts do %>
<script type="text/javascript">
function redirect_to(url) {
window.location = url;
};
Gmaps4Rails.callback = function() {
function say_yo(arg) { return function(){alert('yo '+ arg + '!' );};};
for (var i = 0; i < Gmaps4Rails.markers.length; ++i) {
google.maps.event.addListener(Gmaps4Rails.markers[i].google_object, 'click', redirect_to(Gmaps4Rails.markers[i].link));
}
}
</script>
<% end %>
Is it any wrong? because there just an info window that show after i clicked the marker(Not redirect to any page)
First include the link inside the json:
Model.all.to_gmaps4rails do |object|
"\"link\": \"your link as string\""
end
Then add the extra listeners in your view (beware to include this AFTER your call to the gmaps method):
<%= gmaps(whatever you need here) %>
<% content_for :scripts do %>
<script type="text/javascript">
function redirect_to(url) {
window.location = url;
};
Gmaps4Rails.callback = function() {
function say_yo(arg) { return function(){alert('yo '+ arg + '!' );};};
for (var i = 0; i < Gmaps4Rails.markers.length; ++i) {
google.maps.event.addListener(Gmaps4Rails.markers[i].google_object, 'click', redirect_to(Gmaps4Rails.markers[i].link));
}
}
</script>
<% end %>
I'm trying to build a chained select menu. This is the tutorial I used: http://railscasts.com/episodes/88-dynamic-select-menus
Something goes wrong, I don't know what I'm missing.
javascript
var sottocategorie = new Array();
<% for element in #sottocategorie -%>
sottocategorie.push(new Array(<%= element.idcategoria %>, <%= element.c2 %>));
<% end -%>
function selezionacategoria() {
categoriaid = $('segnalazione_categoria1').getValue();
options = $('segnalazione_categoria2').options;
options.length = 1;
sottocategorie.each(function(elementement) {
if (element[0] == categoriaid) {
options[options.length] = new Option(element[1]);
}
});
if (option.length == 1) {
$('sottocategoria_field').hide();
} else {
$('sottocategoria_field').show();
}
}
document.observe('dom:loaded', function() {
//selezionacategoria();
$('segnalazione_categoria1').observe('change', selezionacategoria);
});
html
<label for="segnalazione_categoria1">Categoria:</label>
<%= f.collection_select :categoria1, Categorium.find(:all), :id, :c1, :prompt => "Seleziona categoria" %>
<p id="sottocategoria_field">
<label for="segnalazione_categoria2">Categoria:</label>
<%= f.collection_select :categoria2, Sottocategoria1.find(:all), :id, :c2, :prompt => "Seleziona sottocategoria" %>
</p>
routes:
match '/:controller(/:action(/:id))'
The chained select menu doesn't run, the "filter" doesn't work, and also
if (option.length == 1) {
$('sottocategoria_field').hide();
} else {
$('sottocategoria_field').show();
}
doesn't work.
SOLUTION:
I've changed the javascript file using jQuery:
var sottocategorie = new Array();
<% for sottocategoria in #sottocategorie %>
sottocategorie.push(new Array('<%= sottocategoria.idcategoria %>', '<%= escape_javascript(sottocategoria.c2) %>', <%= sottocategoria.id %>));
<% end %>
function menuSelected(orig_menu, new_menu, item_array) {
orig_value = $('#segnalazione_categoria1 :selected').text();
//alert(orig_value);
$(new_menu).empty();
jQuery.each(item_array, function(i, val) {
if (val[0] == orig_value) {
$(new_menu).append($("<option></option>").attr("value",val[2]).text(val[1]));
}
});
}
$(document).ready(function(){
//bind the click event to the city submit button
$('#submit_button').bind('click', function () {
menuSelected('#segnalazione_categoria1', '#segnalazione_categoria2', sottocategorie);
});
});
SOLUTION WITH THREE LEVELS OF CHAINING:
var sottocategorie = new Array();
var subsottocategorie = new Array();
<% for sottocategoria in #sottocategorie %>
sottocategorie.push(new Array('<%= sottocategoria.idcategoria %>', '<%= escape_javascript(sottocategoria.c2) %>', <%= sottocategoria.id %>));
<% end %>
<% for subsottocategoria in #subsottocategorie %>
subsottocategorie.push(new Array('<%= subsottocategoria.idsottocategoria1s %>', '<%= escape_javascript(subsottocategoria.c3) %>', <%= subsottocategoria.id %>));
<% end %>
function menuSelected(orig_menu, new_menu, item_array) {
orig_value = $(''+ orig_menu + ' :selected').text();
//alert(orig_value);
$(new_menu).empty();
jQuery.each(item_array, function(i, val) {
if (val[0] == orig_value) {
$(new_menu).append($("<option></option>").attr("value",val[1]).text(val[1]));
}
});
}
$(document).ready(function(){
$(".nascosto").hide();
$(".nascosto1").hide();
//bind the click event to the city submit button
$('#segnalazione_categoria1').bind('click', function () {
$(".nascosto").show();
$('#segnalazione_categoria3').empty();
menuSelected('#segnalazione_categoria1', '#segnalazione_categoria2', sottocategorie);
});
$('#segnalazione_categoria2').bind('click', function (event) {
$(".nascosto1").show();
menuSelected('#segnalazione_categoria2', '#segnalazione_categoria3', subsottocategorie);
});
});