31

I'm using Twitter's Bootstrap for defining my CSS. I have made a page with three tabs. The second tab contains a map built with Google Maps. However when opening the page and switching to the second page with the map, the map is not rendered completely. Once I reload the page with the google maps tab as the selected tab the map loads entirely.

I read some posts that advised people with the same problem to add the following code to the javascript:

google.maps.event.addDomListener(window, 'resize', function() {
    map.setCenter(homeLatlng);
});

However this doesn't seem to be the solution. Please find the complete code below:

Javascript:

<script type="text/javascript">
function initialize() {
    google.maps.event.addDomListener(window, 'resize', function() {
        map.setCenter(homeLatlng);
    });

    var myLatlng = new google.maps.LatLng(37.4419, -122.1419);
    var myOptions = {
        zoom: 13,
        center: myLatlng,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    }
    var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
    downloadUrl("data.xml", function(data) {
        var markers = data.documentElement.getElementsByTagName("marker");
        for (var i = 0; i < markers.length; i++) {
            var latlng = new google.maps.LatLng(parseFloat(markers[i].getAttribute("lat")), 
                                parseFloat(markers[i].getAttribute("lng")));
            var marker = new google.maps.Marker({position: latlng, map: map});
        }
    });
}
</script>

HTML:

<div class="tab-pane" id="orange" style="background-color:#E3F2FF;">
      <div id="map_canvas" style="width:780px; height:400px; overflow:;"></div>
</div>

How can I resolve this? Maybe I can add some javascript that reloads the google maps part once the tab is selected but I don't know how to do this....

Updated code still shows the error:

<div class="tab-pane" id="orange" style="background-color:#E3F2FF;">
    <div id="map_canvas" style="width:780px; height:400px; overflow:;"></div>
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
    <script type="text/javascript" src="util.js"></script>
    <script type="text/javascript">
      function initialize() {
        google.maps.event.addDomListener(window, 'resize', function() {
            map.setCenter(homeLatlng);
        });

        var myLatlng = new google.maps.LatLng(37.4419, -122.1419);
        var myOptions = {
          zoom: 13,
          center: myLatlng,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        }
        var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
        downloadUrl("data.xml", function(data) {
          var markers = data.documentElement.getElementsByTagName("marker");
          for (var i = 0; i < markers.length; i++) {
            var latlng = new google.maps.LatLng(parseFloat(markers[i].getAttribute("lat")),
                                        parseFloat(markers[i].getAttribute("lng")));
            var marker = new google.maps.Marker({position: latlng, map: map});
           }
        });
        map.checkResize();
    }
    </script>
</div>
Markus Mitterauer
  • 1,560
  • 1
  • 14
  • 28
TrendyT
  • 429
  • 2
  • 5
  • 12
  • possible duplicate: http://stackoverflow.com/questions/3777810/google-maps-dont-fully-load – Evan Davis Apr 17 '12 at 18:51
  • 4
    you cannot load google maps into a hidden element. You will need to load the maps AFTER the element is shown. – Evan Davis Apr 17 '12 at 18:51
  • Hi Mathletics, Thank you for your help. I simply updated the script in the following way attempting to load the map AFTER the element is shown but this still causes the error. I have listed the updated code above: – TrendyT Apr 18 '12 at 08:49
  • "error" meaning the map still doesn't display correctly? – Evan Davis Apr 18 '12 at 12:28
  • That's right. With error I mean that the map is still not rendered completely. – TrendyT Apr 18 '12 at 13:13
  • loading it directly, it seems to work fine. http://jsfiddle.net/y8pm4/ are you able to reproduce the error in a fiddle? – Evan Davis Apr 18 '12 at 14:19
  • Thank you for your continuing support! I have attempted to reproduce the error in a fiddle: http://jsfiddle.net/y8pm4/9/. However with the code I use in fiddle right now, no map is shown at all.... – TrendyT Apr 18 '12 at 15:35
  • 1
    In your linked fiddle, you are still initializing the map as soon as the page loads, not when the tab is shown. You need to move the `var map = new google.Maps.map(...)` code into your tab control so that it is executed after the tab is shown and the map div is visible. – Evan Davis Apr 18 '12 at 17:48
  • That helps, thank you. What's the best way to do this? By adding an 'onLoad' function to the div? like: http://jsfiddle.net/y8pm4/9/ – TrendyT Apr 18 '12 at 18:38
  • unfortunately, I'm not familiar with Twitter bootstrap. You may want to delete this question and ask a new one regarding bootstrap (or just look in the docs for how to add actions to specific tabs.) – Evan Davis Apr 18 '12 at 20:18
  • Thank you very much for all your help Mathletics. Once I have found the solution I will post it here. – TrendyT Apr 19 '12 at 12:32
  • @TrendyT did you managed to find a solution? and is it still something you are looking at? – baptme Jul 09 '12 at 16:27

7 Answers7

47

I was battling with this issue as well. I was using a modal form and it rendered the map when it was hidden. When the tab is shown, you need to trigger this code:

google.maps.event.trigger(map, 'resize');
map.setZoom( map.getZoom() );

Hopefully it will work for you. If that doesn't work, here is the link where I found the solution. Maybe there will be another helpful comment.

http://code.google.com/p/gmaps-api-issues/issues/detail?id=1448

Theo
  • 2,609
  • 1
  • 26
  • 27
  • 4
    With bootstrap, make sure this gets put in your shown event, not the show event. – Michael Feb 15 '14 at 02:20
  • 1
    Bootstrap < 3 uses the 'shown' event. For Bootstrap 3, we have to use 'shown.bs.tab'. $('#maptab').on('shown.bs.tab', function () { google.maps.event.trigger(map, 'resize'); }); – Justin Nafe Mar 24 '14 at 21:30
8

There's a lot of solutions here and frankly they're all wrong. If you have to hi-jack the default functionality of Bootstrap tabs, you might as well not use Bootstrap tabs. If you're only calling resize after the tab is shown, you may still have issues with the GMaps interface (zoom level and such). You simply have to initialize the map after the tab is visible.

var myCenter=new google.maps.LatLng(53, -1.33);
var marker=new google.maps.Marker({
    position:myCenter
});

function initialize() {
  var mapProp = {
      center:myCenter,
      zoom: 14,
      draggable: false,
      scrollwheel: false,
      mapTypeId:google.maps.MapTypeId.ROADMAP
  };

  var map=new google.maps.Map(document.getElementById("map-canvas"),mapProp);
  marker.setMap(map);

  google.maps.event.addListener(marker, 'click', function() {

    infowindow.setContent(contentString);
    infowindow.open(map, marker);

  }); 
};

$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
    initialize();
});

You can see a working example in this bootply: http://www.bootply.com/102241

Note: if your interface is still glitchy, it could be this issue: Google Maps API V3 : weird UI display glitches (with screenshot)

Using the most recent gmaps api, you just need to add this to your styling:

.gm-style img { max-width: none; }
.gm-style label { width: auto; display: inline; }
Community
  • 1
  • 1
Archonic
  • 5,207
  • 5
  • 39
  • 55
  • 1
    Initializing the map when it becomes visible is the cleanest and most reliable solution, that should be the accepted answer. – Tdy Aug 03 '16 at 04:12
6

Works for me after testing different delays :

    $(window).resize(function() {
        setTimeout(function() {
              google.maps.event.trigger(map, 'resize');
           }, 300)            

});

Hope it helps.

Cyril Jacquart
  • 2,632
  • 3
  • 25
  • 24
4

I have solved the problem by using

google.maps.event.trigger(map, 'resize');

inside show function in bootstrap-tab.js means at the time of showing the box you should trigger resize event and will work..

Edit: I have seen another link with the same answer Google Maps API v3, jQuery UI Tabs, map not resizing I have seen this link after solving the problem to find out the reason which is still unanswered that why resize event does not works on the click event of the tabs but works in the tab js

Community
  • 1
  • 1
Ankit Sharma
  • 143
  • 1
  • 10
2

this works fine for me, I use jquery tabs

            setTimeout(function() {
            google.maps.event.trigger(map, "resize");
            map.setCenter(new google.maps.LatLng(default_lat, default_lng));
            map.setZoom(default_map_zoom);
        }, 2000);

from this link https://code.google.com/p/gmaps-api-issues/issues/detail?id=1448

Karim Samir
  • 1,470
  • 17
  • 17
1

To show a google maps in a hidden div, the div must show before the map is created and loaded. Below is an example:

<div  id="map_canvas" style="width:500px; height:500px"></div>

<script>
$(document).ready(function(){
  $('#button').click(function() {
    $('#map_canvas').delay('700').fadeIn();
    setTimeout(loadScript,1000);
  }); 
});

    function initialize() {
        var title= "Title";
        var lat = 50;
        var lng = 50;
        var myLatlng = new google.maps.LatLng(parseFloat(lat),parseFloat(lng));
        var myOptions = {
        zoom: 8,
        center: myLatlng,
        mapTypeId: google.maps.MapTypeId.ROADMAP
      }
      var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
      var marker = new google.maps.Marker({
            position: myLatlng,
            title:artTitle
        });
        // To add the marker to the map, call setMap();
        marker.setMap(map);
    }

    function loadScript() {
      var script = document.createElement("script");
      script.type = "text/javascript";
      script.src = "http://maps.google.com/maps/api/js?sensor=false&callback=initialize";
      document.body.appendChild(script);
    }       
</script>
Memonic
  • 345
  • 5
  • 14
-1

For me, what it worked was to call the function that renders the map after the, in my case, the modal had shown.

All I had to do was:

$(document).on("shown", "#eventModal", function(){
    bindMap(coordinates);
});

You can do the same with the tabs, because they also have a "shown" event.

Juliana
  • 578
  • 7
  • 18