1

I have a Google Map with multiple markers. I'm trying to show info in my InfoWindow for each marker:

function initializeMaps() {
      var latlng = new google.maps.LatLng(59.4920, 37.3010);
      var myOptions = {
          zoom: 6,
          center: latlng,
          disableDefaultUI: false,
          scrollwheel: false,
          mapTypeId: google.maps.MapTypeId.ROADMAP,
      };
      var infoWindow = new google.maps.InfoWindow();
      var latlngbounds = new google.maps.LatLngBounds();
      var map = new google.maps.Map(document.getElementById('map'),myOptions);

      var mc = new MarkerClusterer(map);
      var marker, i;
        for (i = 0; i < data.markers.length; i++) { 
              var image = "/images/markers/green-marker.png";
              marker = new google.maps.Marker({
              position: new google.maps.LatLng(data.markers[i].lat, data.markers[i].lng),
              map: map,
              title: data.markers[i].name,
              icon: image,
            });
            /*jshint loopfunc: true */
            (function (marker, data) {
            google.maps.event.addListener(marker, "click", function (e) {

                for (i=0; i<data.markers.length; i++) {
                    infoWindow.setContent("<div style = 'min-width:200px;min-height:40px'>" + '<img src="' + data.markers[i].link + '" style="height:150px;width:250px;" />' + "<br />" + data.markers[i].description + "<br />" + "<button>Read More</button>" + "</div>");
                    infoWindow.open(map, marker);
                }

            });
        })(marker, data);
        latlngbounds.extend(marker.position);

            mc.addMarker(marker);
        }
        var bounds = new google.maps.LatLngBounds();
    }

But it shows me only last element information of my array on every single marker infoWindow on the map. Below my JSON file:

var data = {
"markers":[
    {
        "city": "City Sample Text",
        "name": "Name Sample Text",
        "shortname": "redsquare_location",
        "description": "Descr Sample Text",
        "lat": "51.4910",
        "lng": "31.2985",
        "link": "images/infowindows/rs_rp.png",
    },
    {
        "city": "City Sample Text",
        "name": "Name Sample Text",
        "shortname": "pchurch_location",
        "description": "Descr Sample Text",
        "lat": "51.4925",
        "lng": "31.3007",
        "link": "images/infowindows/pc_rp.png",
    },
    {
        "city": "City Sample Text",
        "name": "Name Sample Text",
        "shortname": "muschool_location",
        "description": "Decr Sample Text",
        "lat": "51.4932",
        "lng": "31.3054",
        "link": "images/infowindows/ms_rp.png",
    }       
]
}

What my mistake is?

dintro
  • 25
  • 4

2 Answers2

0

You can see only the last element information because of this

var marker, i;
for (i = 0; i < data.markers.length; i++) { 
      var image = "/images/markers/green-marker.png";
      marker = new google.maps.Marker({
          position: new google.maps.LatLng(data.markers[i].lat, data.markers[i].lng),
          map: map,
          title: data.markers[i].name,
          icon: image,
      });

      google.maps.event.addListener(marker, "click", function (e) {
          ...
      });
}

You're trying to set event listener inside of the "for" loop. So, your case is very similar to Javascript multiple dynamic addEventListener created in for loop - passing parameters not working.

This code will work if you'll use something like this:

data.markers.forEach(function(marker){
    var image = "/images/markers/green-marker.png";
    var mapMarker = new google.maps.Marker({
          position: new google.maps.LatLng(marker.lat, marker.lng),
          map: map,
          title: marker.name,
          icon: image,
    });
    google.maps.event.addListener(marker, "click", function(e) {
      ...
    });
    mc.addMaker(mapMarker);
})
Community
  • 1
  • 1
Evgeny Sorokin
  • 630
  • 3
  • 12
0

Duplicate of the issue in question: Google Maps JS API v3 - Simple Multiple Marker Example

You aren't getting function closure on the i variable in the click listener and going through the loop inside the click listener will always leave the information in the infowindow at the last entry in the data:

(function (marker, data) {
    google.maps.event.addListener(marker, "click", function (e) {

        for (i=0; i<data.markers.length; i++) {
            infoWindow.setContent("<div style = 'min-width:200px;min-height:40px'>" + '<img src="' + data.markers[i].link + '" style="height:150px;width:250px;" />' + "<br />" + data.markers[i].description + "<br />" + "<button>Read More</button>" + "</div>");
            infoWindow.open(map, marker);
        }

    });
})(marker, data);

Simplest solution it to get function closure on the data required to populate the infowindow, so you don't need to iterate through the whole set of input data on each marker click:

(function(marker, data) {
  google.maps.event.addListener(marker, "click", function(e) {

    infoWindow.setContent("<div style = 'min-width:200px;min-height:40px'>" + '<img src="' + data.link + '" style="height:150px;width:250px;" />' + "<br />" + data.description + "<br />" + "<button>Read More</button>" + "</div>");
    infoWindow.open(map, marker);
  });
})(marker, data.markers[i]);

proof of concept fiddle

code snippet:

function initializeMaps() {
  var latlng = new google.maps.LatLng(59.4920, 37.3010);
  var myOptions = {
    zoom: 6,
    center: latlng,
    disableDefaultUI: false,
    scrollwheel: false,
    mapTypeId: google.maps.MapTypeId.ROADMAP,
  };
  var infoWindow = new google.maps.InfoWindow();
  var latlngbounds = new google.maps.LatLngBounds();
  var map = new google.maps.Map(document.getElementById('map'), myOptions);

  var mc = new MarkerClusterer(map);
  var marker, i;
  for (i = 0; i < data.markers.length; i++) {
    var image = "http://maps.google.com/mapfiles/ms/icons/green.png";
    var marker = new google.maps.Marker({
      position: new google.maps.LatLng(data.markers[i].lat, data.markers[i].lng),
      map: map,
      title: data.markers[i].name,
      icon: image,
    });
    /*jshint loopfunc: true */
    (function(marker, data) {
      google.maps.event.addListener(marker, "click", function(e) {

        infoWindow.setContent("<div style = 'min-width:200px;min-height:40px'>" + '<img src="' + data.link + '" style="height:150px;width:250px;" />' + "<br />" + data.description + "<br />" + "<button>Read More</button>" + "</div>");
        infoWindow.open(map, marker);
      });
    })(marker, data.markers[i]);
    latlngbounds.extend(marker.position);

    mc.addMarker(marker);
  }
  // var bounds = new google.maps.LatLngBounds();
  map.fitBounds(latlngbounds);
}
google.maps.event.addDomListener(window, "load", initializeMaps);

var data = {
  "markers": [{
    "city": "City Sample Text",
    "name": "Name Sample Text",
    "shortname": "redsquare_location",
    "description": "Descr Sample Text 0",
    "lat": "51.4910",
    "lng": "31.2985",
    "link": "images/infowindows/rs_rp.png",
  }, {
    "city": "City Sample Text",
    "name": "Name Sample Text",
    "shortname": "pchurch_location",
    "description": "Descr Sample Text 1",
    "lat": "51.4925",
    "lng": "31.3007",
    "link": "images/infowindows/pc_rp.png",
  }, {
    "city": "City Sample Text",
    "name": "Name Sample Text",
    "shortname": "muschool_location",
    "description": "Decr Sample Text 2",
    "lat": "51.4932",
    "lng": "31.3054",
    "link": "images/infowindows/ms_rp.png",
  }]
};
html,
body,
#map {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script src="https://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclustererplus/src/markerclusterer.js"></script>
<div id="map"></div>
Community
  • 1
  • 1
geocodezip
  • 158,664
  • 13
  • 220
  • 245