60

I'm trying to insert a Google map into a modal using Twitter Bootstrap. The modal shows up with the shape of the map present, but only part of the map is displayed, the rest is gray. Upon resizing the screen the map always shows up correctly, although centered in the wrong place.

I've searched and found suggestions such as calling the map's resize event, or setting the max-width of the map image to none, but none of these suggestions have helped so far. It seems like the map is failing to figure out it's correct size as long as it's in an element that's hidden.

JS

function initialize() {
  var mapOptions = {
    center: new google.maps.LatLng(51.219987, 4.396237),
    zoom: 12,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  var map = new google.maps.Map(document.getElementById("mapCanvas"),
    mapOptions);
  var marker = new google.maps.Marker({
    position: new google.maps.LatLng(51.219987, 4.396237)
  });
  marker.setMap(map);
}

HTML

<div class="modal hide fade" id="myModal">
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal">×</button>
    <h3></h3>
  </div>
  <div class="modal-body">
    <div id="mapCanvas" style="width: 500px; height: 400px"></div>
  </div>
  <div class="modal-footer">
    <a href="#" class="btn" data-dismiss="modal">Close</a>
  </div>
</div>

I'm using Twitter Bootstrap v2.0.4. I need some help because I'm failing to trigger the resize event correctly or editing the css so that the Google map is left alone.

merv
  • 67,214
  • 13
  • 180
  • 245
Eels
  • 625
  • 1
  • 6
  • 8
  • When are you calling the `initialize()` method? Maybe try calling it only after a `shown` event. – merv Jul 31 '12 at 14:59
  • It's being called in the onLoad event of the body of the page. Show happens in the javascript of Twitter bootstrap, so I don't know how to link that with the script on my page. – Eels Aug 01 '12 at 05:46

11 Answers11

110

Google Maps indeed displays "Grey" area's when it's placed inside a dynamic element (for example: One that resizes, fades etc.). You're right about triggering the "resize" function, which should be called once the animation is complete (the shown.bs.modal event in Bootstrap 3 or the shown event in Bootstrap 2):

$("#myModal").on("shown.bs.modal", function () {
    google.maps.event.trigger(map, "resize");
});

In Bootstrap 2, you will do:

$('#myModal').on('shown', function () {
    google.maps.event.trigger(map, "resize");
});

(where map is the variable name of your map (see Google Maps documentation for further details), and #myModal the ID from your element).

UPDATE 2018-05-22

With a new renderer release in version 3.32 of Maps JavaScript API the resize event is no longer a part of Map class.

The documentation states

When the map is resized, the map center is fixed

  • The full-screen control now preserves center.

  • There is no longer any need to trigger the resize event manually.

source: https://developers.google.com/maps/documentation/javascript/new-renderer

google.maps.event.trigger(map, "resize"); doesn't have any effect starting from version 3.32

Community
  • 1
  • 1
MarcoK
  • 6,090
  • 2
  • 28
  • 40
  • My problem is in knowing where to do that: the modal javascript code is from Twitter Bootstrap, so I don't really want to place any map info into that. The javascript that loads the map is executed in the body's onLoad, but that's basically too early since the modal isn't visible yet at that point. – Eels Jul 31 '12 at 17:27
  • @Eels Changed my answer, completed it with the `shown` event from Twitter Bootstrap. – MarcoK Aug 01 '12 at 07:15
  • Interesting.. the SHOW event doesn't do it.. NOTICE: the "n" at the end of the event name that is triggered. "shown" instead of "show" fixed it for me!! THANK YOU! – Fydo Oct 29 '12 at 00:02
  • Where is the variable name of the map found? I tried $('#map_canvas'), '#map_canvas', and 'map_canvas' and couldn't get anywhere. – dacopenhagen Jan 30 '13 at 22:20
  • That fixes the gray boxes, but it's still not centering at the correct location for me – andrewtweber Mar 30 '13 at 20:24
  • 1
    @andrewtweber You can use the answer to the following question for recentering the map: http://stackoverflow.com/questions/8558226/recenter-a-google-map-after-container-changed-width – Jan-Henk Jun 19 '13 at 16:05
  • In Bootstrap v3 you will have probably problem with this. Good soloution for this is from @Jakki – 3y3skill3r Nov 26 '14 at 00:00
  • In Boostrap v3 the event to capture is `shown.bs.modal` instead of `shown`; otherwise this still works fine. – Christopher King Jul 09 '15 at 13:53
  • 1
    @MarcoK I updated your answer to provide solution for BS3 too. Lots of traffic comes to this question and lots of people are using BS3. :) Nice answer! – Ionică Bizău Feb 23 '16 at 11:24
  • Still gray for me. – Joseph Norris May 24 '17 at 21:07
  • Anybody found a solution for the newest Google Maps API? I have a form inside a modal and I need to display a map with drag and drop marker :/ – Thiago A. Klein Nov 14 '18 at 20:05
43

For me, it works like this (Boostrap 3):

$("#contact-modal").on("shown.bs.modal", function () {
    google.maps.event.trigger(map, "resize");
});
henrikstroem
  • 2,978
  • 4
  • 35
  • 51
38

Showing the map correctly and centered

I wanted to point out a few modifications I made, based on the original answer, to make it work with Bootstrap 3 (check about modals usage).

// Resize map to show on a Bootstrap's modal
$('#map-modal').on('shown.bs.modal', function() {
  var currentCenter = map.getCenter();  // Get current center before resizing
  google.maps.event.trigger(map, "resize");
  map.setCenter(currentCenter); // Re-set previous center
});

In this case, I also take care of recentering the map, based on this question suggested in Jan-Henk's comment to the first answer.

Community
  • 1
  • 1
Roberto S.
  • 1,262
  • 1
  • 14
  • 19
8

When using Bootstrap 3 you need to use what is provided within their documentation i.e. instead of 'shown' use 'shown.bs.modal'

Example:

 $('#modal').on('shown.bs.modal', function () { 
     initialiseMap();
 });
user2956820
  • 81
  • 1
  • 2
5

The accepted answer does, indeed, work in this case where the contents of the div are local. Unfortunately, I had the same problem showing a map that was included as part of remote data. Getting the handle of the map and calling resize did not correctly center my map. Here is how I fixed the issue in my remote data situation.

Include a script tag as part of your remote data with a function to initialize the map

<script type="text/javascript">
    function renderMap() {
        var point = new google.maps.LatLng(51.219987, 4.396237);
        var map = new google.maps.Map(document.getElementById('map'), {
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            zoom: 13,
            center: point
        });
        var marker = new google.maps.Marker({ position: point, map: map, icon: 'http://www.google.com/intl/en_us/mapfiles/ms/icons/red-dot.png' });
    }
</script>

Call the function in the shown event of the dialog on the main page

<script type="text/javascript">

    $(document).ready(function () {
        $('#dlgReportInfo').on('shown', function () {
            renderMap();
        });
    })
</script>

This way, the map is already sized in the dialog before you initialize it. Hopefully this will help out any others with a similar situation.

Jason Butera
  • 2,376
  • 3
  • 29
  • 46
5

The accepted answer got rid of the gray boxes, but does not center the map at the right coordinates for me. My solution was just to wait to render the map until after the modal is finished displaying.

$('#modal').on('shown', function () {
    initialize();
});
andrewtweber
  • 24,520
  • 22
  • 88
  • 110
5

the following code work perfectly fine for bootstrap 3

$("#mapModal").on("shown.bs.modal", function () {initialize();});
David
  • 15,894
  • 22
  • 55
  • 66
Jakki
  • 349
  • 4
  • 6
4
    this works for me 
    **<!-- Modal -->**
    <div class="modal fade" id="myModal" role="dialog">
        <div class="modal-dialog">

            <!-- Modal content-->
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal">&times;</button>
                    <h4 class="modal-title">Google Maps</h4>
                </div>
                <div class="modal-body">

                    <div id="map_canvas" style="width:auto; height: 500px;"></div>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                </div>
            </div>
        </div>
    </div>


**Button**
 <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal">View Map</button>

**javascript**
<script type="text/javascript">
    function initializeMap() {
        var mapOptions = {
            center: new google.maps.LatLng(51.219987, 4.396237),
            zoom: 12,
            mapTypeId: google.maps.MapTypeId.HYBRID
        };
        var map = new google.maps.Map(document.getElementById("map_canvas"),
          mapOptions);
        var marker = new google.maps.Marker({
            position: new google.maps.LatLng(51.219987, 4.396237)
        });
        marker.setMap(map);
    }

    //show map on modal
    $('#myModal').on('shown.bs.modal', function () {
        initializeMap();
    });

</script>

hope this will help

Jerrilyn
  • 41
  • 1
3

I have fixed with solution:

$('#myId').on('shown.bs.modal', function () { 
    initializeMap() // with initializeMap function get map.
});

//event shown.bs.modal on modal bootstrap will fire after modal show, not use show.bs.modal because it will call before modal show.

1

try this !

<div class="modal fade" id="map_modal" tabindex="-1" role="dialog" aria-    labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
    <div class="modal-content">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
            <h4 class="modal-title" id="myModalLabel">Modal title</h4>
        </div>
        <div class="modal-body"><div id="map_canvas" style="width:530px; height:300px"></div></div>

    </div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->

var map = marker = new Array();
geocoder = NULL;


                    function addPoint(location, id, mapId) {
                        if (!marker[id]) {
                            marker[id] = new google.maps.Marker({
                                position: location,
                                map: map[mapId],
                                draggable: true
                            });
                        }

                    }


                    function placeMarker(location, editStr, id) {
                        if (!marker[id]) {
                            marker[id] = new google.maps.Marker({
                                position: location,
                                map: map[id],
                                draggable: false
                            });
                        }
                        marker[id].setPosition(location);
                        map[id].setCenter(location);
                        $("#longitud").val(location.lat());
                        $("#latitud").val(location.lng());


                    }


                    function  initializeMap(id, div_id, lat, lng, editStr) {
                        if (!geocoder)
                            geocoder = new google.maps.Geocoder();

                        if (!map[id]) {
                            var coordinates = new google.maps.LatLng(lat, lng);
                            var myOptions = {zoom: 8, center: coordinates, mapTypeId: google.maps.MapTypeId.ROADMAP}
                            map[id] = new google.maps.Map(document.getElementById(div_id), myOptions);
                            google.maps.event.addListener(map[id], 'click', function(event) {
                                placeMarker(event.latLng, editStr, id);
                            });

                            placeMarker(coordinates, editStr, id);

                        }
                    }


                    $('#map_modal').on('shown.bs.modal', function(e) {
                        initializeMap("#newMaps", "map_canvas", 10.444598, -66.9287, "");
                    })
John Paul
  • 12,196
  • 6
  • 55
  • 75
Carlos Avalos
  • 247
  • 4
  • 8
1

I am also facing the same issue but i resolve it by waiting for the map's 'idle' state (i.e. when it's finished) and then calling the resize:

 google.maps.event.addListenerOnce(map, 'idle', function () {
                 var currentCenter = map.getCenter();
                 google.maps.event.trigger(map, 'resize');
                 map.setCenter(currentCenter);

                 map.setZoom(15);
             });

after

              map = new google.maps.Map(document.getElementById('map-canvas2'),mapOptions);
Sunil Devre
  • 374
  • 1
  • 15