0

I have a map in a modal which i would like to display a map of locations for each individual product activated by a click event (note my locations are post codes):

Modal

<div id="myModal" class="modal">
    <div class="modal-content">
        <span class="modal-close">x</span>
        <div id="map_canvas"></div>
    </div>
</div>

Product

if (Model.locationsExist > 1)
{
    <div class="maplink">See @Model.locationsExist locations on map</div>
}
else
{
    <div class="maplink">See on map</div>
}
@Html.HiddenFor(x => x.locationString, new { @class = "locstring" })

Map Globals

var map;
var elevator;
var myOptions = {
    zoom: 5,
    center: new google.maps.LatLng(53.90, -3.00),
    mapTypeId: 'roadmap'
};

var addresses;
var gmarkers = [];

Map creation -I have a function that iterates an array of postcodes and adds them to the map ... also to a global array so that I can remove them later as per this post

function loadmap(locs){           

    map = new google.maps.Map($('#map_canvas')[0], myOptions);

    addresses = locs.split('|');

        for (var x = 0; x < addresses.length; x++) {
            var marker = $.getJSON('http://maps.googleapis.com/maps/api/geocode/json?address=' + addresses[x] + '&sensor=false', null, function (data) {
                var p = data.results[0].geometry.location
                var latlng = new google.maps.LatLng(p.lat, p.lng);
                new google.maps.Marker({
                    position: latlng,
                    map: map
                });

            });

            gmarkers.push(marker);                
        }

        addresses = [];
    };

function removeMarkers() {
    for (i = 0; i < gmarkers.length; i++) {
            gmarkers[i].setMap(null);
        }
    };

Map open and close - I show the modal on the click of the link in my product thumbnail. This runs the creation code. The when i click the close link the pins should be removed. Then new pins added if another map link is clicked.

$(document).on('click', '.maplink', function () {
        loadmap($(this).siblings('.locstring').val());
        $('#myModal').css("display", "block");
    });

$(document).on('click', '.modal-close', function () {
        $('#myModal').css("display", "none");
        removeMarkers();
    });

The first time I click the modal shows and the map is fine. It works. I close and then click another link and the map seems to bug out:

enter image description here

I have looked at numerous posts and this is the 5th version I have tried. Has anyone had this before?

Community
  • 1
  • 1

2 Answers2

0

I had this issue with bootstrap modals and you have to trigger the Google Map resize event when the map is shown modal or before.

In Bootstrap its like:

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

After triggering the resize event the Google Map loses his initial settings like Zoomlevel or center, so you should restore or initilize the Google Map before it is shown at this point them.

See Embedding Google Maps as CSS Overlay doesn't load properly

The matter is setting the google map to display:none. If you use opacity this could easier solve your problem than triggering the resize event. ;-)

Community
  • 1
  • 1
frankhammer
  • 73
  • 1
  • 7
0

I found the answer to my problem whilst experimenting with frankhammer suggestion.

I simply changed the order that I displayed the modal:

$(document).on('click', '.maplink', function () {                
        $('#myModal').css("display", "block");
        loadmap($(this).siblings('.locstring').val());
    });

This then meant that I could do away with my remove pin code entirely.

So my code ended up looking like this:

var map;
var elevator;
var myOptions = {
    zoom: 5,
    center: new google.maps.LatLng(53.90, -3.00),
    mapTypeId: 'roadmap'
};

var addresses;

$(document).ready(function () {
    $(document).on('click', '.maplink', function () {                
        $('#myModal').css("display", "block");
        loadmap($(this).siblings('.locstring').val());
    });

    $(document).on('click', '.modal-close', function () {
        $('#myModal').css("display", "none");
    }); 
}

function loadmap(locs) {

    map = new google.maps.Map($('#map_canvas')[0], myOptions);

    addresses = locs.split('|');

    for (var x = 0; x < addresses.length; x++) {
        var marker = $.getJSON('http://maps.googleapis.com/maps/api/geocode/json?address=' + addresses[x] + '&sensor=false', null, function (data) {
        var p = data.results[0].geometry.location
        var latlng = new google.maps.LatLng(p.lat, p.lng);
        new google.maps.Marker({
            position: latlng,
            map: map
        });

    });               
}
    addresses = [];
};