Robin93K
Robin93K

Reputation: 335

Google Maps InfoWindow shows up on wrong Map

My Problem is in the WP-Plugin I write that when there is more than one map open on the same time,
e.g. on the mainpage where the last 3 posts are shown each with an own minimap showing their position, that when I click on one of the markers, doesn't matter from which map, the infoWindows will show up all in the last map...

I initialize the maps with the following code:

function Initialize(lat, lng, zm, pid) {    
    geocoder = new google.maps.Geocoder();
    var latlng = new google.maps.LatLng(lat,lng);
    var mapOptions = {
        zoom: zm,
        center: latlng,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    }

    var name = "map_canvas" + pid;  

    map = new google.maps.Map(document.getElementById(name), mapOptions);
}

and set the markers as followed:

function AddMarker( lat, lng, address, title, link, image, target ) {

    var marker = new google.maps.Marker({
        map: map,
        position: new google.maps.LatLng(lat, lng),
        icon: new google.maps.MarkerImage( image ),
        title: title
    });

    var infowindow = new google.maps.InfoWindow({ 
        content: '<a href="' + link + '" target="_' + target + '">' + title + '</a><br /><small><font color="#000000">' + address + '</font></small>', 
    });
    google.maps.event.addListener(marker, 'click', function() {
        infowindow.open(map,marker);
    });
}

the var map stands on top of the functionfile, kinda like a Global, so that the markers are all on the right map, but sadly the infowindows won't follow them...

does anyone else experienced such stuff, or has an idea how I can solve it?

Upvotes: 0

Views: 840

Answers (2)

RobH
RobH

Reputation: 3612

Your problem is that this:

google.maps.event.addListener(marker, 'click', function() {
    infowindow.open(map,marker);
});

Accesses the map variable when the map is clicked not the value of the variable when you assign the handler. Pass a copy and use that instead:

google.maps.event.addListener(marker, 'click', (function (m) {
    return function() {
        infowindow.open(m,marker);
    };
}(map)));

Edit:

The above uses an immediately invoked function expression to pass in a copy of the map variable. All this does is declare a function and then immediately call it, passing in map.

function (m) {
    return function() {
        infowindow.open(m,marker);
    };
}(map)

However, the whole thing needs to be wrapped in () so that the JS parser reads it as a function expression and not a function declaration.

Another way of solving it would be:

function AddMarker( lat, lng, address, title, link, image, target ) {

    var marker = new google.maps.Marker({
        map: map,
        position: new google.maps.LatLng(lat, lng),
        icon: new google.maps.MarkerImage( image ),
        title: title
    });

    var infowindow = new google.maps.InfoWindow({ 
        content: '<a href="' + link + '" target="_' + target + '">' + title + '</a><br /><small><font color="#000000">' + address + '</font></small>', 
    });

    // Add a function that returns a new function that uses a local
    // copy of the passed in map.
    var getMapClickListener = function (m) {
        return function () {
            infowindow.open(m, marker);
        };
    };

   // Then use the new function when adding the handler.
    google.maps.event.addListener(marker, 'click', getMapClickListener(map));
}

Upvotes: 3

Andy
Andy

Reputation: 63524

I think the problem is that while you're assigning the map name to name correctly using the pid, each map is then being assigned to the map variable, each one overriding the other.

What you might find useful is using an object to hold your maps using the pids as keys:

var mapHolder = {};
var name = "map_canvas" + pid;
var mapHolder[pid] = new google.maps.Map(document.getElementById(name), mapOptions);

That way you can access each map without hassle just by passing in the pid to the addMarker function:

function AddMarker( lat, lng, address, title, link, image, target, pid) {

  var marker = new google.maps.Marker({
    map: mapHolder[pid],
    position: new google.maps.LatLng(lat, lng),
    icon: new google.maps.MarkerImage( image ),
    title: title
  });

  var infowindow = new google.maps.InfoWindow({
    content: // content
  });

  google.maps.event.addListener(marker, 'click', function() {
    infowindow.open(mapHolder[pid], marker);
  });

}

That way all your markers and infowindows should open on the correct map.

Upvotes: 1

Related Questions