Search code examples
ruby-on-railsruby-on-rails-3prototypejsrjsgmaps4rails

gmaps4rails map not showing when loaded dynamically using prototype


I have a view with 3 tabs each representing a view of the data (Table, Map, Charts). When I click on the tab it blinds up the view before if runs switch_view.js.rjs

<%= link_to_remote I18n.t('biomass_configuration_menu.button.view.table'), 
        :url =>{:controller => :biogas_calculator, :action => :switch_view, :view => "table"}, 
        :method => :get, 
        :loading => visual_effect(:blind_up, "biomass_configuration", :duration => 0.5, :queue => 'front'), 
        :html => {:id => "table_view", :class => "toggle_map_button"} %>

<%= link_to_remote I18n.t('biomass_configuration_menu.button.view.map'), 
        :url =>{:controller => :biogas_calculator, :action => :switch_view, :view => "map"}, 
        :method => :get, 
        :loading => visual_effect(:blind_up, "biomass_configuration", :duration => 0.5, :queue => 'front'), 
        :html => {:id => "map_view", :class => "toggle_map_button"} %>

<%= link_to_remote I18n.t('biomass_configuration_menu.button.view.charts'), 
        :url =>{:controller => :biogas_calculator, :action => :switch_view, :view => "charts"}, 
        :method => :get, 
        :loading => visual_effect(:blind_up, "biomass_configuration", :duration => 0.5, :queue => 'front'), 
        :html => {:id => "chart_view", :class => "toggle_map_button"} %>

When I click on the map tab I am running this:

In the HTML map view:

<%= gmaps(:map_options => { :id => "configuration_map", 
          :last_map => false },
          :markers => { "data" => @json, "options" => {"list_container" => "markers_list" }}) %>

In my RJS (switch_view.js.rjs), biomass_configuration is the DIV the HTML presenting either a Table, a Map or Charts:

page.replace_html("biomass_configuration", :partial => "biomass_configuration")

page[:biomass_configuration].visual_effect :blind_down, :duration => 1

if session[:view] == "map"
      page.delay 3 do
         page << "Gmaps.loadMaps();"    <=== I thought this would do the trick
      end
end

When I click on the tabs, it correctly blinds up and down for the table view and the charts, but it still doesn't work with my map.

I figured I should put a delay after the blind down and before I call Gmaps.loadMaps() ... I tried playing with that delay without any chance.

If I reload the page Ctrl + R then the blind up and down seem to work correct.

I also tried setting :last_map => true with no success ...

Here the app http://biowattsonline.com

My application.js:

//= require prototype
//= require prototype_ujs
//= require effects
//= require dragdrop
//= require controls
//= require_tree .
//= require gmaps4rails/bing.js
//= require gmaps4rails/googlemaps.js
//= require gmaps4rails/mapquest.js
//= require gmaps4rails/openlayers.js   
//= require gmaps4rails/all_apis.js
//= require facebox.js
//= require i18n
//= require i18n/translations

20121229 - WHAT I DID NEW to resolve the issue:

Instead of replacing the div biomass_configuration, I decided to load all 3 views and only show the one on a tab click. So the other DIVs are set with display:none.

I changed my tab buttons link_to_remote and my switch_view.rjs:

MY TAB BUTTONS:

<%= link_to_remote I18n.t('biomass_configuration_menu.button.view.table'), 
    :url =>{:controller => :biogas_calculator, :action => :switch_view, :view => "table"}, 
    :method => :get, 
    :loading => visual_effect(:fade, "biomass_configuration_charts", :duration => 1, :queue => 'front') +
                visual_effect(:fade, "biomass_configuration_map", :duration => 1, :queue => 'front'),
    :html => {:id => "table_view", :class => "toggle_map_button"} %>

<%= link_to_remote I18n.t('biomass_configuration_menu.button.view.map'), 
    :url =>{:controller => :biogas_calculator, :action => :switch_view, :view => "map"}, 
    :method => :get, 
    :before =>  visual_effect(:fade, "biomass_configuration_charts", :duration => 1, :queue => 'front') + 
                visual_effect(:fade, "biomass_configuration_table", :duration => 1, :queue => 'front'),
    :loading => visual_effect(:appear, "biomass_configuration_map", :duration => 1, :queue => 'end'), 
    :complete => 'Gmaps.loadMaps();' ,
    :html => {:id => "map_view", :class => "toggle_map_button"}  if logged_in? %>

<%= link_to_remote I18n.t('biomass_configuration_menu.button.view.charts'), 
    :url =>{:controller => :biogas_calculator, :action => :switch_view, :view => "charts"}, 
    :method => :get, 
    :loading  => visual_effect(:fade, "biomass_configuration_table", :duration => 1, :queue => 'front') + 
                 visual_effect(:fade, "biomass_configuration_map", :duration => 1, :queue => 'front'), 
    :html => {:id => "chart_view", :class => "toggle_map_button"} %>

and my RJS:

if  session[:view] == "map"
  #page[:biomass_configuration_map].visual_effect :appear
end

if  session[:view] == "table"
  page[:biomass_configuration_table].visual_effect :appear
end

if  session[:view] == "charts"
  page[:biomass_configuration_charts].visual_effect :appear
end

This time the map shows but in a corner. A problem I had before, but somehow the fix didn't work on that one.

20120101 - Added Goggle maps API library

In my layout:

<head>
  <%= render "layouts/tags" %>

  <script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=I_DID_PUT_MY_KEY_HERE&sensor=true">
  </script>

  <%= stylesheet_link_tag    "application" %>
  <%= javascript_include_tag "application" %>

  <%= render 'layouts/google_analytics' %>    
</head>

Loading Google maps api before the other libraries in application.js

Still Works on my development environment but not once deployed on Heroku.

20120103 Updates

HEADER page generated

<head>
<script type="text/javascript" src="//maps.google.com/maps/api/js?v=3.5&sensor=false&libraries=geometry"/>
<script src="http://maps.gstatic.com/cat_js/intl/en_us/mapfiles/api-3/5/16/%7Bmain,geometry%7D.js" type="text/javascript"/>
<script type="text/javascript" src="//google-maps-utility-library-v3.googlecode.com/svn/tags/markerclustererplus/2.0.5/src/markerclusterer_packed.js"/>
<link href="/assets/application.css" media="screen" rel="stylesheet" type="text/css"/>
<script src="/assets/application.js" type="text/javascript"/>

<style type="text/css" media="screen">
<script type="text/javascript">
<script type="text/javascript" charset="UTF-8" src="http://maps.gstatic.com/cat_js/intl/en_us/mapfiles/api-3/5/16/%7Bcommon,util%7D.js"/>
<script type="text/javascript" src="chrome-extension://bfbmjmiodbnnpllbbbfblcplfjjepjdn/js/injected.js"/>
<style type="text/css" media="print">
<script type="text/javascript" charset="UTF-8" src="http://maps.gstatic.com/cat_js/intl/en_us/mapfiles/api-3/5/16/%7Bcommon,util%7D.js"/>
</head>

FOOTER generated

<script type="text/javascript" src="//maps.google.com/maps/api/js?v=3.5&sensor=false&libraries=geometry"/>
<script src="http://maps.gstatic.com/cat_js/intl/en_us/mapfiles/api-3/5/16/%7Bmain,geometry%7D.js" type="text/javascript"/>
<script type="text/javascript" src="//google-maps-utility-library-v3.googlecode.com/svn/tags/infobox/1.1.9/src/infobox_packed.js"/>
<script type="text/javascript" src="//google-maps-utility-library-v3.googlecode.com/svn/tags/markerclustererplus/2.0.5/src/markerclusterer_packed.js"/>
<script type="text/javascript" src="//google-maps-utility-library-v3.googlecode.com/svn/trunk/richmarker/src/richmarker-compiled.js"/>
<script type="text/javascript" charset="utf-8">

Gmaps.configuration_map = new Gmaps4RailsGoogle();
Gmaps.load_configuration_map = function() {
Gmaps.configuration_map.map_options.detect_location = false;
Gmaps.configuration_map.map_options.center_on_user = false;
Gmaps.configuration_map.map_options.zoom = 0;
Gmaps.configuration_map.map_options.id = 'configuration_map';
Gmaps.configuration_map.map_options.last_map = false;
Gmaps.configuration_map.initialize();
Gmaps.configuration_map.markers = [{"description": "<div style='width:200px;'><p>Dec 13,2010 16:32 UTC</p> <h1 style='font-size:14px;' class=selling>SELLING</h1> <h2 style='font-size:12px;'><span style='color:#333;'>Lucerne gras, 2. cut, start flowering</span><sup style='font-size:9px;' class='cancelled state'>cancelled</sup></h2>  <p style='font-size:12px;'>2000 tons in Goma, Republique democratique du congo</p> Posted by <b><em>biowatts</em></b> </div>", "sidebar": "<span class='map_sidebar_item'><b>Lucerne gras, 2. cut, start flowering</b><br>2000 t/a</span>", "lng": "29.225241", "lat": "-1.693314"},{"description": "<div style='width:200px;'><p>Sep 17, 2011 23:43 UTC</p> <h1 style='font-size:14px;' class=wanted>WANTED</h1> <h2 style='font-size:12px;'><span style='color:#333;'>feeder cattle liquid manure</span><sup style='font-size:9px;' class='cancelled state'>cancelled</sup></h2>  <p style='font-size:12px;'>1000 tons in Rio de janeiro, Brasil</p> Posted by <b><em>biowatts</em></b> </div>", "sidebar": "<span class='map_sidebar_item'><b>feeder cattle liquid manure</b><br>1000 t/a</span>", "lng":"-43.2095869", "lat": "-22.9035393"},{"description": "<div style='width:200px;'><p>Sep 17, 2011 23:43 UTC</p> <h1 style='font-size:14px;' class=wanted>WANTED</h1> <h2 style='font-size:12px;'><span style='color:#333;'>Dummy</span><sup style='font-size:9px;' class='cancelled state'>cancelled</sup></h2>  <p style='font-size:12px;'>4000 tons in Sydney, Australia</p> Posted by <b><em>biowatts</em></b> </div>", "sidebar": "<span class='map_sidebar_item'><b>Dummy</b><br>4000 t/a</span>", "lng": "151.2070914", "lat": "-33.8689009"}];
Gmaps.configuration_map.markers_conf.list_container = 'markers_list';
Gmaps.configuration_map.create_markers();
Gmaps.configuration_map.adjustMapToBounds();
Gmaps.configuration_map.callback();
};
window.onload = function() { Gmaps.loadMaps(); }; <=========== when :last_map => false 
</script>

Note the Gmaps.loadMaps despite :last_option => false ... I thought should happen only when :last_map option set to true ?


Solution

  • I faced this situation before and it's not related to gmaps4rails.

    You have to:

    • include all the js files in the page manually so that they are loaded properly when the page is loaded

    • pass the proper option to the helper so that it doesn't try to include it again

    • use Gmaps.loadMaps() as you already understood.

    To sum up, it's just a question of js file loading.


    Let's make things clear:

    Files to include in your html (I assume you use google maps):

    <script type="text/javascript" src="//maps.google.com/maps/api/js?v=3.5&sensor=false&amp;libraries=geometry"></script>
    <script type="text/javascript" src="//google-maps-utility-library-v3.googlecode.com/svn/tags/markerclustererplus/2.0.5/src/markerclusterer_packed.js"></script>
    

    Files to include in your js manifest:

    //= require ./gmaps4rails/googlemaps.js
    

    As you already did, the google maps javascript must be added before the application.js file.

    To make sure the gmaps4rails files are included in your app, you can run the generator to have them copied in your app: rails generate gmaps4rails:install. From there you can remove much of the files depending on the map API you use.


    Change your call to the helper this way:

    <%= gmaps(:map_options => { :id => "configuration_map" },
              :markers => { "data" => @json, "options" => {"list_container" => "markers_list"     }},
              :scripts => :none,
              :last_map => false) %>
    

    Sidenote:

    You load the js file http://maps.gstatic.com twice but with different options, you could simply do:

     <script src="http://maps.gstatic.com/cat_js/intl/en_us/mapfiles/api-3/5/16/%7Bmain,geometry,common,util%7D.js" type="text/javascript"/>