1

I'm using Google Maps in a (initially hidden) tab, with the map being generated from the sample code provided by the Wordpress Advanced Custom Fields plugin.

My map is opening with tiles missing. I understand this is because the tab is initially hidden,and there are various solutions using google.maps.event.trigger(map, "resize") but for the life of me I can't get this working.

Here's the acf code with the basic ammendments I've found, but still not working:

        (function($) {
            var map;
            function render_map( $el ) {
                var $markers = $el.find(".marker");
                var args = {
                    zoom        : 16,
                    center      : new google.maps.LatLng(0, 0),
                    mapTypeId   : google.maps.MapTypeId.ROADMAP
                };
                map = new google.maps.Map( $el[0], args);
                map.markers = [];
                $markers.each(function(){
                    add_marker( $(this), map );
                });
                center_map( map );
            }

            function add_marker( $marker, map ) {
                var latlng = new google.maps.LatLng( $marker.attr("data-lat"), $marker.attr("data-lng") );
                var marker = new google.maps.Marker({
                    position    : latlng,
                    map         : map
                });
                map.markers.push( marker );
                if( $marker.html() )
                {
                    var infowindow = new google.maps.InfoWindow({
                        content     : $marker.html()
                    });
                    google.maps.event.addListener(marker, "click", function() {
                        infowindow.open( map, marker );
                    });
                }
            }

            function center_map( map ) {
                var bounds = new google.maps.LatLngBounds();
                $.each( map.markers, function( i, marker ){
                    var latlng = new google.maps.LatLng( marker.position.lat(), marker.position.lng() );
                    bounds.extend( latlng );
                });

                if( map.markers.length == 1 )
                {
                    map.setCenter( bounds.getCenter() );
                    map.setZoom( 16 );
                }
                else
                {
                    map.fitBounds( bounds );
                }

            }
            $(document).ready(function(){
                $(".acf-map").each(function(){
                    render_map( $(this) );
                });
            });
            $(document).on("click", "#map-tab", function() {
                alert("clicked");
                google.maps.event.trigger(map, "resize");
                map.setCenter( bounds.getCenter() );
                map.setZoom( 16 );
            });
        })(jQuery);

Can anyone suggest what I'm doing wrong? Very grateful for any assistance

Christian Mayne
  • 1,709
  • 7
  • 26
  • 42

3 Answers3

1

You need to do the fitBounds operation after the map has been rendered (after it is shown and has the final size). Currently it is being done when the map is hidden so it is fitting to a zero size map. Note that if you click the "Location mentioned" tab twice, it renders the tiles, but the center is still in the upper left hand corner.

proof of concept example (Show/Hide does fitBounds after the div is shown, Show 1/Hide 1 uses your code)

geocodezip
  • 158,664
  • 13
  • 220
  • 245
  • Thanks, I've now updated the code to fitBounds after rendering the mapas you suggest, but I'm still getting the same problem. – Christian Mayne Jan 28 '14 at 20:16
  • I don't see it changed in the [live version](http://www.pastonpaper.com/product/family-bible-of-william-and-olive-kelham-london/). That version only does the fitBounds in the center_map function (unless I am missing something or have a cache issue), which only runs when the page loads, not when the tab is displayed. – geocodezip Jan 28 '14 at 20:58
  • I've checked and the live version does appear to be updated: I changed it so the center_map function ran after the render_map function, though my javascript / jQuery isn't great as you can probably tell so that may not have worked. – Christian Mayne Jan 28 '14 at 21:24
  • The issue is that the render_map function (and the center_map function also) is running on page load, not when the tab is displayed. When they run (with the tab hidden) the browser reports a size of zero to the google maps API for that div, and the map exhibits the behavior you see (the center is in the upper left corner). See my proof of concept which I added to the answer. – geocodezip Jan 28 '14 at 23:56
1

First, go to the file where you put the tab template, search for the <li> tag that load your map tab and put this inside:

<li onclick="reloadmap()">

And in the map script right after the

google.maps.event.addDomListener(window, 'load', initialize);

put this:

function reloadmap(){
  //when you resize the map, you lose your zoom and your center
  //so you need to get them again here
    z = map.getZoom();
    c = map.getCenter();
    google.maps.event.trigger(map, 'resize');
  //and set them again here
    map.setZoom(z);
    map.setCenter(c);
}
Jeffrey Bosboom
  • 13,313
  • 16
  • 79
  • 92
Número Perdido
  • 31
  • 2
  • 2
  • 6
  • Please do not post the same answer verbatim on multiple questions. Either flag the questions as duplicates or tailor your answer specifically for each question. – Jeffrey Bosboom Mar 29 '15 at 16:44
0

I had the same problem, where the map is not visible after resize after changing the dom element to visible. The reason was, that the width of a hidden element is zero. Thus the map was initialized to a zero size map.

Changing the size of the map before calling resize solved this in my case.

Note: to retrieve the map later on after initialization you can save it in the jquery data object like this:

var $map = $('#id-of-the-map');  // get the jquery dom element of the map
var mapInstance = new google.maps.Map($map[0], {... some google maps options ...});
$map.data('mapInstance', mapInstance);

Then later on change the dimensions of the dom element before resize:

var $map = $('#id-of-the-map');  // get the jquery dom element of the map
if ($map.is(':visible')) {   // if it became visible
    $map.height($map.width() / 1.6);  // resize the dom element
    var mapInstance = $map.data('mapInstance'); // get the google maps map instance
    google.maps.event.trigger(mapInstance, "resize");   // resize the map
}
John Doe
  • 2,746
  • 2
  • 35
  • 50